Decompiled source of Zombie v0.2.0

plugins\com.EMOKaMi.Zombie.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.EMOKaMi.Zombie")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.9.0")]
[assembly: AssemblyInformationalVersion("0.1.9")]
[assembly: AssemblyProduct("com.EMOKaMi.Zombie")]
[assembly: AssemblyTitle("Zombie")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.9.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Zombie
{
	[BepInPlugin("com.EMOKaMi.Zombie", "Zombie", "0.1.9")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Id = "com.EMOKaMi.Zombie";

		internal static ManualLogSource Log { get; private set; }

		public static Plugin Instance { get; private set; }

		public static string Name => "Zombie";

		public static string Version => "0.1.9";

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, (string)null);
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
			if (!Object.op_Implicit((Object)(object)((Component)this).gameObject.GetComponent<ZombieModeManager>()))
			{
				((Component)this).gameObject.AddComponent<ZombieModeManager>();
			}
		}
	}
	public class ZombieModeManager : MonoBehaviourPunCallbacks
	{
		public enum GameState
		{
			Waiting,
			InitialCountdown,
			Active,
			RoundIntermission,
			ZombieWin,
			HumanWin
		}

		public static ZombieModeManager Instance;

		public GameState CurrentState;

		public float StateTimer;

		private const float COUNTDOWN_TIME = 10f;

		private const float INTERMISSION_TIME = 10f;

		public float Setting_RespawnTime = 60f;

		public int Setting_InitialZombies = 1;

		public float Setting_InfectionDmg = 0.5f;

		public bool Setting_InfiniteStamina;

		private Dictionary<int, float> pendingRespawns = new Dictionary<int, float>();

		private Dictionary<int, bool> isPendingConversion = new Dictionary<int, bool>();

		private Rect uiRect = new Rect((float)(Screen.width - 350), 10f, 340f, 150f);

		private Rect respawnUiRect = new Rect((float)(Screen.width / 2 - 150), (float)(Screen.height / 2 + 50), 300f, 100f);

		private Rect settingsRect = new Rect(50f, 50f, 350f, 350f);

		private bool showSettings;

		private List<int> zombieActorNumbers = new List<int>();

		private int alphaZombieActorNumber = -1;

		public bool IsSystemReviving;

		private float localRespawnEndTime;

		private bool localIsConversion;

		public bool IsZombiesFrozen
		{
			get
			{
				if (CurrentState != GameState.RoundIntermission)
				{
					return CurrentState == GameState.InitialCountdown;
				}
				return true;
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			if (!PhotonNetwork.InRoom)
			{
				return;
			}
			if (PhotonNetwork.IsMasterClient && Input.GetKeyDown((KeyCode)291))
			{
				showSettings = !showSettings;
				if (showSettings)
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
				}
			}
			if (PhotonNetwork.IsMasterClient && Input.GetKeyDown((KeyCode)289))
			{
				Plugin.Log.LogInfo((object)"Forcing Game Start via F8");
				OnReachFirstMountain();
			}
			if (PhotonNetwork.IsMasterClient)
			{
				UpdateMasterLogic();
				UpdateRespawnLogic();
			}
		}

		public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"Z_RespawnTime"))
			{
				Setting_RespawnTime = (float)propertiesThatChanged[(object)"Z_RespawnTime"];
			}
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"Z_InitialCount"))
			{
				Setting_InitialZombies = (int)propertiesThatChanged[(object)"Z_InitialCount"];
			}
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"Z_Infection"))
			{
				Setting_InfectionDmg = (float)propertiesThatChanged[(object)"Z_Infection"];
			}
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"Z_InfStamina"))
			{
				Setting_InfiniteStamina = (bool)propertiesThatChanged[(object)"Z_InfStamina"];
			}
		}

		private void SyncSettings()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0066: Expected O, but got Unknown
			if (PhotonNetwork.IsMasterClient)
			{
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"Z_RespawnTime", (object)Setting_RespawnTime);
				((Dictionary<object, object>)val).Add((object)"Z_InitialCount", (object)Setting_InitialZombies);
				((Dictionary<object, object>)val).Add((object)"Z_Infection", (object)Setting_InfectionDmg);
				((Dictionary<object, object>)val).Add((object)"Z_InfStamina", (object)Setting_InfiniteStamina);
				Hashtable val2 = val;
				PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
			}
		}

		private void UpdateMasterLogic()
		{
			if (StateTimer > 0f)
			{
				StateTimer -= Time.deltaTime;
			}
			switch (CurrentState)
			{
			case GameState.InitialCountdown:
				if (StateTimer <= 0f)
				{
					StartGame();
				}
				break;
			case GameState.RoundIntermission:
				if (StateTimer <= 0f)
				{
					StartRound();
				}
				break;
			case GameState.Active:
				CheckWinConditions();
				break;
			}
		}

		private void UpdateRespawnLogic()
		{
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, float> pendingRespawn in pendingRespawns)
			{
				if (Time.time >= pendingRespawn.Value)
				{
					list.Add(pendingRespawn.Key);
				}
			}
			foreach (int item in list)
			{
				bool flag = isPendingConversion.ContainsKey(item) && isPendingConversion[item];
				float num = ((item == alphaZombieActorNumber) ? 1f : 0.7f);
				if (flag)
				{
					((MonoBehaviourPun)this).photonView.RPC("RPC_MakeZombie", (RpcTarget)0, new object[2] { item, num });
				}
				else
				{
					((MonoBehaviourPun)this).photonView.RPC("RPC_RespawnZombie", (RpcTarget)0, new object[2] { item, num });
				}
				pendingRespawns.Remove(item);
				isPendingConversion.Remove(item);
			}
		}

		public void ForceRespawnZombie(int actorNumber)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				if (pendingRespawns.ContainsKey(actorNumber))
				{
					pendingRespawns.Remove(actorNumber);
				}
				if (isPendingConversion.ContainsKey(actorNumber))
				{
					isPendingConversion.Remove(actorNumber);
				}
				float num = ((actorNumber == alphaZombieActorNumber) ? 1f : 0.7f);
				((MonoBehaviourPun)this).photonView.RPC("RPC_RespawnZombie", (RpcTarget)0, new object[2] { actorNumber, num });
				((MonoBehaviourPun)this).photonView.RPC("RPC_SyncRespawnTimer", (RpcTarget)0, new object[3] { actorNumber, 0f, false });
			}
		}

		public void OnRunStarted()
		{
			ResetGame();
			((MonoBehaviour)this).StartCoroutine(CheckBeachRoutine());
		}

		private IEnumerator CheckBeachRoutine()
		{
			yield return (object)new WaitForSeconds(1f);
			if (Object.op_Implicit((Object)(object)Singleton<MapHandler>.Instance) && (int)Singleton<MapHandler>.Instance.GetCurrentSegment() == 0)
			{
				Plugin.Log.LogInfo((object)"Run Started at Beach! Starting Zombie Countdown...");
				OnReachFirstMountain();
			}
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_SetState", newPlayer, new object[2] { CurrentState, StateTimer });
				((MonoBehaviourPun)this).photonView.RPC("RPC_SyncZombieList", newPlayer, new object[1] { zombieActorNumbers.ToArray() });
				SyncSettings();
			}
		}

		[PunRPC]
		private void RPC_SyncZombieList(int[] zombies)
		{
			zombieActorNumbers.Clear();
			zombieActorNumbers.AddRange(zombies);
		}

		public void OnReachFirstMountain()
		{
			if (CurrentState == GameState.Waiting)
			{
				SetStateRPC(GameState.InitialCountdown, 10f);
			}
		}

		public void OnCampfireLit(Vector3 teleportPos)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (CurrentState == GameState.Active)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_TeleportAll", (RpcTarget)0, new object[1] { teleportPos });
				SetStateRPC(GameState.RoundIntermission, 10f);
			}
		}

		public void OnPlayerDied(int actorNumber, bool wasAlreadyZombie)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				float num = (wasAlreadyZombie ? Setting_RespawnTime : 3f);
				pendingRespawns[actorNumber] = Time.time + num;
				isPendingConversion[actorNumber] = !wasAlreadyZombie;
				((MonoBehaviourPun)this).photonView.RPC("RPC_SyncRespawnTimer", (RpcTarget)0, new object[3]
				{
					actorNumber,
					num,
					!wasAlreadyZombie
				});
			}
		}

		private void StartGame()
		{
			Player[] playerList = PhotonNetwork.PlayerList;
			if (playerList.Length != 0)
			{
				int num = Mathf.Min(Setting_InitialZombies, playerList.Length);
				List<int> list = new List<int>();
				while (list.Count < num)
				{
					int item = Random.Range(0, playerList.Length);
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
				foreach (int item2 in list)
				{
					Player val = playerList[item2];
					if (alphaZombieActorNumber == -1)
					{
						((MonoBehaviourPun)this).photonView.RPC("RPC_SetAlpha", (RpcTarget)0, new object[1] { val.ActorNumber });
					}
					((MonoBehaviourPun)this).photonView.RPC("RPC_MakeZombie", (RpcTarget)0, new object[2] { val.ActorNumber, 0f });
				}
			}
			SetStateRPC(GameState.Active, 0f);
		}

		private void StartRound()
		{
			SetStateRPC(GameState.Active, 0f);
		}

		private void CheckWinConditions()
		{
			int num = 0;
			Player[] playerList = PhotonNetwork.PlayerList;
			Character val2 = default(Character);
			foreach (Player val in playerList)
			{
				if (!zombieActorNumbers.Contains(val.ActorNumber) && PlayerHandler.TryGetCharacter(val.ActorNumber, ref val2) && !val2.data.dead && !val2.data.fullyPassedOut)
				{
					num++;
				}
			}
			if (num == 0 && PhotonNetwork.PlayerList.Length != 0)
			{
				SetStateRPC(GameState.ZombieWin, 0f);
			}
		}

		public void OnHumanVictory()
		{
			SetStateRPC(GameState.HumanWin, 0f);
		}

		private void SetStateRPC(GameState state, float timer)
		{
			((MonoBehaviourPun)this).photonView.RPC("RPC_SetState", (RpcTarget)0, new object[2] { state, timer });
		}

		[PunRPC]
		private void RPC_SetState(GameState state, float timer)
		{
			CurrentState = state;
			StateTimer = timer;
		}

		[PunRPC]
		private void RPC_SetAlpha(int actorNumber)
		{
			alphaZombieActorNumber = actorNumber;
			if (!zombieActorNumbers.Contains(actorNumber))
			{
				zombieActorNumbers.Add(actorNumber);
			}
		}

		[PunRPC]
		private void RPC_MakeZombie(int actorNumber, float injury)
		{
			if (!zombieActorNumbers.Contains(actorNumber))
			{
				zombieActorNumbers.Add(actorNumber);
			}
			if (PhotonNetwork.LocalPlayer.ActorNumber == actorNumber)
			{
				((MonoBehaviour)this).StartCoroutine(TransformToZombieRoutine(injury));
			}
		}

		[PunRPC]
		private void RPC_RespawnZombie(int actorNumber, float injury)
		{
			if (PhotonNetwork.LocalPlayer.ActorNumber == actorNumber)
			{
				((MonoBehaviour)this).StartCoroutine(TransformToZombieRoutine(injury));
			}
		}

		private IEnumerator TransformToZombieRoutine(float injury)
		{
			while ((Object)(object)Character.localCharacter == (Object)null)
			{
				yield return null;
			}
			Character myChar = Character.localCharacter;
			IsSystemReviving = true;
			if (myChar.data.dead)
			{
				((MonoBehaviourPun)myChar).photonView.RPC("RPCA_Revive", (RpcTarget)0, new object[1] { true });
			}
			yield return null;
			myChar.refs.afflictions.SetStatus((STATUSTYPE)0, injury, true);
			IsSystemReviving = false;
			if (myChar.isZombie)
			{
				yield break;
			}
			GameObject val = PhotonNetwork.Instantiate("MushroomZombie_Player", ((Component)myChar).transform.position, ((Component)myChar).transform.rotation, (byte)0, (object[])null);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"Failed to instantiate MushroomZombie_Player!");
				yield break;
			}
			MushroomZombie component = val.GetComponent<MushroomZombie>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.isNPCZombie = false;
			}
			val.GetComponent<PhotonView>().RPC("RPC_Arise", (RpcTarget)0, new object[1] { ((MonoBehaviourPun)myChar).photonView.ViewID });
		}

		[PunRPC]
		private void RPC_SyncRespawnTimer(int actorNumber, float duration, bool isConversion)
		{
			if (PhotonNetwork.LocalPlayer.ActorNumber == actorNumber)
			{
				localRespawnEndTime = Time.time + duration;
				localIsConversion = isConversion;
			}
		}

		[PunRPC]
		private void RPC_TeleportAll(Vector3 pos)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Character.localCharacter))
			{
				Character.localCharacter.WarpPlayerRPC(pos + Vector3.up * 2f, false);
			}
		}

		public void ResetGame()
		{
			CurrentState = GameState.Waiting;
			zombieActorNumbers.Clear();
			pendingRespawns.Clear();
			isPendingConversion.Clear();
			alphaZombieActorNumber = -1;
		}

		public bool IsPlayerZombie(int actorNumber)
		{
			return zombieActorNumbers.Contains(actorNumber);
		}

		private void OnGUI()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.InRoom)
			{
				return;
			}
			if (showSettings && PhotonNetwork.IsMasterClient)
			{
				settingsRect = GUI.Window(999003, settingsRect, new WindowFunction(DrawSettingsWindow), "PEAK Zombie Mode Settings");
			}
			if (CurrentState != 0)
			{
				GUI.skin.label.fontSize = 20;
				GUI.skin.label.alignment = (TextAnchor)2;
				string text = "";
				Color color = Color.white;
				bool flag = IsPlayerZombie(PhotonNetwork.LocalPlayer.ActorNumber);
				switch (CurrentState)
				{
				case GameState.InitialCountdown:
					text = $"ZOMBIE INFECTION IN: {StateTimer:F1}";
					color = Color.red;
					break;
				case GameState.RoundIntermission:
					text = $"人類已逃亡到營火處\n下回合將在倒數 {StateTimer:F1} 秒後開始";
					color = Color.green;
					break;
				case GameState.Active:
					if (flag)
					{
						text = "YOU ARE INFECTED\nHUNT THE HUMANS!";
						color = Color.green;
					}
					else
					{
						text = "SURVIVE! REACH THE PEAK!";
						color = Color.white;
					}
					break;
				case GameState.ZombieWin:
					text = "ZOMBIE VICTORY\nALL HUMANS INFECTED";
					color = Color.red;
					GUI.skin.label.fontSize = 40;
					break;
				case GameState.HumanWin:
					text = "HUMAN VICTORY\nESCAPED THE PEAK";
					color = Color.cyan;
					GUI.skin.label.fontSize = 40;
					break;
				}
				GUI.color = color;
				GUI.Label(uiRect, text);
				GUI.color = Color.white;
				GUI.skin.label.fontSize = 12;
				GUI.skin.label.alignment = (TextAnchor)0;
			}
			if (Time.time < localRespawnEndTime)
			{
				float num = localRespawnEndTime - Time.time;
				string arg = (localIsConversion ? "TURNING INTO ZOMBIE IN" : "RESPAWNING IN");
				GUI.skin.label.fontSize = 30;
				GUI.skin.label.alignment = (TextAnchor)4;
				GUI.color = Color.red;
				GUI.Label(respawnUiRect, $"{arg}\n{num:F1}");
				GUI.color = Color.white;
				GUI.skin.label.fontSize = 12;
				GUI.skin.label.alignment = (TextAnchor)0;
			}
		}

		private void DrawSettingsWindow(int id)
		{
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Space(10f);
			GUILayout.Label($"Zombie Respawn Time: {Setting_RespawnTime:F0}s", Array.Empty<GUILayoutOption>());
			float num = GUILayout.HorizontalSlider(Setting_RespawnTime, 10f, 120f, Array.Empty<GUILayoutOption>());
			if (num != Setting_RespawnTime)
			{
				Setting_RespawnTime = num;
				SyncSettings();
			}
			GUILayout.Label($"Initial Zombies: {Setting_InitialZombies}", Array.Empty<GUILayoutOption>());
			float num2 = GUILayout.HorizontalSlider((float)Setting_InitialZombies, 1f, 4f, Array.Empty<GUILayoutOption>());
			if ((int)num2 != Setting_InitialZombies)
			{
				Setting_InitialZombies = (int)num2;
				SyncSettings();
			}
			GUILayout.Label($"Infection Strength: {Setting_InfectionDmg:F2}", Array.Empty<GUILayoutOption>());
			float num3 = GUILayout.HorizontalSlider(Setting_InfectionDmg, 0.1f, 1f, Array.Empty<GUILayoutOption>());
			if (num3 != Setting_InfectionDmg)
			{
				Setting_InfectionDmg = num3;
				SyncSettings();
			}
			bool flag = GUILayout.Toggle(Setting_InfiniteStamina, " Infinite Zombie Stamina", Array.Empty<GUILayoutOption>());
			if (flag != Setting_InfiniteStamina)
			{
				Setting_InfiniteStamina = flag;
				SyncSettings();
			}
			GUILayout.Space(20f);
			if (GUILayout.Button("Close Menu (F10)", Array.Empty<GUILayoutOption>()))
			{
				showSettings = false;
			}
			GUILayout.EndVertical();
			GUI.DragWindow();
		}
	}
	[HarmonyPatch(typeof(RunManager), "StartRun")]
	public static class RunManagerPatch
	{
		[HarmonyPostfix]
		public static void Postfix()
		{
			if (PhotonNetwork.IsMasterClient && Object.op_Implicit((Object)(object)ZombieModeManager.Instance))
			{
				ZombieModeManager.Instance.OnRunStarted();
			}
		}
	}
	[HarmonyPatch(typeof(MapHandler), "GoToSegment")]
	public static class MapHandlerPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Segment s)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)s == 0 && PhotonNetwork.IsMasterClient && Object.op_Implicit((Object)(object)ZombieModeManager.Instance))
			{
				ZombieModeManager.Instance.OnReachFirstMountain();
			}
		}
	}
	[HarmonyPatch(typeof(Campfire), "IsInteractible")]
	public static class CampfireInteractPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Character interactor, ref bool __result)
		{
			if (Object.op_Implicit((Object)(object)ZombieModeManager.Instance) && ZombieModeManager.Instance.IsPlayerZombie(((MonoBehaviourPun)interactor).photonView.Owner.ActorNumber))
			{
				__result = false;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Campfire), "EveryoneInRange")]
	public static class CampfireRangePatch
	{
		[HarmonyPrefix]
		public static bool Prefix(out string printout, ref bool __result)
		{
			if (Object.op_Implicit((Object)(object)ZombieModeManager.Instance) && ZombieModeManager.Instance.CurrentState != 0)
			{
				printout = "";
				__result = true;
				return false;
			}
			printout = "";
			return true;
		}
	}
	[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
	public static class CampfirePatch
	{
		[HarmonyPostfix]
		public static void Postfix(Campfire __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.IsMasterClient && Object.op_Implicit((Object)(object)ZombieModeManager.Instance))
			{
				ZombieModeManager.Instance.OnCampfireLit(((Component)__instance).transform.position);
			}
		}
	}
	[HarmonyPatch(typeof(MushroomZombie), "Update")]
	public static class ZombieControlPatch
	{
		private static MethodInfo startLungingMethod = AccessTools.Method(typeof(MushroomZombie), "StartLunging", (Type[])null, (Type[])null);

		[HarmonyPrefix]
		public static bool Prefix(MushroomZombie __instance)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Invalid comparison between Unknown and I4
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (((MonoBehaviourPun)__instance).photonView.IsMine && Object.op_Implicit((Object)(object)ZombieModeManager.Instance))
			{
				if (__instance.isNPCZombie && ZombieModeManager.Instance.IsPlayerZombie(((MonoBehaviourPun)__instance).photonView.Owner.ActorNumber))
				{
					__instance.isNPCZombie = false;
				}
				if (ZombieModeManager.Instance.IsZombiesFrozen)
				{
					if (Object.op_Implicit((Object)(object)__instance.character) && Object.op_Implicit((Object)(object)__instance.character.input))
					{
						__instance.character.input.ResetInput();
					}
					return false;
				}
			}
			if (((MonoBehaviourPun)__instance).photonView.IsMine && !__instance.isNPCZombie)
			{
				if ((bool)AccessTools.Field(typeof(MushroomZombie), "mushroomsGrowing").GetValue(__instance))
				{
					AccessTools.Method(typeof(MushroomZombie), "UpdateMushroomGrowth", (Type[])null, (Type[])null).Invoke(__instance, null);
				}
				if ((int)__instance.currentState == 4 || (int)__instance.currentState == 5)
				{
					return true;
				}
				if (__instance.character.input.useSecondaryWasPressed && startLungingMethod != null)
				{
					Vector3 forward = ((Component)MainCamera.instance).transform.forward;
					Vector3 val = __instance.character.Center + forward * 100f;
					AccessTools.Field(typeof(MushroomZombie), "lungeTargetForward").SetValue(__instance, val);
					AccessTools.Field(typeof(MushroomZombie), "timeSpentLunging").SetValue(__instance, 0f);
					((MonoBehaviourPun)__instance).photonView.RPC("RPC_PlaySFX", (RpcTarget)0, new object[1] { 0 });
					GamefeelHandler.instance.AddPerlinShake(5f, 0.3f, 10f);
					__instance.character.input.jumpWasPressed = true;
					__instance.currentState = (State)4;
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GlobalEvents), "TriggerCharacterDied")]
	public static class DeathScreenBlockPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Character character)
		{
			if (Object.op_Implicit((Object)(object)ZombieModeManager.Instance) && ZombieModeManager.Instance.CurrentState == ZombieModeManager.GameState.Active && ((MonoBehaviourPun)character).photonView.Owner != null && ZombieModeManager.Instance.IsPlayerZombie(((MonoBehaviourPun)character).photonView.Owner.ActorNumber))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterItems), "Update")]
	public static class ZombieItemBlockPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(CharacterItems __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance.character) && __instance.character.isZombie)
			{
				if ((Object)(object)__instance.character.input != (Object)null)
				{
					__instance.character.input.usePrimaryIsPressed = false;
					__instance.character.input.usePrimaryWasPressed = false;
					__instance.character.input.usePrimaryWasReleased = false;
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Character), "RPCA_Die")]
	public static class CharacterDeathPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Character __instance)
		{
			if (PhotonNetwork.IsMasterClient && Object.op_Implicit((Object)(object)ZombieModeManager.Instance) && ZombieModeManager.Instance.CurrentState == ZombieModeManager.GameState.Active && ((MonoBehaviourPun)__instance).photonView.Owner != null)
			{
				bool wasAlreadyZombie = ZombieModeManager.Instance.IsPlayerZombie(((MonoBehaviourPun)__instance).photonView.Owner.ActorNumber);
				ZombieModeManager.Instance.OnPlayerDied(((MonoBehaviourPun)__instance).photonView.Owner.ActorNumber, wasAlreadyZombie);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Revive")]
	public static class ZombieReviveBlockPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Character __instance)
		{
			if (Object.op_Implicit((Object)(object)ZombieModeManager.Instance) && ZombieModeManager.Instance.CurrentState != 0 && ((MonoBehaviourPun)__instance).photonView.Owner != null && ZombieModeManager.Instance.IsPlayerZombie(((MonoBehaviourPun)__instance).photonView.Owner.ActorNumber))
			{
				if (ZombieModeManager.Instance.IsSystemReviving)
				{
					return true;
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Skelleton), "Interact_CastFinished")]
	public static class SkelletonRevivePatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Skelleton __instance, Character interactor)
		{
			if (Object.op_Implicit((Object)(object)ZombieModeManager.Instance) && ZombieModeManager.Instance.CurrentState != 0)
			{
				object? value = AccessTools.Field(typeof(Skelleton), "spawnedFromCharacter").GetValue(__instance);
				Character val = (Character)((value is Character) ? value : null);
				if ((Object)(object)val != (Object)null && ((MonoBehaviourPun)val).photonView.Owner != null && ZombieModeManager.Instance.IsPlayerZombie(((MonoBehaviourPun)val).photonView.Owner.ActorNumber))
				{
					ZombieModeManager.Instance.ForceRespawnZombie(((MonoBehaviourPun)val).photonView.Owner.ActorNumber);
					Action_ReduceUses val2 = default(Action_ReduceUses);
					if (Object.op_Implicit((Object)(object)interactor.data.currentItem) && ((Component)interactor.data.currentItem).TryGetComponent<Action_ReduceUses>(ref val2))
					{
						((ItemActionBase)val2).RunAction();
					}
					__instance.ReleaseInteract(interactor);
					Object.Destroy((Object)(object)((Component)__instance).gameObject);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(MushroomZombie), "OnBitCharacter")]
	public static class ZombieBitePatch
	{
		[HarmonyPostfix]
		public static void Postfix(MushroomZombie __instance, Character c)
		{
			if (PhotonNetwork.IsMasterClient && (Object)(object)c != (Object)null && (Object)(object)ZombieModeManager.Instance != (Object)null)
			{
				float setting_InfectionDmg = ZombieModeManager.Instance.Setting_InfectionDmg;
				c.refs.afflictions.AddStatus((STATUSTYPE)10, setting_InfectionDmg, false, true);
				c.refs.afflictions.AddStatus((STATUSTYPE)0, 0.2f, false, true);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "UseStamina")]
	public static class ZombieStaminaPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Character __instance)
		{
			if ((Object)(object)ZombieModeManager.Instance != (Object)null && ZombieModeManager.Instance.Setting_InfiniteStamina && ((MonoBehaviourPun)__instance).photonView.Owner != null && ZombieModeManager.Instance.IsPlayerZombie(((MonoBehaviourPun)__instance).photonView.Owner.ActorNumber))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(RunManager), "EndGame")]
	public static class WinPatch
	{
		[HarmonyPostfix]
		public static void Postfix()
		{
			if (PhotonNetwork.IsMasterClient && Object.op_Implicit((Object)(object)ZombieModeManager.Instance))
			{
				ZombieModeManager.Instance.OnHumanVictory();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}