Decompiled source of ReviveAllies v0.2.5

ReviveAllies.dll

Decompiled 2 weeks ago
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);
	}
}