using 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);
}
}