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-01-14 22:31:48 -08:00
|
|
|
|
using QSB.ShipSync.TransformSync;
|
2020-12-14 21:20:53 +00:00
|
|
|
|
using System.Linq;
|
2021-05-25 10:04:26 +01:00
|
|
|
|
using UnityEngine;
|
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;
|
|
|
|
|
|
|
|
|
|
// TODO : Remove with future functionality.
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(ShipEjectionSystem), nameof(ShipEjectionSystem.OnPressInteract))]
|
|
|
|
|
public static bool DisableEjection()
|
|
|
|
|
=> false;
|
|
|
|
|
|
|
|
|
|
// TODO : Remove with future functionality.
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(ShipDetachableLeg), nameof(ShipDetachableLeg.Detach))]
|
|
|
|
|
public static bool ShipDetachableLeg_Detach(out OWRigidbody __result)
|
|
|
|
|
{
|
|
|
|
|
__result = null;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO : Remove with future functionality.
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(ShipDetachableModule), nameof(ShipDetachableModule.Detach))]
|
|
|
|
|
public static bool ShipDetachableModule_Detach(out OWRigidbody __result)
|
|
|
|
|
{
|
|
|
|
|
__result = null;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(PlayerResources), nameof(PlayerResources.OnImpact))]
|
2022-03-29 13:17:52 -07:00
|
|
|
|
public static bool PlayerResources_OnImpact(PlayerResources __instance, ImpactData impact) =>
|
2022-03-29 13:30:45 -07:00
|
|
|
|
// don't take damage from impact in ship
|
2022-03-29 13:17:52 -07:00
|
|
|
|
!PlayerState.IsInsideShip();
|
2022-03-02 19:46:33 -08:00
|
|
|
|
|
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(HighSpeedImpactSensor), nameof(HighSpeedImpactSensor.FixedUpdate))]
|
2022-03-29 13:30:45 -07:00
|
|
|
|
public static bool HighSpeedImpactSensor_FixedUpdate(HighSpeedImpactSensor __instance) =>
|
|
|
|
|
// don't insta-die from impact in ship
|
|
|
|
|
!PlayerState.IsInsideShip();
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-03-02 19:46:33 -08:00
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
|
2022-03-27 23:13:23 -07:00
|
|
|
|
private static bool DeathManager_KillPlayer(DeathManager __instance, DeathType deathType)
|
2022-03-02 19:46:33 -08:00
|
|
|
|
{
|
2022-03-27 23:13:23 -07:00
|
|
|
|
Original(__instance, deathType);
|
|
|
|
|
return false;
|
2022-02-05 04:03:12 -08:00
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
static void Original(DeathManager @this, DeathType deathType)
|
2022-03-02 19:46:33 -08:00
|
|
|
|
{
|
2022-03-27 23:13:23 -07:00
|
|
|
|
@this._fakeMeditationDeath = false;
|
|
|
|
|
if (deathType == DeathType.Meditation && @this.CheckShouldWakeInDreamWorld())
|
|
|
|
|
{
|
|
|
|
|
@this._fakeMeditationDeath = true;
|
|
|
|
|
OWInput.ChangeInputMode(InputMode.None);
|
|
|
|
|
ReticleController.Hide();
|
|
|
|
|
Locator.GetPromptManager().SetPromptsVisible(false);
|
|
|
|
|
GlobalMessenger.FireEvent("FakePlayerMeditationDeath");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (deathType == DeathType.DreamExplosion)
|
|
|
|
|
{
|
|
|
|
|
Achievements.Earn(Achievements.Type.EARLY_ADOPTER);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (PlayerState.InDreamWorld() && deathType != DeathType.Dream && deathType != DeathType.DreamExplosion && deathType != DeathType.Supernova && deathType != DeathType.TimeLoop && deathType != DeathType.Meditation)
|
|
|
|
|
{
|
|
|
|
|
Locator.GetDreamWorldController().ExitDreamWorld(deathType);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!@this._isDying)
|
|
|
|
|
{
|
|
|
|
|
if (@this._invincible && deathType != DeathType.Supernova && deathType != DeathType.BigBang && deathType != DeathType.Meditation && deathType != DeathType.TimeLoop && deathType != DeathType.BlackHole)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-28 12:21:07 -07:00
|
|
|
|
if (!Custom(@this, deathType))
|
2022-03-27 23:13:23 -07:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!TimeLoopCoreController.ParadoxExists())
|
|
|
|
|
{
|
|
|
|
|
var component = Locator.GetPlayerBody().GetComponent<PlayerResources>();
|
|
|
|
|
if ((deathType == DeathType.TimeLoop || deathType == DeathType.Supernova) && component.GetTotalDamageThisLoop() > 1000f)
|
|
|
|
|
{
|
|
|
|
|
Achievements.Earn(Achievements.Type.DIEHARD);
|
|
|
|
|
PlayerData.SetPersistentCondition("THERE_IS_BUT_VOID", true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((TimeLoop.GetLoopCount() != 1 && TimeLoop.GetSecondsElapsed() < 60f || TimeLoop.GetLoopCount() == 1 && Time.timeSinceLevelLoad < 60f && !TimeLoop.IsTimeFlowing()) && deathType != DeathType.Meditation && LoadManager.GetCurrentScene() == OWScene.SolarSystem)
|
|
|
|
|
{
|
|
|
|
|
Achievements.Earn(Achievements.Type.GONE_IN_60_SECONDS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TimeLoop.GetLoopCount() > 1)
|
|
|
|
|
{
|
|
|
|
|
Achievements.SetHeroStat(Achievements.HeroStat.TIMELOOP_COUNT, (uint)(TimeLoop.GetLoopCount() - 1));
|
|
|
|
|
if (deathType == DeathType.TimeLoop || deathType == DeathType.BigBang || deathType == DeathType.Supernova)
|
|
|
|
|
{
|
|
|
|
|
PlayerData.CompletedFullTimeLoop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (deathType == DeathType.Supernova && !PlayerData.GetPersistentCondition("KILLED_BY_SUPERNOVA_AND_KNOWS_IT") && PlayerData.GetFullTimeLoopsCompleted() > 2U && PlayerData.GetPersistentCondition("HAS_SEEN_SUN_EXPLODE"))
|
|
|
|
|
{
|
|
|
|
|
PlayerData.SetPersistentCondition("KILLED_BY_SUPERNOVA_AND_KNOWS_IT", true);
|
|
|
|
|
MonoBehaviour.print("KILLED_BY_SUPERNOVA_AND_KNOWS_IT");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@this._isDying = true;
|
|
|
|
|
@this._deathType = deathType;
|
|
|
|
|
MonoBehaviour.print("Player was killed by " + deathType);
|
|
|
|
|
Locator.GetPauseCommandListener().AddPauseCommandLock();
|
|
|
|
|
PlayerData.SetLastDeathType(deathType);
|
|
|
|
|
GlobalMessenger<DeathType>.FireEvent("PlayerDeath", deathType);
|
|
|
|
|
}
|
2022-03-02 19:46:33 -08:00
|
|
|
|
}
|
2022-02-05 04:03:12 -08:00
|
|
|
|
|
2022-03-28 12:21:07 -07:00
|
|
|
|
static bool Custom(DeathManager @this, DeathType deathType)
|
2022-03-02 19:46:33 -08:00
|
|
|
|
{
|
2022-03-27 23:13:23 -07:00
|
|
|
|
if (RespawnOnDeath.Instance == null)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2020-08-23 15:51:45 +02:00
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
if (RespawnOnDeath.Instance.AllowedDeathTypes.Contains(deathType))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-03-02 19:46:33 -08:00
|
|
|
|
|
2022-03-28 12:21:07 -07:00
|
|
|
|
if (@this.CheckShouldWakeInDreamWorld())
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
if (QSBPlayerManager.LocalPlayer.IsDead)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-06-15 18:55:54 +01:00
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
var deadPlayersCount = QSBPlayerManager.PlayerList.Count(x => x.IsDead);
|
|
|
|
|
if (deadPlayersCount == QSBPlayerManager.PlayerList.Count - 1)
|
|
|
|
|
{
|
|
|
|
|
new EndLoopMessage().Send();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2021-06-20 14:33:14 +01:00
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
RespawnOnDeath.Instance.ResetPlayer();
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
QSBPlayerManager.LocalPlayer.IsDead = true;
|
|
|
|
|
new PlayerDeathMessage(deathType).Send();
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-03-27 23:13:23 -07:00
|
|
|
|
if (PlayerAttachWatcher.Current)
|
|
|
|
|
{
|
|
|
|
|
PlayerAttachWatcher.Current.DetachPlayer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2022-03-02 19:46:33 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-24 22:04:54 -08:00
|
|
|
|
|
2022-03-29 13:17:52 -07:00
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(ShipDamageController), nameof(ShipDamageController.Explode))]
|
|
|
|
|
public static bool ShipDamageController_Explode()
|
|
|
|
|
// prevent ship from exploding
|
|
|
|
|
// todo remove this when sync ship explosions
|
|
|
|
|
=> false;
|
2022-02-27 04:40:44 -08:00
|
|
|
|
|
2022-03-02 19:46:33 -08:00
|
|
|
|
[HarmonyPrefix]
|
|
|
|
|
[HarmonyPatch(typeof(DestructionVolume), nameof(DestructionVolume.VanishShip))]
|
|
|
|
|
public static bool DestructionVolume_VanishShip(DestructionVolume __instance)
|
|
|
|
|
{
|
|
|
|
|
if (RespawnOnDeath.Instance == null)
|
|
|
|
|
{
|
2022-02-27 04:40:44 -08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-03-02 19:46:33 -08:00
|
|
|
|
|
2022-03-29 13:17:52 -07:00
|
|
|
|
// apparently this is to fix a weird bug when flying into the sun. idk this is 2-year-old code.
|
2022-03-02 19:46:33 -08:00
|
|
|
|
if (!ShipTransformSync.LocalInstance.hasAuthority)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (PlayerState.IsInsideShip() || PlayerState.UsingShipComputer() || PlayerState.AtFlightConsole())
|
|
|
|
|
{
|
|
|
|
|
Locator.GetDeathManager().KillPlayer(__instance._deathType);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-29 13:17:52 -07:00
|
|
|
|
// don't actually delete the ship to allow respawns or something
|
|
|
|
|
|
2022-03-02 19:46:33 -08:00
|
|
|
|
return true;
|
2020-12-02 21:23:01 +00:00
|
|
|
|
}
|
2022-03-29 13:30:45 -07:00
|
|
|
|
}
|