Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ReviveAllies v0.2.5
ReviveAllies.dll
Decompiled a year agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ReviveAllies")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReviveAllies")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("98679114-b256-4e33-bc5d-e532d621ae3b")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Ratzu.Valheim.ReviveAllies; public static class Character_Patch { [HarmonyPatch(typeof(Character), "CheckDeath")] public class PatchCheckDeathCheckRespawnTimeout { public static bool Prefix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { if (val.GetPlayerID() != Game.instance.GetPlayerProfile().GetPlayerID()) { return true; } TombStone activeTombStone = TombStoneManager.GetActiveTombStone(); if ((Object)(object)activeTombStone == (Object)null) { return true; } if (!activeTombStone.IsWithinReviveWindow()) { ReviveAllies.logger.LogInfo((object)"___ REVIVE WINDOW TIMED OUT, RESPAWNING AT DEFAULT LOCATION ___"); ClientRespawnManager.RequestForceRespawn(); } } return true; } } } public static class ClientRespawnManager { public static bool isForceRespawning; public static void RequestRespawnAtTombstone(TombStone tombStone) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)tombStone).transform.position; ReviveAllies.logger.LogInfo((object)$"___ REQUESTING RESPAWN AT LOCATION <{position.x}, {position.y}, {position.z}> ___"); TombStoneManager.isRespawningFromTombstone = true; Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "You are being revived.", 0, (Sprite)null); } Game.instance.RequestRespawn(10f, false); } public static void RequestForceRespawn() { if (!isForceRespawning) { TombStoneManager.ClearActiveTombStone(); isForceRespawning = true; Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "You are being returned to a familiar place.", 0, (Sprite)null); } Game.instance.RequestRespawn(10f, false); } } } public static class Game_Patch { [HarmonyPatch(typeof(Game), "Shutdown")] public static class PatchShutdownClearActiveTombStone { private static bool Prefix(Game __instance) { TombStoneManager.ClearActiveTombStone(); return true; } } [HarmonyPatch(typeof(Game), "FindSpawnPoint")] public static class PatchFindSpawnPointUseRevivePoint { public static bool Prefix(Game __instance, ref bool __result, ref Vector3 point, ref bool usedLogoutPoint, ref float dt) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) __instance.m_respawnWait += dt; usedLogoutPoint = false; if (!__instance.m_respawnAfterDeath && __instance.m_playerProfile.HaveLogoutPoint()) { Vector3 logoutPoint = __instance.m_playerProfile.GetLogoutPoint(); ZNet.instance.SetReferencePosition(logoutPoint); if (__instance.m_respawnWait > __instance.m_respawnLoadDuration && ZNetScene.instance.IsAreaReady(logoutPoint)) { float num = default(float); if (!ZoneSystem.instance.GetGroundHeight(logoutPoint, ref num)) { Vector3 val = logoutPoint; ZLog.Log((object)("Invalid spawn point, no ground " + ((object)(Vector3)(ref val)).ToString())); __instance.m_respawnWait = 0f; __instance.m_playerProfile.ClearLoguoutPoint(); point = Vector3.zero; __result = false; return false; } __instance.m_playerProfile.ClearLoguoutPoint(); point = logoutPoint; if (point.y < num) { point.y = num; } point.y += 0.25f; usedLogoutPoint = true; ZLog.Log((object)("Spawned after " + __instance.m_respawnWait)); __result = true; return false; } point = Vector3.zero; __result = false; return false; } if ((Object)(object)TombStoneManager.GetActiveTombStone() != (Object)null && TombStoneManager.isRespawningFromTombstone) { point = ((Component)TombStoneManager.GetActiveTombStone()).transform.position; ReviveAllies.logger.LogInfo((object)$"Respawning at TombStone <{point.x}, {point.y}, {point.z}>"); __result = true; return false; } if (__instance.m_playerProfile.HaveCustomSpawnPoint()) { Vector3 customSpawnPoint = __instance.m_playerProfile.GetCustomSpawnPoint(); ZNet.instance.SetReferencePosition(customSpawnPoint); if (__instance.m_respawnWait > __instance.m_respawnLoadDuration && ZNetScene.instance.IsAreaReady(customSpawnPoint)) { Bed val2 = __instance.FindBedNearby(customSpawnPoint, 5f); if ((Object)(object)val2 != (Object)null) { ZLog.Log((object)"Found bed at custom spawn point"); point = val2.GetSpawnPoint(); __result = true; return false; } ZLog.Log((object)"Failed to find bed at custom spawn point, using original"); __instance.m_playerProfile.ClearCustomSpawnPoint(); __instance.m_respawnWait = 0f; point = Vector3.zero; __result = false; return false; } point = Vector3.zero; __result = false; return false; } Vector3 val3 = default(Vector3); if (ZoneSystem.instance.GetLocationIcon(__instance.m_StartLocation, ref val3)) { point = val3 + Vector3.up * 2f; ZNet.instance.SetReferencePosition(point); __result = ZNetScene.instance.IsAreaReady(point); return false; } ZNet.instance.SetReferencePosition(Vector3.zero); point = Vector3.zero; __result = false; return false; } } } public static class Player_Patch { [HarmonyPatch(typeof(Player), "Awake")] public class PatchPlayerAwakeRegisterCollisionRPCsAndCheckCollisions { public static void Postfix(Player __instance) { CapsuleCollider val = ((Character)(Player.m_localPlayer?)).m_collider; CapsuleCollider collider = ((Character)__instance).m_collider; if ((Object)(object)val != (Object)null && (Object)(object)collider != (Object)null) { Player localPlayer = Player.m_localPlayer; bool? obj; if (localPlayer == null) { obj = null; } else { ZNetView nview = ((Character)localPlayer).m_nview; if (nview == null) { obj = null; } else { ZDO zDO = nview.GetZDO(); obj = ((zDO != null) ? new bool?(zDO.GetBool("dead", false)) : null); } } bool? flag = obj; int num; if (!flag.GetValueOrDefault()) { ZNetView nview2 = ((Character)__instance).m_nview; bool? obj2; if (nview2 == null) { obj2 = null; } else { ZDO zDO2 = nview2.GetZDO(); obj2 = ((zDO2 != null) ? new bool?(zDO2.GetBool("dead", false)) : null); } flag = obj2; num = (flag.GetValueOrDefault() ? 1 : 0); } else { num = 1; } Physics.IgnoreCollision((Collider)(object)val, (Collider)(object)collider, (byte)num != 0); } ZNetView nview3 = ((Character)__instance).m_nview; if (nview3 != null) { nview3.Register("OnSpawn", (Action<long>)delegate(long sender) { __instance.RPC_OnSpawn(sender); }); } } } [HarmonyPatch(typeof(Player), "FindHoverObject")] public class PatchIgnoreDeadPlayersOnHover { public static bool Prefix(Player __instance, ref GameObject hover, ref Character hoverCreature) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) hover = null; hoverCreature = null; RaycastHit[] array = Physics.RaycastAll(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, 50f, __instance.m_interactMask); Array.Sort(array, (RaycastHit x, RaycastHit y) => ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance)); RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val = array2[i]; if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody) && (Object)(object)((Component)((RaycastHit)(ref val)).collider.attachedRigidbody).gameObject == (Object)(object)((Component)__instance).gameObject) { continue; } if ((Object)(object)hoverCreature == (Object)null) { Character val2 = (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody) ? ((Component)((RaycastHit)(ref val)).collider.attachedRigidbody).GetComponent<Character>() : ((Component)((RaycastHit)(ref val)).collider).GetComponent<Character>()); if ((Object)(object)val2 != (Object)null && (!Object.op_Implicit((Object)(object)val2.GetBaseAI()) || !val2.GetBaseAI().IsSleeping())) { hoverCreature = val2; } } Player component = ((Component)((RaycastHit)(ref val)).collider).GetComponent<Player>(); bool? obj; if (component == null) { obj = null; } else { ZNetView nview = ((Character)component).m_nview; if (nview == null) { obj = null; } else { ZDO zDO = nview.GetZDO(); obj = ((zDO != null) ? new bool?(zDO.GetBool("dead", false)) : null); } } bool? flag = obj; if (flag.GetValueOrDefault()) { continue; } if (Vector3.Distance(((Character)__instance).m_eye.position, ((RaycastHit)(ref val)).point) < __instance.m_maxInteractDistance) { if (((Component)((RaycastHit)(ref val)).collider).GetComponent<Hoverable>() != null) { hover = ((Component)((RaycastHit)(ref val)).collider).gameObject; } else if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody)) { hover = ((Component)((RaycastHit)(ref val)).collider.attachedRigidbody).gameObject; } else { hover = ((Component)((RaycastHit)(ref val)).collider).gameObject; } } break; } return false; } } [HarmonyPatch(typeof(Player), "RPC_OnDeath")] public class PatchRPC_OnDeathDisableCollisionsOnDeath { public static void Postfix(Player __instance) { CapsuleCollider val = ((Character)(Player.m_localPlayer?)).m_collider; CapsuleCollider collider = ((Character)__instance).m_collider; if ((Object)(object)val != (Object)null && (Object)(object)collider != (Object)null) { Physics.IgnoreCollision((Collider)(object)val, (Collider)(object)collider, true); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public class PatchOnSpawnedSendRPCAndClearTombstoneOnSpawned { public static void Postfix(Player __instance) { if (__instance != null) { ZNetView nview = ((Character)__instance).m_nview; if (nview != null) { nview.InvokeRPC("OnSpawn", new object[0]); } } ClientRespawnManager.isForceRespawning = false; TombStoneManager.ClearActiveTombStone(); } } [HarmonyPatch(typeof(Player), "OnDeath")] public class PatchOnDeathDoNotRequestRespawn { public static bool Prefix(Player __instance) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected I4, but got Unknown //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) if (!((Character)__instance).m_nview.IsOwner()) { Debug.Log((object)"OnDeath call but not the owner"); return false; } bool flag = __instance.HardDeath(); ((Character)__instance).m_nview.GetZDO().Set(ZDOVars.s_dead, true); ((Character)__instance).m_nview.InvokeRPC(ZNetView.Everybody, "OnDeath", new object[0]); Game.instance.IncrementPlayerStat((PlayerStatType)0, 1f); HitType hitType = ((Character)__instance).m_lastHit.m_hitType; HitType val = hitType; switch ((int)val) { case 0: Game.instance.IncrementPlayerStat((PlayerStatType)55, 1f); break; case 1: Game.instance.IncrementPlayerStat((PlayerStatType)56, 1f); break; case 2: Game.instance.IncrementPlayerStat((PlayerStatType)57, 1f); break; case 3: Game.instance.IncrementPlayerStat((PlayerStatType)58, 1f); break; case 4: Game.instance.IncrementPlayerStat((PlayerStatType)59, 1f); break; case 5: Game.instance.IncrementPlayerStat((PlayerStatType)60, 1f); break; case 6: Game.instance.IncrementPlayerStat((PlayerStatType)61, 1f); break; case 7: Game.instance.IncrementPlayerStat((PlayerStatType)62, 1f); break; case 8: Game.instance.IncrementPlayerStat((PlayerStatType)64, 1f); break; case 9: Game.instance.IncrementPlayerStat((PlayerStatType)63, 1f); break; case 10: Game.instance.IncrementPlayerStat((PlayerStatType)65, 1f); break; case 11: Game.instance.IncrementPlayerStat((PlayerStatType)66, 1f); break; case 12: Game.instance.IncrementPlayerStat((PlayerStatType)67, 1f); break; case 13: Game.instance.IncrementPlayerStat((PlayerStatType)68, 1f); break; case 14: Game.instance.IncrementPlayerStat((PlayerStatType)69, 1f); break; case 15: Game.instance.IncrementPlayerStat((PlayerStatType)70, 1f); break; case 16: Game.instance.IncrementPlayerStat((PlayerStatType)71, 1f); break; case 17: Game.instance.IncrementPlayerStat((PlayerStatType)72, 1f); break; case 18: Game.instance.IncrementPlayerStat((PlayerStatType)73, 1f); break; default: ZLog.LogWarning((object)("Not implemented death type " + ((object)(HitType)(ref ((Character)__instance).m_lastHit.m_hitType)).ToString())); break; } Game.instance.GetPlayerProfile().SetDeathPoint(((Component)__instance).transform.position); __instance.CreateDeathEffects(); __instance.CreateTombStone(); __instance.m_foods.Clear(); if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)17)) { __instance.m_skills.Clear(); } else if (flag) { __instance.m_skills.OnDeath(); } ((Character)__instance).m_seman.RemoveAllStatusEffects(false); __instance.m_timeSinceDeath = 0f; if (!flag) { ((Character)__instance).Message((MessageType)1, "$msg_softdeath", 0, (Sprite)null); } ((Character)__instance).Message((MessageType)2, "$msg_youdied", 0, (Sprite)null); __instance.ShowTutorial("death", false); Minimap.instance.AddPin(((Component)__instance).transform.position, (PinType)4, $"$hud_mapday {EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds())}", true, false, 0L, ""); if (((Character)__instance).m_onDeath != null) { ((Character)__instance).m_onDeath(); } Biome currentBiome = __instance.GetCurrentBiome(); string text = "biome:" + ((object)(Biome)(ref currentBiome)).ToString(); Gogan.LogEvent("Game", "Death", text, 0L); return false; } } [HarmonyPatch(typeof(Player), "Update")] public class PatchUpdateForceKillOnUseIfHasActiveTombStone { public static void Prefix(Player __instance) { if (((Character)__instance).m_nview.IsValid() && ((Character)__instance).m_nview.IsOwner()) { bool flag = ((Character)__instance).TakeInput(); __instance.UpdateHover(); if (flag && (ZInput.GetButtonDown("Use") || ZInput.GetButtonDown("JoyUse")) && (Object)(object)TombStoneManager.GetActiveTombStone() != (Object)null) { ReviveAllies.logger.LogInfo((object)"___ KILLING SELF ___"); ClientRespawnManager.RequestForceRespawn(); } } } } [HarmonyPatch(typeof(Player), "TakeInput")] public class TakeInputPatchAllowWhileDeadIfPlayerHasActiveTombStone { public static bool Prefix(Player __instance, ref bool __result) { if (((Character)__instance).IsDead() && (Object)(object)TombStoneManager.GetActiveTombStone() != (Object)null) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(Player), "CreateTombStone")] public class PatchCreateTombStoneAlwaysCreate { public static bool Prefix(Player __instance) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) ((Humanoid)__instance).UnequipAllItems(); GameObject val = Object.Instantiate<GameObject>(__instance.m_tombstone, ((Character)__instance).GetCenterPoint(), ((Component)__instance).transform.rotation); val.GetComponent<Container>().GetInventory().MoveInventoryToGrave(((Humanoid)__instance).m_inventory); TombStone component = val.GetComponent<TombStone>(); PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); component.Setup(playerProfile.GetName(), playerProfile.GetPlayerID()); return false; } } public static void RPC_OnSpawn(this Player spawnedPlayer, long sender) { CapsuleCollider val = ((Character)(Player.m_localPlayer?)).m_collider; CapsuleCollider collider = ((Character)spawnedPlayer).m_collider; if ((Object)(object)val != (Object)null && (Object)(object)collider != (Object)null) { Physics.IgnoreCollision((Collider)(object)val, (Collider)(object)collider, false); } } } [BepInPlugin("ratzu.mods.reviveallies", "Revive Allies", "1.0.0")] public class ReviveAllies : BaseUnityPlugin { public const string Version = "1.0.0"; public const string Name = "Revive Allies"; public const string Guid = "ratzu.mods.reviveallies"; public const string Namespace = "Ratzu.Valheim.ReviveAllies"; private static int reviveWindowInSeconds = 60; public static long reviveWindowInTicks = (long)((double)reviveWindowInSeconds * 1000.0 * 10000.0); private Harmony _harmony; public static ManualLogSource logger; private void Awake() { logger = ((BaseUnityPlugin)this).Logger; _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "ratzu.mods.reviveallies"); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public static class TombStoneManager { public static bool isRespawningFromTombstone; private static TombStone activeTombStone; public static TombStone CreateTombStone(Player player) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) ((Humanoid)player).UnequipAllItems(); GameObject val = Object.Instantiate<GameObject>(player.m_tombstone, ((Character)player).GetCenterPoint(), ((Component)player).transform.rotation); val.GetComponent<Container>().GetInventory().MoveInventoryToGrave(((Humanoid)player).m_inventory); TombStone component = val.GetComponent<TombStone>(); PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); component.Setup(playerProfile.GetName(), playerProfile.GetPlayerID()); return component; } public static TombStone GetActiveTombStone() { return activeTombStone; } public static void SetActiveTombStone(TombStone tombStone) { ClearActiveTombStone(); activeTombStone = tombStone; tombStone.m_nview.GetZDO().Set("is_active_tombstone", true); ReviveAllies.logger.LogInfo((object)"___ ACTIVE TOMBSTONE SET ___"); } public static void ClearActiveTombStone() { if (!((Object)(object)activeTombStone == (Object)null)) { if (isRespawningFromTombstone) { activeTombStone.m_container.TakeAll((Humanoid)(object)Player.m_localPlayer); isRespawningFromTombstone = false; } TombStone val = activeTombStone; activeTombStone = null; val.m_nview.GetZDO().Set("is_active_tombstone", false); ReviveAllies.logger.LogInfo((object)"___ ACTIVE TOMBSTONE CLEARED ___"); } } } public static class TombStone_Patch { [HarmonyPatch(typeof(TombStone), "Start")] public static class PatchTombStoneStartRegisterReviveRPC { private static bool Prefix(TombStone __instance) { __instance.m_nview = ((Component)__instance).GetComponent<ZNetView>(); ZNetView nview = __instance.m_nview; if (nview != null) { nview.Register("ReviveOwner", (Action<long>)__instance.RPC_Revive); } return true; } } [HarmonyPatch(typeof(TombStone), "Interact")] public class PatchTombStoneInteractReviveFromTombStone { public static bool Prefix(TombStone __instance, ref bool hold, ref bool __result) { if (hold) { __result = false; return false; } Player obj = __instance.FindOwner(); long? num = ((obj != null) ? new long?(obj.GetPlayerID()) : null); Player localPlayer = Player.m_localPlayer; long? num2 = ((localPlayer != null) ? new long?(localPlayer.GetPlayerID()) : null); if (!num.HasValue || !num2.HasValue || num == num2 || !__instance.IsRevivable()) { return true; } __instance.m_nview.InvokeRPC("ReviveOwner", new object[0]); Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Character)localPlayer2).Message((MessageType)1, string.Format("You are reviving {0}", __instance.m_nview.GetZDO().GetString("ownerName", "")), 0, (Sprite)null); } ReviveAllies.logger.LogInfo((object)"___ REVIVING PLAYER: REVIVE SENT ___"); __result = true; return false; } } [HarmonyPatch(typeof(TombStone), "UpdateDespawn")] public class PatchUpdateDespawnDoNotDestroyIfReviveIsActive { public static bool Prefix(TombStone __instance) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!__instance.m_nview.IsValid()) { return false; } if ((Object)(object)__instance.m_floater != (Object)null) { __instance.UpdateFloater(); } if (__instance.m_nview.IsOwner()) { __instance.PositionCheck(); if (!__instance.m_container.IsInUse() && __instance.m_container.GetInventory().NrOfItems() <= 0 && !__instance.IsRevivable()) { __instance.GiveBoost(); __instance.m_removeEffect.Create(((Component)__instance).transform.position, ((Component)__instance).transform.rotation, (Transform)null, 1f, -1); __instance.m_nview.Destroy(); } } return false; } } [HarmonyPatch(typeof(TombStone), "Setup")] public class PatchSetupSetupActiveTombStone { public static void Prefix(TombStone __instance) { TombStoneManager.SetActiveTombStone(__instance); } } [HarmonyPatch(typeof(TombStone), "GetHoverText")] public class PatchTombStoneGetHoverTextShowRevive { public static bool Prefix(TombStone __instance, ref string __result) { Player obj = __instance.FindOwner(); long? num = ((obj != null) ? new long?(obj.GetPlayerID()) : null); Player localPlayer = Player.m_localPlayer; long? num2 = ((localPlayer != null) ? new long?(localPlayer.GetPlayerID()) : null); if (!num.HasValue || !num2.HasValue || num == num2 || !__instance.IsRevivable()) { return true; } if (!__instance.m_nview.IsValid()) { return true; } string @string = __instance.m_nview.GetZDO().GetString("ownerName", ""); string text = __instance.m_text + " " + @string; __result = Localization.instance.Localize(text) + Localization.instance.Localize("\n[<color=yellow><b>$KEY_Use</b></color>] Revive"); return false; } } public static bool IsWithinReviveWindow(this TombStone tombStone) { return ZNet.instance.GetTime().Ticks <= tombStone.m_nview.GetZDO().GetLong("timeOfDeath", 0L) + ReviveAllies.reviveWindowInTicks; } public static bool IsRevivable(this TombStone tombStone) { int result; if (tombStone.IsWithinReviveWindow()) { ZNetView nview = tombStone.m_nview; bool? obj; if (nview == null) { obj = null; } else { ZDO zDO = nview.GetZDO(); obj = ((zDO != null) ? new bool?(zDO.GetBool("is_active_tombstone", false)) : null); } bool? flag = obj; result = (flag.GetValueOrDefault() ? 1 : 0); } else { result = 0; } return (byte)result != 0; } public static bool IsInstanceOwner(this TombStone tombStone) { Player localPlayer = Player.m_localPlayer; long? num = ((localPlayer != null) ? new long?(localPlayer.GetPlayerID()) : null); if (!num.HasValue) { return false; } return num == tombStone.FindOwner().GetPlayerID(); } public static void RPC_Revive(this TombStone tombStone, long sender) { ReviveAllies.logger.LogInfo((object)"___ REVIVING SELF: REVIVE RECEIVED ___"); if (!tombStone.IsRevivable()) { ReviveAllies.logger.LogInfo((object)"___ REVIVING SELF: TOMBSTONE NOT REVIVABLE ___"); } if (!tombStone.IsInstanceOwner()) { ReviveAllies.logger.LogInfo((object)"___ REVIVING SELF: NOT OWNER OF TOMBSTONE ___"); return; } ReviveAllies.logger.LogInfo((object)"___ REVIVING SELF: TOMBSTONE VALID ___"); ClientRespawnManager.RequestRespawnAtTombstone(tombStone); } }