253 lines
8.2 KiB
C#
Raw Normal View History

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;
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]
[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;
}
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
{
__instance._body.SetPosition(shipCenter);
2022-04-08 21:45:32 -07:00
}
if (!__instance._dead)
2022-04-08 21:45:32 -07: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
{
__instance._impactSpeed = a.magnitude;
__instance._body.AddVelocityChange(-a);
2022-04-08 21:45:32 -07:00
}
}
return false;
}
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-12-09 15:51:14 +00:00
__instance.enabled = true;
__instance._resurrectAfterDelay = true;
__instance._resurrectTime = Time.time + 2f;
return false;
}
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-12-09 15:51:14 +00:00
new EndLoopMessage().Send();
DebugLog.DebugWrite($"- All players are dead.");
}
2022-12-10 11:33:14 +00:00
else if (!RespawnOnDeath.Instance.AllowedDeathTypes.Contains(__instance._deathType))
{
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();
}
return false;
}
2022-12-09 15:51:14 +00:00
__instance._isDead = true;
GlobalMessenger.FireEvent("DeathSequenceComplete");
if (PlayerData.GetPersistentCondition("DESTROYED_TIMELINE_LAST_SAVE"))
{
2022-12-09 15:51:14 +00:00
PlayerData.SetPersistentCondition("DESTROYED_TIMELINE_LAST_SAVE", false);
}
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-12-09 15:51:14 +00:00
LoadManager.LoadScene(OWScene.Credits_Final, LoadManager.FadeType.ToWhite, 1f, true);
return false;
}
2022-12-09 15:51:14 +00:00
if (TimeLoopCoreController.ParadoxExists())
{
2022-12-09 15:51:14 +00:00
Locator.GetTimelineObliterationController().BeginTimelineObliteration(TimelineObliterationController.ObliterationType.PARADOX_DEATH, null);
return false;
}
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-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);
// 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();
}
// 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
}
[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
}