2021-10-12 15:32:24 +01:00
|
|
|
|
using HarmonyLib;
|
2021-12-23 17:07:29 -08:00
|
|
|
|
using QSB.DeathSync.Messages;
|
|
|
|
|
using QSB.Messaging;
|
2020-12-14 20:31:31 +01:00
|
|
|
|
using QSB.Patches;
|
2021-07-31 09:45:38 +01:00
|
|
|
|
using QSB.Player;
|
2022-12-09 15:51:14 +00:00
|
|
|
|
using QSB.Utility;
|
2020-12-14 21:20:53 +00:00
|
|
|
|
using System.Linq;
|
2021-05-25 10:04:26 +01:00
|
|
|
|
using UnityEngine;
|
2022-12-10 13:06:02 +00:00
|
|
|
|
using UnityEngine.UI;
|
2020-08-13 21:46:16 +02:00
|
|
|
|
|
2022-03-02 19:46:33 -08:00
|
|
|
|
namespace QSB.DeathSync.Patches;
|
|
|
|
|
|
|
|
|
|
[HarmonyPatch]
|
|
|
|
|
public class DeathPatches : QSBPatch
|
2020-08-13 21:46:16 +02:00
|
|
|
|
{
|
2022-03-02 19:46:33 -08:00
|
|
|
|
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
|
|
|
|
|
2022-11-19 01:21:28 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// don't take damage from impact in ship
|
|
|
|
|
/// </summary>
|
2022-03-02 19:46:33 -08:00
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(PlayerResources), nameof(PlayerResources.OnImpact))]
|
2022-11-19 01:21:28 -08:00
|
|
|
|
public static bool PlayerResources_OnImpact(PlayerResources __instance, ImpactData impact)
|
|
|
|
|
{
|
|
|
|
|
if (QSBCore.ShipDamage)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return !PlayerState.IsInsideShip();
|
|
|
|
|
}
|
2022-03-02 19:46:33 -08:00
|
|
|
|
|
2022-04-08 21:46:30 -07:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// don't insta-die from impact in ship
|
|
|
|
|
/// </summary>
|
2022-03-02 19:46:33 -08:00
|
|
|
|
[HarmonyPrefix]
|
2022-11-19 01:16:20 -08:00
|
|
|
|
[HarmonyPatch(typeof(HighSpeedImpactSensor), nameof(HighSpeedImpactSensor.HandlePlayerInsideShip))]
|
|
|
|
|
public static bool HighSpeedImpactSensor_HandlePlayerInsideShip(HighSpeedImpactSensor __instance)
|
2022-04-08 21:45:32 -07:00
|
|
|
|
{
|
2022-11-19 01:21:28 -08:00
|
|
|
|
if (QSBCore.ShipDamage)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 01:16:20 -08:00
|
|
|
|
var shipCenter = Locator.GetShipTransform().position + Locator.GetShipTransform().up * 2f;
|
|
|
|
|
var distanceFromShip = Vector3.Distance(__instance._body.GetPosition(), shipCenter);
|
|
|
|
|
if (distanceFromShip > 8f)
|
2022-04-08 21:45:32 -07:00
|
|
|
|
{
|
2022-11-19 01:16:20 -08:00
|
|
|
|
__instance._body.SetPosition(shipCenter);
|
2022-04-08 21:45:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 01:16:20 -08:00
|
|
|
|
if (!__instance._dead)
|
2022-04-08 21:45:32 -07:00
|
|
|
|
{
|
2022-11-19 01:16:20 -08:00
|
|
|
|
var a = __instance._body.GetVelocity() - Locator.GetShipBody().GetPointVelocity(__instance._body.GetPosition());
|
|
|
|
|
if (a.sqrMagnitude > __instance._sqrCheckSpeedThreshold)
|
2022-04-08 21:45:32 -07:00
|
|
|
|
{
|
2022-11-19 01:16:20 -08:00
|
|
|
|
__instance._impactSpeed = a.magnitude;
|
|
|
|
|
__instance._body.AddVelocityChange(-a);
|
2022-04-08 21:45:32 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.FinishDeathSequence))]
|
2023-01-02 21:42:33 -08:00
|
|
|
|
public static bool DeathManager_FinishDeathSequence(DeathManager __instance)
|
2022-12-09 15:51:14 +00:00
|
|
|
|
{
|
2023-01-20 13:57:30 -08:00
|
|
|
|
// funny moment for eye
|
|
|
|
|
if (QSBSceneManager.CurrentScene != OWScene.SolarSystem)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
if (!__instance._isDead)
|
2022-03-02 19:46:33 -08:00
|
|
|
|
{
|
2022-12-09 15:51:14 +00:00
|
|
|
|
if (__instance.CheckShouldWakeInDreamWorld())
|
2022-03-27 23:13:23 -07:00
|
|
|
|
{
|
2022-12-09 15:51:14 +00:00
|
|
|
|
__instance.enabled = true;
|
|
|
|
|
__instance._resurrectAfterDelay = true;
|
|
|
|
|
__instance._resurrectTime = Time.time + 2f;
|
|
|
|
|
return false;
|
2022-03-27 23:13:23 -07:00
|
|
|
|
}
|
2020-08-23 15:51:45 +02:00
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
var deadPlayersCount = QSBPlayerManager.PlayerList.Count(x => x.IsDead);
|
2022-12-10 11:33:14 +00:00
|
|
|
|
if (deadPlayersCount == QSBPlayerManager.PlayerList.Count - 1 && !QSBCore.DebugSettings.DisableLoopDeath)
|
2022-03-27 23:13:23 -07:00
|
|
|
|
{
|
2022-12-09 15:51:14 +00:00
|
|
|
|
new EndLoopMessage().Send();
|
|
|
|
|
DebugLog.DebugWrite($"- All players are dead.");
|
2022-03-27 23:13:23 -07:00
|
|
|
|
}
|
2022-12-10 11:33:14 +00:00
|
|
|
|
else if (!RespawnOnDeath.Instance.AllowedDeathTypes.Contains(__instance._deathType))
|
2022-03-28 12:21:07 -07:00
|
|
|
|
{
|
2022-12-09 15:51:14 +00:00
|
|
|
|
RespawnOnDeath.Instance.ResetPlayer();
|
|
|
|
|
QSBPlayerManager.LocalPlayer.IsDead = true;
|
|
|
|
|
new PlayerDeathMessage(__instance._deathType).Send();
|
|
|
|
|
if (PlayerAttachWatcher.Current)
|
|
|
|
|
{
|
|
|
|
|
PlayerAttachWatcher.Current.DetachPlayer();
|
|
|
|
|
}
|
2022-03-28 12:21:07 -07:00
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-06-15 18:55:54 +01:00
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
__instance._isDead = true;
|
|
|
|
|
GlobalMessenger.FireEvent("DeathSequenceComplete");
|
|
|
|
|
if (PlayerData.GetPersistentCondition("DESTROYED_TIMELINE_LAST_SAVE"))
|
2022-03-27 23:13:23 -07:00
|
|
|
|
{
|
2022-12-09 15:51:14 +00:00
|
|
|
|
PlayerData.SetPersistentCondition("DESTROYED_TIMELINE_LAST_SAVE", false);
|
2022-03-27 23:13:23 -07:00
|
|
|
|
}
|
2021-06-20 14:33:14 +01:00
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
if (__instance._deathType == DeathType.BigBang)
|
|
|
|
|
{
|
|
|
|
|
if (TimeLoopCoreController.ParadoxExists())
|
|
|
|
|
{
|
|
|
|
|
PlayerData.RevertParadoxLoopCountStates();
|
|
|
|
|
}
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
LoadManager.LoadScene(OWScene.Credits_Final, LoadManager.FadeType.ToWhite, 1f, true);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
if (TimeLoopCoreController.ParadoxExists())
|
2022-03-27 23:13:23 -07:00
|
|
|
|
{
|
2022-12-09 15:51:14 +00:00
|
|
|
|
Locator.GetTimelineObliterationController().BeginTimelineObliteration(TimelineObliterationController.ObliterationType.PARADOX_DEATH, null);
|
|
|
|
|
return false;
|
2022-03-27 23:13:23 -07:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-09 15:51:14 +00:00
|
|
|
|
if (TimeLoop.IsTimeFlowing() && TimeLoop.IsTimeLoopEnabled())
|
|
|
|
|
{
|
|
|
|
|
if (__instance._finishedDLC)
|
|
|
|
|
{
|
|
|
|
|
GlobalMessenger.FireEvent("TriggerEndOfDLC");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
GlobalMessenger.FireEvent("TriggerFlashback");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (__instance._deathType == DeathType.Meditation && PlayerState.OnQuantumMoon() && Locator.GetQuantumMoon().GetStateIndex() == 5)
|
|
|
|
|
{
|
|
|
|
|
__instance._timeloopEscapeType = TimeloopEscapeType.Quantum;
|
|
|
|
|
__instance.FinishEscapeTimeLoopSequence();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
GlobalMessenger.FireEvent("TriggerDeathOutsideTimeLoop");
|
|
|
|
|
}
|
2022-03-02 19:46:33 -08:00
|
|
|
|
}
|
2022-12-09 15:51:14 +00:00
|
|
|
|
|
|
|
|
|
return false;
|
2022-03-02 19:46:33 -08:00
|
|
|
|
}
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-12-10 13:06:02 +00:00
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(PauseMenuManager), nameof(PauseMenuManager.Update))]
|
|
|
|
|
public static bool PauseMenuManager_Update(PauseMenuManager __instance)
|
|
|
|
|
{
|
|
|
|
|
// disable meditate button when in respawn map
|
|
|
|
|
|
|
|
|
|
if (__instance._waitingToApplySkipLoopStyle)
|
|
|
|
|
{
|
|
|
|
|
var disableMeditate = PlayerState.IsSleepingAtCampfire() || PlayerState.IsGrabbedByGhost() || QSBPlayerManager.LocalPlayer.IsDead;
|
|
|
|
|
__instance._skipToNextLoopButton.GetComponent<UIStyleApplier>().ChangeState(disableMeditate ? UIElementState.DISABLED : UIElementState.NORMAL, false);
|
|
|
|
|
__instance._waitingToApplySkipLoopStyle = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OWInput.IsNewlyPressed(InputLibrary.pause, InputMode.All) && __instance._isOpen && MenuStackManager.SharedInstance.GetMenuCount() == 1)
|
|
|
|
|
{
|
|
|
|
|
__instance._pauseMenu.EnableMenu(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(PauseMenuManager), nameof(PauseMenuManager.OnActivateMenu))]
|
|
|
|
|
public static bool PauseMenuManager_OnActivateMenu(PauseMenuManager __instance)
|
|
|
|
|
{
|
|
|
|
|
if (__instance._skipToNextLoopButton.activeSelf)
|
|
|
|
|
{
|
|
|
|
|
bool flag = !PlayerState.IsSleepingAtCampfire() && !PlayerState.IsGrabbedByGhost() && !QSBPlayerManager.LocalPlayer.IsDead;
|
|
|
|
|
__instance._endCurrentLoopAction.enabled = flag;
|
|
|
|
|
__instance._skipToNextLoopButton.GetComponent<Selectable>().interactable = flag;
|
|
|
|
|
__instance._skipToNextLoopButton.GetComponent<UIStyleApplier>().SetAutoInputStateChangesEnabled(flag);
|
|
|
|
|
__instance._waitingToApplySkipLoopStyle = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-02 19:46:33 -08:00
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(DestructionVolume), nameof(DestructionVolume.VanishShip))]
|
2022-05-14 14:33:49 +01:00
|
|
|
|
public static bool DestructionVolume_VanishShip(DestructionVolume __instance, OWRigidbody shipBody, RelativeLocationData entryLocation)
|
2022-03-02 19:46:33 -08:00
|
|
|
|
{
|
2022-05-14 14:33:49 +01:00
|
|
|
|
var cockpitIntact = !shipBody.GetComponent<ShipDamageController>().IsCockpitDetached();
|
|
|
|
|
if (PlayerState.IsInsideShip() || PlayerState.UsingShipComputer() || (cockpitIntact && PlayerState.AtFlightConsole()))
|
2022-03-02 19:46:33 -08:00
|
|
|
|
{
|
2022-05-14 14:33:49 +01:00
|
|
|
|
var autopilot = shipBody.GetComponent<Autopilot>();
|
|
|
|
|
if (autopilot != null && autopilot.IsFlyingToDestination())
|
|
|
|
|
{
|
|
|
|
|
var astroObject = __instance.GetComponentInParent<AstroObject>();
|
|
|
|
|
if (astroObject != null && astroObject.GetAstroObjectType() == AstroObject.Type.Star)
|
|
|
|
|
{
|
|
|
|
|
PlayerData.SetPersistentCondition("AUTOPILOT_INTO_SUN", true);
|
|
|
|
|
MonoBehaviour.print("AUTOPILOT_INTO_SUN");
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-02 19:46:33 -08:00
|
|
|
|
|
|
|
|
|
Locator.GetDeathManager().KillPlayer(__instance._deathType);
|
2023-01-04 20:07:35 -08:00
|
|
|
|
// detach the player before vanishing so we dont deactivate the player too
|
2023-01-02 21:42:33 -08:00
|
|
|
|
if (PlayerAttachWatcher.Current)
|
|
|
|
|
{
|
|
|
|
|
PlayerAttachWatcher.Current.DetachPlayer();
|
|
|
|
|
}
|
2023-01-04 20:07:35 -08:00
|
|
|
|
// original method returns here. we dont cuz we want to ship to get deactivated even if the player is inside it
|
2022-03-02 19:46:33 -08:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-14 14:33:49 +01:00
|
|
|
|
__instance.Vanish(shipBody, entryLocation);
|
|
|
|
|
GlobalMessenger.FireEvent("ShipDestroyed");
|
|
|
|
|
return false;
|
2020-12-02 21:23:01 +00:00
|
|
|
|
}
|
2023-01-04 20:07:35 -08:00
|
|
|
|
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(DestructionVolume), nameof(DestructionVolume.VanishShipCockpit))]
|
|
|
|
|
public static bool DestructionVolume_VanishShipCockpit(DestructionVolume __instance, OWRigidbody shipCockpitBody, RelativeLocationData entryLocation)
|
|
|
|
|
{
|
|
|
|
|
if (PlayerState.AtFlightConsole())
|
|
|
|
|
{
|
|
|
|
|
Locator.GetDeathManager().KillPlayer(__instance._deathType);
|
|
|
|
|
// detach the player before vanishing so we dont deactivate the player too
|
|
|
|
|
if (PlayerAttachWatcher.Current)
|
|
|
|
|
{
|
|
|
|
|
PlayerAttachWatcher.Current.DetachPlayer();
|
|
|
|
|
}
|
|
|
|
|
// original method returns here. we dont cuz we want to ship cockpit to get deactivated even if the player is inside it
|
|
|
|
|
}
|
|
|
|
|
__instance.Vanish(shipCockpitBody, entryLocation);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(DestructionVolume), nameof(DestructionVolume.VanishNomaiShuttle))]
|
|
|
|
|
public static bool DestructionVolume_VanishNomaiShuttle(DestructionVolume __instance, OWRigidbody shuttleBody, RelativeLocationData entryLocation)
|
|
|
|
|
{
|
|
|
|
|
if (shuttleBody.GetComponentInChildren<NomaiShuttleController>().IsPlayerInside())
|
|
|
|
|
{
|
|
|
|
|
Locator.GetDeathManager().KillPlayer(__instance._deathType);
|
|
|
|
|
// original method returns here. we dont cuz we want to nomai shuttle to get deactivated even if the player is inside it
|
|
|
|
|
}
|
|
|
|
|
__instance.Vanish(shuttleBody, entryLocation);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-03-29 13:30:45 -07:00
|
|
|
|
}
|