Decompiled source of Fire S Mythos v0.2.1

FireSMythos/FireSMythos.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Xml;
using BepInEx;
using DM;
using FireSMythos;
using FireSMythos.AssetManagement;
using FireSMythos.TABSSimp;
using HarmonyLib;
using Landfall.MonoBatch;
using Landfall.TABS;
using Landfall.TABS.AI;
using Landfall.TABS.AI.Systems;
using Landfall.TABS.GameMode;
using Landfall.TABS.GameState;
using Landfall.TABS.UnitEditor;
using Landfall.TABS.UnitPlacement;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using Sirenix.Serialization;
using TFBGames;
using TMPro;
using Unity.Entities;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.LowLevel;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FireSMythos")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FireSMythos")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1619c49c-bc45-486c-bbca-6b52cef4f478")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(GameObject), "SetActive", new Type[] { typeof(bool) })]
[HarmonyPriority(0)]
internal static class FireSSetActivePatch
{
	private static void Prefix(GameObject __instance, bool __0, ref bool __runOriginal)
	{
		if (!__0)
		{
			FireSFinalMethodPolicy.Apply((Object)(object)__instance, ref __runOriginal);
		}
	}
}
namespace FireSMythos
{
	public class FireSAttack : GameStateListener
	{
		private static bool gameLoopPaused;

		private static bool gameLoopPauseScheduled;

		private static int pauseGeneration;

		private Unit unit;

		private TeamSystem teamSystem;

		private static bool pausedByFireS;

		private static float previousTimeScale = 1f;

		private bool battleStarted;

		private bool attackExecuted;

		private static readonly HashSet<FireSAttack> activeFireSUnits = new HashSet<FireSAttack>();

		private bool registeredInBattle;

		private bool showVictoryScreen;

		private GUIStyle victoryStyle;

		private static readonly HashSet<FireSAttack> forceRemovalOwners = new HashSet<FireSAttack>();

		private static bool victorySoundPlayed;

		public static bool IsGameLoopPaused => gameLoopPaused;

		public static bool BlockVanillaVictory
		{
			get
			{
				activeFireSUnits.RemoveWhere((FireSAttack x) => (Object)(object)x == (Object)null);
				return activeFireSUnits.Count > 0;
			}
		}

		public static bool ForceRemovalWindow
		{
			get
			{
				forceRemovalOwners.RemoveWhere((FireSAttack x) => (Object)(object)x == (Object)null);
				return forceRemovalOwners.Count > 0;
			}
		}

		public static bool IsSimulationPaused => pausedByFireS;

		private void Start()
		{
			InitializeReferences();
			FireSSceneRespawnManager.NotifyFireSSpawned(unit);
		}

		private void InitializeReferences()
		{
			if ((Object)(object)unit == (Object)null)
			{
				unit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			}
			if (teamSystem == null && World.Active != null)
			{
				teamSystem = World.Active.GetOrCreateManager<TeamSystem>();
			}
		}

		public override void OnEnterBattleState()
		{
			battleStarted = true;
			showVictoryScreen = true;
			if (!victorySoundPlayed)
			{
				victorySoundPlayed = true;
				PlayVictorySound();
			}
			if (!registeredInBattle)
			{
				activeFireSUnits.Add(this);
				registeredInBattle = true;
			}
		}

		public override void OnEnterPlacementState()
		{
			ResumeGameTime();
			battleStarted = false;
			attackExecuted = false;
			showVictoryScreen = false;
			forceRemovalOwners.Remove(this);
			UnregisterFromBattle();
		}

		private void OnDestroy()
		{
			forceRemovalOwners.Remove(this);
			UnregisterFromBattle();
		}

		private void OnGUI()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (showVictoryScreen)
			{
				if (victoryStyle == null)
				{
					victoryStyle = new GUIStyle(GUI.skin.label);
					victoryStyle.alignment = (TextAnchor)4;
					victoryStyle.fontStyle = (FontStyle)1;
					victoryStyle.fontSize = Mathf.Max(32, Screen.height / 12);
					victoryStyle.normal.textColor = Color.white;
				}
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((float)Screen.width * 0.15f, (float)Screen.height * 0.38f, (float)Screen.width * 0.7f, (float)Screen.height * 0.24f);
				int depth = GUI.depth;
				Color color = GUI.color;
				GUI.depth = -1000;
				GUI.color = new Color(0f, 0f, 0f, 0.65f);
				GUI.Box(val, GUIContent.none);
				GUI.color = Color.white;
				GUI.Label(val, "Fire S wins", victoryStyle);
				GUI.color = color;
				GUI.depth = depth;
			}
		}

		private void UnregisterFromBattle()
		{
			if (registeredInBattle)
			{
				activeFireSUnits.Remove(this);
				registeredInBattle = false;
			}
			activeFireSUnits.RemoveWhere((FireSAttack x) => (Object)(object)x == (Object)null);
		}

		private void Update()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			CheckForTabResume();
			if (pausedByFireS)
			{
				Time.timeScale = 0f;
			}
			if (!battleStarted || attackExecuted)
			{
				return;
			}
			InitializeReferences();
			if ((Object)(object)unit == (Object)null || teamSystem == null)
			{
				return;
			}
			if ((Object)(object)unit.data != (Object)null)
			{
				unit.data.health = float.PositiveInfinity;
			}
			Team val = (Team)((int)unit.Team != 1);
			List<Unit> teamUnits = teamSystem.GetTeamUnits(val);
			if (teamUnits == null)
			{
				return;
			}
			List<Unit> list = new List<Unit>();
			for (int i = 0; i < teamUnits.Count; i++)
			{
				Unit val2 = teamUnits[i];
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)unit)
				{
					list.Add(val2);
				}
			}
			attackExecuted = true;
			forceRemovalOwners.Add(this);
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			Debug.LogWarning((object)("[FireSMythos] ENEMY ELIMINATION STARTED. Targets: " + list.Count));
			try
			{
				for (int j = 0; j < list.Count; j++)
				{
					Unit val3 = list[j];
					if ((Object)(object)val3 == (Object)null)
					{
						continue;
					}
					GameObject val4 = null;
					try
					{
						val4 = ((Component)val3).gameObject;
					}
					catch (Exception ex)
					{
						num3++;
						Debug.LogWarning((object)("[FireSMythos] Cannot access enemy GameObject: " + ex));
						continue;
					}
					if ((Object)(object)val4 == (Object)null)
					{
						continue;
					}
					string name = ((Object)val4).name;
					try
					{
						if ((Object)(object)val3.data != (Object)null && (Object)(object)val3.data.healthHandler != (Object)null)
						{
							if ((Object)(object)val3.unitBlueprint != (Object)null)
							{
								FireSBlockedUnits.Register(val3.unitBlueprint);
							}
							val3.data.healthHandler.Die(unit);
						}
					}
					catch (Exception ex2)
					{
						Debug.LogWarning((object)("[FireSMythos] ENEMY DIE FAILED: " + ex2));
					}
					try
					{
						ForceDeath(val3);
					}
					catch (Exception ex3)
					{
						Debug.LogWarning((object)("[FireSMythos] FORCE DEATH FAILED: " + ex3));
					}
					try
					{
						if ((Object)(object)val4 != (Object)null)
						{
							val4.SetActive(false);
						}
					}
					catch (Exception ex4)
					{
						num3++;
						Debug.LogWarning((object)("[FireSMythos] SETACTIVE FAILED: " + name + " | " + ex4));
					}
					try
					{
						if ((Object)(object)val4 != (Object)null)
						{
							Object.Destroy((Object)(object)val4, 0f);
						}
					}
					catch (Exception ex5)
					{
						num3++;
						Debug.LogWarning((object)("[FireSMythos] DESTROY FAILED: " + name + " | " + ex5));
					}
					num++;
				}
				if (FireSModeController.DestructionModeEnabled)
				{
					Debug.LogWarning((object)"[FireSMythos] DESTRUCTION MODE ACTIVE!");
					FireSWorldDestruction.DestroyActiveScene();
				}
				((MonoBehaviour)this).StartCoroutine(FireSPersistentModObjectGuard.QuarantineBurst(0.8f, 0.1f));
			}
			catch (Exception ex6)
			{
				Debug.LogError((object)("[FireSMythos] UNEXPECTED ELIMINATION ERROR: " + ex6));
			}
			finally
			{
				forceRemovalOwners.Remove(this);
				try
				{
					PauseGameTime();
					Debug.LogWarning((object)"[FireSMythos] GAME LOOP PAUSE REQUESTED.");
				}
				catch (Exception ex7)
				{
					Debug.LogError((object)("[FireSMythos] GAME LOOP PAUSE FAILED: " + ex7));
				}
				Debug.LogWarning((object)("[FireSMythos] ENEMY ELIMINATION FINISHED. Processed=" + num + ", DieFailures=" + num2 + ", CleanupFailures=" + num3));
			}
		}

		private void ForceDeath(Unit enemy)
		{
			if ((Object)(object)enemy == (Object)null || (Object)(object)enemy.data == (Object)null)
			{
				return;
			}
			try
			{
				enemy.data.Dead = true;
				enemy.dead = true;
				enemy.data.muscleControl = 0f;
				enemy.data.ragdollControl = 0f;
				Debug.Log((object)("[FireSMythos] FORCE DEATH APPLIED: " + ((Object)enemy).name));
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[FireSMythos] FORCE DEATH FAILED: " + ex));
			}
		}

		private void PauseGameTime()
		{
			if (!pausedByFireS)
			{
				previousTimeScale = Time.timeScale;
				pausedByFireS = true;
			}
			Time.timeScale = 0f;
			if (!gameLoopPaused && !gameLoopPauseScheduled)
			{
				gameLoopPauseScheduled = true;
				((MonoBehaviour)this).StartCoroutine(FreezeGameLoopAfterDelay(++pauseGeneration));
				Debug.Log((object)"[FireSMythos] Time stopped. Full PlayerLoop freeze scheduled.");
			}
		}

		private IEnumerator FreezeGameLoopAfterDelay(int generation)
		{
			yield return (object)new WaitForSecondsRealtime(1f);
			if (generation == pauseGeneration && pausedByFireS)
			{
				gameLoopPauseScheduled = false;
				gameLoopPaused = FireSPlayerLoopFreeze.Freeze();
				if (gameLoopPaused)
				{
					Debug.Log((object)"[FireSMythos] FULL GAME LOOP FROZEN!");
				}
			}
		}

		private static void ResumeGameTime()
		{
			pauseGeneration++;
			gameLoopPauseScheduled = false;
			FireSPlayerLoopFreeze.Restore();
			gameLoopPaused = false;
			if (pausedByFireS)
			{
				Time.timeScale = previousTimeScale;
				pausedByFireS = false;
				Debug.Log((object)"[FireSMythos] FULL GAME LOOP RESTORED!");
			}
		}

		public static void ResumeFromPlayerLoop()
		{
			ResumeGameTime();
		}

		public static void CheckForTabResume()
		{
			if (pausedByFireS && Input.GetKeyDown((KeyCode)9))
			{
				ResumeGameTime();
			}
		}

		private static string FindVictorySoundRef(SoundPlayer player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.soundBank == (Object)null || player.soundBank.Categories == null)
			{
				Debug.LogError((object)"[FireSMythos] SoundBank not available!");
				return null;
			}
			string text = null;
			int num = 0;
			SoundBankCategory[] categories = player.soundBank.Categories;
			foreach (SoundBankCategory val in categories)
			{
				if (val == null || val.soundEffects == null)
				{
					continue;
				}
				string text2 = val.categoryName ?? "";
				SoundEffectInstance[] soundEffects = val.soundEffects;
				foreach (SoundEffectInstance val2 in soundEffects)
				{
					if (val2 == null || string.IsNullOrEmpty(val2.soundRef))
					{
						continue;
					}
					string soundRef = val2.soundRef;
					string text3 = text2 + "/" + soundRef;
					string[] array = (text2 + " " + soundRef).ToLowerInvariant().Split(new char[5] { ' ', '/', '_', '-', '.' }, StringSplitOptions.RemoveEmptyEntries);
					int num2 = 0;
					string[] array2 = array;
					for (int k = 0; k < array2.Length; k++)
					{
						switch (array2[k])
						{
						case "victory":
							num2 = Math.Max(num2, 100);
							break;
						case "winner":
							num2 = Math.Max(num2, 90);
							break;
						case "win":
							num2 = Math.Max(num2, 80);
							break;
						case "won":
							num2 = Math.Max(num2, 70);
							break;
						case "success":
							num2 = Math.Max(num2, 50);
							break;
						}
					}
					if (text2.Equals("UI", StringComparison.OrdinalIgnoreCase))
					{
						num2 += 10;
					}
					if (num2 > 0)
					{
						Debug.Log((object)("[FireSMythos] Possible victory sound: " + text3 + " (score: " + num2 + ")"));
						if (num2 > num)
						{
							num = num2;
							text = text3;
						}
					}
				}
			}
			if (text == null)
			{
				Debug.LogWarning((object)"[FireSMythos] No victory sound found. Check available UI sound references.");
				SoundBankCategory[] categories2 = player.soundBank.Categories;
				foreach (SoundBankCategory val3 in categories2)
				{
					if (val3 == null || val3.soundEffects == null || !val3.categoryName.ToLowerInvariant().Contains("ui"))
					{
						continue;
					}
					SoundEffectInstance[] soundEffects2 = val3.soundEffects;
					foreach (SoundEffectInstance val4 in soundEffects2)
					{
						if (val4 != null)
						{
							Debug.Log((object)("[FireSMythos] UI sound: " + val3.categoryName + "/" + val4.soundRef));
						}
					}
				}
				return null;
			}
			Debug.Log((object)("[FireSMythos] Selected victory sound: " + text));
			return text;
		}

		private static void PlayVictorySound()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SoundPlayer service = ServiceLocator.GetService<SoundPlayer>();
				string text = FindVictorySoundRef(service);
				if (!string.IsNullOrEmpty(text))
				{
					Camera main = Camera.main;
					Vector3 val = Vector3.zero;
					if ((Object)(object)main != (Object)null)
					{
						val = ((Component)main).transform.position + ((Component)main).transform.forward * 25f;
					}
					service.PlaySoundEffect(text, 1f, val, (MaterialType)0, (Transform)null, 1f);
					Debug.Log((object)"[FireSMythos] Victory sound played!");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[FireSMythos] Victory sound error: " + ex));
			}
		}
	}
	public class FireSBaseVisibility : MonoBehaviour
	{
		private Transform customVisualRoot;

		private Renderer[] baseRenderers;

		public void Initialize(Transform visualRoot)
		{
			customVisualRoot = visualRoot;
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			List<Renderer> list = new List<Renderer>();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Transform transform = ((Component)val).transform;
					if (!((Object)(object)transform == (Object)(object)customVisualRoot) && !transform.IsChildOf(customVisualRoot))
					{
						val.enabled = false;
						list.Add(val);
					}
				}
			}
			baseRenderers = list.ToArray();
			Debug.Log((object)("[FireSMythos] Hidden base renderers: " + baseRenderers.Length));
		}

		private void OnEnable()
		{
			EnforceInvisible();
		}

		private void LateUpdate()
		{
			EnforceInvisible();
		}

		private void EnforceInvisible()
		{
			if (baseRenderers == null)
			{
				return;
			}
			Renderer[] array = baseRenderers;
			foreach (Renderer val in array)
			{
				if ((Object)(object)val != (Object)null && val.enabled)
				{
					val.enabled = false;
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class FireSBehaviourEnabledPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.PropertySetter(typeof(Behaviour), "enabled");
		}

		private static bool Prefix(Behaviour __instance, bool __0)
		{
			if (__0)
			{
				return true;
			}
			return !FireSMutationGuard.ShouldBlock((Component)(object)__instance, "Behaviour.enabled = false");
		}
	}
	public static class FireSBlockedUnits
	{
		private static readonly HashSet<string> blockedBlueprints = new HashSet<string>();

		public static int BlockedCount => blockedBlueprints.Count;

		public static bool Register(UnitBlueprint blueprint)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)blueprint == (Object)null)
			{
				return false;
			}
			string text = ((object)blueprint.Entity.GUID/*cast due to .constrained prefix*/).ToString();
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			bool flag = blockedBlueprints.Add(text);
			if (flag)
			{
				Debug.LogWarning((object)("[FireSMythos] UNIT TYPE PERMANENTLY BLOCKED: " + blueprint.Name + " | GUID: " + text));
			}
			return flag;
		}

		public static bool IsBlocked(UnitBlueprint blueprint)
		{
			//IL_001b: 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)
			if ((Object)(object)blueprint == (Object)null)
			{
				return false;
			}
			return blockedBlueprints.Contains(((object)blueprint.Entity.GUID/*cast due to .constrained prefix*/).ToString());
		}

		public static void Reset()
		{
			blockedBlueprints.Clear();
		}
	}
	internal static class FireSCallerPolicy
	{
		private static readonly HashSet<string> logged = new HashSet<string>();

		private static bool IsFrameworkAssembly(string name)
		{
			return name == "mscorlib" || name == "System" || name.StartsWith("System.") || name == "netstandard" || name.StartsWith("UnityEngine") || name.StartsWith("Unity.") || name.StartsWith("Mono.") || name.StartsWith("MonoMod") || name.StartsWith("0Harmony") || name.StartsWith("Harmony") || name.StartsWith("BepInEx") || name.StartsWith("Microsoft.");
		}

		private static bool IsVanillaAssembly(Assembly assembly)
		{
			try
			{
				string location = assembly.Location;
				if (string.IsNullOrEmpty(location))
				{
					return false;
				}
				string fullPath = Path.GetFullPath(Path.Combine(Application.dataPath, "Managed"));
				string text = fullPath;
				char directorySeparatorChar = Path.DirectorySeparatorChar;
				fullPath = text + directorySeparatorChar;
				string fullPath2 = Path.GetFullPath(location);
				return fullPath2.StartsWith(fullPath, StringComparison.OrdinalIgnoreCase);
			}
			catch
			{
				return false;
			}
		}

		public static bool TryGetModCaller(out string caller)
		{
			caller = null;
			StackFrame[] frames = new StackTrace(0, fNeedFileInfo: false).GetFrames();
			if (frames == null)
			{
				return false;
			}
			Assembly assembly = typeof(FireSCallerPolicy).Assembly;
			StackFrame[] array = frames;
			foreach (StackFrame stackFrame in array)
			{
				MethodBase method = stackFrame.GetMethod();
				if (method == null)
				{
					continue;
				}
				Assembly assembly2 = ((method.DeclaringType != null) ? method.DeclaringType.Assembly : method.Module.Assembly);
				if (!(assembly2 == null) && !(assembly2 == assembly) && !assembly2.IsDynamic)
				{
					string name = assembly2.GetName().Name ?? "";
					if (!IsFrameworkAssembly(name) && !IsVanillaAssembly(assembly2))
					{
						caller = assembly2.FullName;
						return true;
					}
				}
			}
			return false;
		}

		public static void LogBlocked(string operation, string caller)
		{
			string item = operation + "|" + caller;
			if (logged.Add(item))
			{
				Debug.LogWarning((object)("[FireSIntegrityGuard] BLOCKED: " + operation + " | Caller: " + caller));
			}
		}
	}
	[HarmonyPatch]
	internal static class FireSDataHandlerDeadPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.PropertySetter(typeof(DataHandler), "Dead");
		}

		private static bool Prefix(DataHandler __instance, bool __0)
		{
			if (!__0)
			{
				return true;
			}
			if (FireSProtection.IsProtectedObject((Object)(object)__instance))
			{
				return false;
			}
			return !FireSMutationGuard.ShouldBlock((Component)(object)__instance, "DataHandler.Dead = true");
		}
	}
	[HarmonyPatch]
	[HarmonyPriority(0)]
	internal static class FireSDiePolicyPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			foreach (MethodInfo method in AccessTools.GetDeclaredMethods(typeof(HealthHandler)))
			{
				if (method.Name == "Die")
				{
					yield return method;
				}
			}
		}

		private static void Prefix(HealthHandler __instance, ref bool __runOriginal)
		{
			FireSFinalMethodPolicy.Apply((Object)(object)__instance, ref __runOriginal);
		}
	}
	internal static class FireSExternalFreeze
	{
		private static readonly Assembly ownAssembly = typeof(FireSExternalFreeze).Assembly;

		private static readonly Dictionary<int, Behaviour> frozenBehaviours = new Dictionary<int, Behaviour>();

		private static bool IsThirdPartyAssembly(Assembly assembly)
		{
			if (assembly == null || assembly == ownAssembly || assembly.IsDynamic)
			{
				return false;
			}
			string text = assembly.GetName().Name ?? "";
			try
			{
				string location = assembly.Location;
				if (!string.IsNullOrEmpty(location))
				{
					string fullPath = Path.GetFullPath(Path.Combine(Application.dataPath, "Managed"));
					char directorySeparatorChar = Path.DirectorySeparatorChar;
					string value = fullPath + directorySeparatorChar;
					string fullPath2 = Path.GetFullPath(location);
					if (fullPath2.StartsWith(value, StringComparison.OrdinalIgnoreCase))
					{
						return false;
					}
				}
			}
			catch
			{
			}
			string[] array = new string[10] { "mscorlib", "netstandard", "System", "UnityEngine", "Unity.", "Mono", "MonoMod", "BepInEx", "Harmony", "TFBGames" };
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				if (text.Equals(text2, StringComparison.OrdinalIgnoreCase) || text.StartsWith(text2 + ".", StringComparison.OrdinalIgnoreCase))
				{
					return false;
				}
			}
			return true;
		}

		public static bool IsThirdPartyServiceAssembly(Assembly assembly)
		{
			return IsThirdPartyAssembly(assembly);
		}

		private static bool IsUIOrCamera(Behaviour behaviour)
		{
			if ((Object)(object)behaviour == (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)behaviour).GetComponentInParent<Camera>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)behaviour).GetComponentInParent<Canvas>() != (Object)null)
			{
				return true;
			}
			return false;
		}

		private static bool IsPhysicsActor(Behaviour behaviour)
		{
			GameObject gameObject = ((Component)behaviour).gameObject;
			return (Object)(object)gameObject.GetComponent<Rigidbody>() != (Object)null || (Object)(object)gameObject.GetComponentInParent<Rigidbody>() != (Object)null || (Object)(object)gameObject.GetComponentInChildren<Rigidbody>(true) != (Object)null || (Object)(object)gameObject.GetComponent<Collider>() != (Object)null || (Object)(object)gameObject.GetComponentInParent<Collider>() != (Object)null || (Object)(object)gameObject.GetComponentInChildren<Collider>(true) != (Object)null;
		}

		private static void FreezeBehaviour(Behaviour behaviour)
		{
			if (!((Object)(object)behaviour == (Object)null) && behaviour.enabled && !FireSProtection.IsProtectedObject((Object)(object)behaviour) && IsThirdPartyAssembly(((object)behaviour).GetType().Assembly))
			{
				int instanceID = ((Object)behaviour).GetInstanceID();
				if (!frozenBehaviours.ContainsKey(instanceID))
				{
					frozenBehaviours.Add(instanceID, behaviour);
					behaviour.enabled = false;
				}
			}
		}

		public static void FreezeModdedBehaviours()
		{
			if (World.Active == null)
			{
				return;
			}
			Debug.Log((object)"[FireSIntegrityGuard] Freezing third-party behaviours...");
			TeamSystem existingManager = World.Active.GetExistingManager<TeamSystem>();
			if (existingManager != null)
			{
				Unit[] array = existingManager.GetAllUnits().ToArray();
				Unit[] array2 = array;
				foreach (Unit val in array2)
				{
					if (!((Object)(object)val == (Object)null) && !FireSProtection.IsFireS(val))
					{
						MonoBehaviour[] componentsInChildren = ((Component)val).GetComponentsInChildren<MonoBehaviour>(true);
						MonoBehaviour[] array3 = componentsInChildren;
						foreach (MonoBehaviour behaviour in array3)
						{
							FreezeBehaviour((Behaviour)(object)behaviour);
						}
					}
				}
			}
			MonoBehaviour[] array4 = Object.FindObjectsOfType<MonoBehaviour>();
			MonoBehaviour[] array5 = array4;
			foreach (MonoBehaviour val2 in array5)
			{
				if (!((Object)(object)val2 == (Object)null) && !IsUIOrCamera((Behaviour)(object)val2) && !((Object)(object)((Component)val2).GetComponentInParent<Unit>() != (Object)null) && IsPhysicsActor((Behaviour)(object)val2))
				{
					FreezeBehaviour((Behaviour)(object)val2);
				}
			}
			Debug.Log((object)("[FireSIntegrityGuard] Frozen components: " + frozenBehaviours.Count));
		}

		public static void RestoreModdedBehaviours()
		{
			foreach (KeyValuePair<int, Behaviour> frozenBehaviour in frozenBehaviours)
			{
				Behaviour value = frozenBehaviour.Value;
				if ((Object)(object)value != (Object)null)
				{
					value.enabled = true;
				}
			}
			Debug.Log((object)("[FireSIntegrityGuard] Restored components: " + frozenBehaviours.Count));
			frozenBehaviours.Clear();
		}
	}
	internal static class FireSFinalMethodPolicy
	{
		public static void Apply(Object target, ref bool runOriginal)
		{
			if (!(target == (Object)null))
			{
				if (FireSProtection.IsProtectedObject(target))
				{
					runOriginal = false;
				}
				else if (FireSAttack.ForceRemovalWindow)
				{
					runOriginal = true;
				}
			}
		}
	}
	internal static class FireSFinalModeMusic
	{
		public static void Play()
		{
			Debug.Log((object)"[FireSMythos] Starting custom Final Mode soundtrack.");
			AssetImporter.PlayAudio("FinalModeMusic");
		}
	}
	internal static class FireSFinalModeScreen
	{
		private static GameObject screenRoot;

		private static Image CreateImage(Transform parent, string name, Color color, Vector2 anchorMin, Vector2 anchorMax)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchorMin;
			component.anchorMax = anchorMax;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).color = color;
			((Graphic)component2).raycastTarget = false;
			return component2;
		}

		private static Component CreateText(Component template, Transform parent, string name, string value, Vector2 anchorMin, Vector2 anchorMax, float fontSize, Color color, TextAnchor legacyAlignment)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(template.gameObject, parent, false);
			((Object)val).name = name;
			FireSModeMenuUI.DisableLocalization(val);
			Component val2 = FireSModeMenuUI.FindLabel(val);
			FireSModeMenuUI.SetLabel(val2, value);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchorMin;
			component.anchorMax = anchorMax;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			TMP_Text val3 = (TMP_Text)(object)((val2 is TMP_Text) ? val2 : null);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.alignment = (TextAlignmentOptions)514;
				val3.fontSize = fontSize;
				((Graphic)val3).color = color;
				val3.fontStyle = (FontStyles)1;
				val3.enableWordWrapping = true;
				((Graphic)val3).raycastTarget = false;
			}
			Text val4 = (Text)(object)((val2 is Text) ? val2 : null);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.alignment = legacyAlignment;
				val4.fontSize = Mathf.RoundToInt(fontSize);
				((Graphic)val4).color = color;
				val4.fontStyle = (FontStyle)1;
				((Graphic)val4).raycastTarget = false;
			}
			return val2;
		}

		public static void Show(Button buttonTemplate, Component textTemplate)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: 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_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Expected O, but got Unknown
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)screenRoot != (Object)null)
			{
				return;
			}
			if ((Object)(object)buttonTemplate == (Object)null || (Object)(object)textTemplate == (Object)null)
			{
				Debug.LogError((object)"[FireSMythos] Final screen templates missing!");
				return;
			}
			FireSFinalModeMusic.Play();
			Time.timeScale = 0f;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			screenRoot = new GameObject("FireS_FinalModeCanvas");
			Canvas val = screenRoot.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			val.overrideSorting = true;
			val.sortingOrder = 32767;
			CanvasScaler val2 = screenRoot.AddComponent<CanvasScaler>();
			val2.uiScaleMode = (ScaleMode)1;
			val2.referenceResolution = new Vector2(1920f, 1080f);
			val2.matchWidthOrHeight = 0.5f;
			screenRoot.AddComponent<GraphicRaycaster>();
			if ((Object)(object)EventSystem.current == (Object)null)
			{
				GameObject val3 = new GameObject("FireS_FinalEventSystem");
				val3.AddComponent<EventSystem>();
				val3.AddComponent<StandaloneInputModule>();
			}
			CanvasGroup val4 = screenRoot.AddComponent<CanvasGroup>();
			val4.alpha = 0f;
			Image val5 = CreateImage(screenRoot.transform, "Final_Background", Color.black, Vector2.zero, Vector2.one);
			((Graphic)val5).raycastTarget = true;
			CreateImage(screenRoot.transform, "Final_RedAtmosphere", new Color(0.35f, 0.005f, 0.015f, 0.22f), new Vector2(0f, 0.25f), new Vector2(1f, 0.75f));
			CreateImage(screenRoot.transform, "Final_TopBorder", new Color(0.8f, 0.015f, 0.035f, 0.9f), new Vector2(0.05f, 0.91f), new Vector2(0.95f, 0.914f));
			CreateImage(screenRoot.transform, "Final_BottomBorder", new Color(0.8f, 0.015f, 0.035f, 0.9f), new Vector2(0.05f, 0.085f), new Vector2(0.95f, 0.089f));
			CreateImage(screenRoot.transform, "Final_LeftBorder", new Color(0.5f, 0.01f, 0.025f, 0.7f), new Vector2(0.05f, 0.1f), new Vector2(0.052f, 0.9f));
			CreateImage(screenRoot.transform, "Final_RightBorder", new Color(0.5f, 0.01f, 0.025f, 0.7f), new Vector2(0.948f, 0.1f), new Vector2(0.95f, 0.9f));
			Image glowImage = CreateImage(screenRoot.transform, "Final_TitleGlow", new Color(0.7f, 0.01f, 0.025f, 0.12f), new Vector2(0.15f, 0.49f), new Vector2(0.85f, 0.72f));
			Component val6 = CreateText(textTemplate, screenRoot.transform, "Final_Title", "You died", new Vector2(0.1f, 0.55f), new Vector2(0.9f, 0.72f), 104f, new Color(0.95f, 0.035f, 0.06f), (TextAnchor)4);
			CreateImage(screenRoot.transform, "Final_MessageSeparator", new Color(0.8f, 0.015f, 0.035f, 0.8f), new Vector2(0.3f, 0.465f), new Vector2(0.7f, 0.469f));
			CreateText(textTemplate, screenRoot.transform, "Final_Message", "You have been killed by Fire S", new Vector2(0.12f, 0.36f), new Vector2(0.88f, 0.45f), 32f, Color.white, (TextAnchor)4);
			Image scanlineImage = CreateImage(screenRoot.transform, "Final_Scanline", new Color(0.95f, 0.02f, 0.045f, 0.18f), new Vector2(0.06f, 0.2f), new Vector2(0.94f, 0.205f));
			GameObject val7 = Object.Instantiate<GameObject>(((Component)buttonTemplate).gameObject, screenRoot.transform, false);
			((Object)val7).name = "FinalMode_LeaveGame";
			Button component = val7.GetComponent<Button>();
			FireSModeMenuUI.ResetButtonEvents(component);
			FireSModeMenuUI.DisableLocalization(val7);
			FireSModeMenuUI.SetLabel(FireSModeMenuUI.FindLabel(val7), "Leave game");
			((Selectable)component).interactable = true;
			((UnityEvent)component.onClick).AddListener(new UnityAction(Application.Quit));
			Navigation navigation = ((Selectable)component).navigation;
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)component).navigation = navigation;
			RectTransform component2 = val7.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 0.19f);
			component2.anchorMax = new Vector2(0.5f, 0.19f);
			component2.pivot = new Vector2(0.5f, 0.5f);
			component2.sizeDelta = new Vector2(390f, 82f);
			component2.anchoredPosition = Vector2.zero;
			if ((Object)(object)((Selectable)component).image != (Object)null)
			{
				((Graphic)((Selectable)component).image).color = new Color(0.55f, 0.015f, 0.03f);
			}
			((Component)component).transform.SetAsLastSibling();
			FireSFinalScreenAnimator fireSFinalScreenAnimator = screenRoot.AddComponent<FireSFinalScreenAnimator>();
			fireSFinalScreenAnimator.Initialize(val4, (Graphic)(object)((val6 is Graphic) ? val6 : null), glowImage, scanlineImage);
			Camera[] array = Object.FindObjectsOfType<Camera>();
			Camera[] array2 = array;
			foreach (Camera val8 in array2)
			{
				if ((Object)(object)val8 != (Object)null)
				{
					((Behaviour)val8).enabled = false;
				}
			}
			Debug.Log((object)"[FireSMythos] FINAL MODE SCREEN CREATED!");
		}
	}
	public class FireSFinalScreenAnimator : MonoBehaviour
	{
		private CanvasGroup canvasGroup;

		private Graphic title;

		private Image glow;

		private Image scanline;

		private float elapsed;

		public void Initialize(CanvasGroup group, Graphic titleGraphic, Image glowImage, Image scanlineImage)
		{
			canvasGroup = group;
			title = titleGraphic;
			glow = glowImage;
			scanline = scanlineImage;
		}

		private void Update()
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			elapsed += unscaledDeltaTime;
			if ((Object)(object)canvasGroup != (Object)null)
			{
				canvasGroup.alpha = Mathf.MoveTowards(canvasGroup.alpha, 1f, unscaledDeltaTime * 0.85f);
			}
			float num = (Mathf.Sin(Time.unscaledTime * 1.8f) + 1f) * 0.5f;
			if ((Object)(object)title != (Object)null)
			{
				title.color = Color.Lerp(new Color(0.58f, 0.015f, 0.035f), new Color(1f, 0.12f, 0.16f), num);
			}
			if ((Object)(object)glow != (Object)null)
			{
				Color color = ((Graphic)glow).color;
				color.a = Mathf.Lerp(0.07f, 0.23f, num);
				((Graphic)glow).color = color;
			}
			if ((Object)(object)scanline != (Object)null)
			{
				RectTransform rectTransform = ((Graphic)scanline).rectTransform;
				float num2 = Mathf.Lerp(0.2f, 0.85f, Mathf.PingPong(Time.unscaledTime * 0.09f, 1f));
				rectTransform.anchorMin = new Vector2(0.06f, num2);
				rectTransform.anchorMax = new Vector2(0.94f, num2 + 0.005f);
			}
		}
	}
	internal static class FireSProtection
	{
		public static bool IsFireS(Unit unit)
		{
			if ((Object)(object)unit == (Object)null)
			{
				return false;
			}
			FireSIndestructibleTag componentInChildren = ((Component)unit).GetComponentInChildren<FireSIndestructibleTag>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				return true;
			}
			if ((Object)(object)unit.unitBlueprint != (Object)null && unit.unitBlueprint.Entity != null && unit.unitBlueprint.Entity.Name == "Fire S")
			{
				return true;
			}
			return false;
		}

		public static bool IsFireS(HealthHandler handler)
		{
			if ((Object)(object)handler == (Object)null)
			{
				return false;
			}
			Unit val = Traverse.Create((object)handler).Field("unit").GetValue<Unit>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)handler).GetComponentInParent<Unit>();
			}
			return IsFireS(val);
		}

		public static bool IsProtectedObject(Object target)
		{
			if (target == null)
			{
				return false;
			}
			GameObject val = (GameObject)(object)((target is GameObject) ? target : null);
			Component val2 = (Component)(object)((target is Component) ? target : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val = val2.gameObject;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Transform val3 = val.transform;
			while ((Object)(object)val3 != (Object)null)
			{
				if ((Object)(object)((Component)val3).GetComponent<FireSIndestructibleTag>() != (Object)null)
				{
					return true;
				}
				val3 = val3.parent;
			}
			FireSIndestructibleTag componentInChildren = val.GetComponentInChildren<FireSIndestructibleTag>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				return true;
			}
			Unit componentInParent = val.GetComponentInParent<Unit>();
			if (IsFireS(componentInParent))
			{
				return true;
			}
			Unit[] componentsInChildren = val.GetComponentsInChildren<Unit>(true);
			Unit[] array = componentsInChildren;
			foreach (Unit unit in array)
			{
				if (IsFireS(unit))
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class FireSHealthHandlerPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			foreach (MethodInfo method in AccessTools.GetDeclaredMethods(typeof(HealthHandler)))
			{
				if (method.Name == "Die" || method.Name == "TakeDamage")
				{
					yield return method;
				}
			}
		}

		private static bool Prefix(HealthHandler __instance)
		{
			return !FireSProtection.IsFireS(__instance);
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "SetInvulnerable", new Type[] { typeof(bool) })]
	internal static class FireSInvulnerabilityPatch
	{
		private static void Prefix(HealthHandler __instance, ref bool invulnerable)
		{
			if (FireSProtection.IsFireS(__instance))
			{
				invulnerable = true;
			}
		}
	}
	[HarmonyPatch(typeof(BaseGameMode), "OnUnitDied", new Type[] { typeof(Unit) })]
	internal static class FireSOnUnitDiedPatch
	{
		private static bool Prefix(Unit unit)
		{
			return !FireSProtection.IsFireS(unit);
		}
	}
	[HarmonyPatch(typeof(BaseGameMode), "OnUnitRemoved", new Type[]
	{
		typeof(Unit),
		typeof(Team)
	})]
	internal static class FireSOnUnitRemovedPatch
	{
		private static bool Prefix(Unit unit)
		{
			return !FireSProtection.IsFireS(unit);
		}
	}
	[HarmonyPatch(typeof(UnitPlacementBrush), "RemoveUnitInternal")]
	internal static class FireSRemoveUnitPatch
	{
		private static bool Prefix(Unit unit)
		{
			return !FireSProtection.IsFireS(unit);
		}
	}
	[HarmonyPatch(typeof(TeamSystem), "RemoveEntity", new Type[]
	{
		typeof(Entity),
		typeof(Team),
		typeof(Unit)
	})]
	internal static class FireSTeamRemovePatch
	{
		private static bool Prefix(Unit unit)
		{
			return !FireSProtection.IsFireS(unit);
		}
	}
	[HarmonyPatch(typeof(UnitAPI), "SetIsDead")]
	internal static class FireSUnitAPISetDeadPatch
	{
		private static bool Prefix(UnitAPI __instance)
		{
			Unit val = null;
			try
			{
				val = Traverse.Create((object)__instance).Field("m_unit").GetValue<Unit>();
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance).GetComponentInParent<Unit>();
			}
			return !FireSProtection.IsFireS(val);
		}
	}
	[HarmonyPatch]
	[HarmonyPriority(800)]
	internal static class FireSUnitDestroyUnitPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			foreach (MethodInfo method in AccessTools.GetDeclaredMethods(typeof(Unit)))
			{
				if (method.Name == "DestroyUnit")
				{
					yield return method;
				}
			}
		}

		private static bool Prefix(Unit __instance)
		{
			return !FireSProtection.IsFireS(__instance);
		}
	}
	[HarmonyPatch(typeof(TeamSystem), "TriggerUnitDeathAction")]
	[HarmonyPriority(800)]
	internal static class FireSTeamDeathActionPatch
	{
		private static bool Prefix(Unit unit)
		{
			return !FireSProtection.IsFireS(unit);
		}
	}
	public class FireSIndestructibleTag : MonoBehaviour
	{
	}
	public static class FireSModeController
	{
		public static bool DestructionModeEnabled { get; private set; }

		public static bool FinalModeEnabled { get; private set; }

		public static void ToggleDestructionMode()
		{
			if (!FinalModeEnabled)
			{
				DestructionModeEnabled = !DestructionModeEnabled;
				Debug.Log((object)("[FireSMythos] Destruction Mode: " + DestructionModeEnabled));
				FireSModeMenuUI.RefreshModeButton();
			}
		}

		public static void EnterFinalMode(Button buttonTemplate, Component textTemplate)
		{
			if (!FinalModeEnabled)
			{
				if ((Object)(object)buttonTemplate == (Object)null || (Object)(object)textTemplate == (Object)null)
				{
					Debug.LogError((object)"[FireSMythos] Final Mode templates missing!");
					return;
				}
				FinalModeEnabled = true;
				DestructionModeEnabled = false;
				Debug.Log((object)"[FireSMythos] FINAL MODE ACTIVATED!");
				FireSFinalModeScreen.Show(buttonTemplate, textTemplate);
			}
		}
	}
	public class FireSModeButtonEvents : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, ISelectHandler, IDeselectHandler
	{
		private string description;

		private bool pointerInside;

		private bool selected;

		public void Initialize(string text)
		{
			description = text;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			pointerInside = true;
			FireSModeMenuUI.ShowTooltip(description);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			pointerInside = false;
			if (!selected)
			{
				FireSModeMenuUI.HideTooltip();
			}
		}

		public void OnSelect(BaseEventData eventData)
		{
			selected = true;
			FireSModeMenuUI.ShowTooltip(description);
		}

		public void OnDeselect(BaseEventData eventData)
		{
			selected = false;
			if (!pointerInside)
			{
				FireSModeMenuUI.HideTooltip();
			}
		}
	}
	internal static class FireSModeMenuUI
	{
		private const string DESTRUCTION_NAME = "FireS_DestructionModeButton";

		private const string FINAL_NAME = "FireS_FinalModeButton";

		private const string DESTRUCTION_DESCRIPTION = "Fire S enters Berserk form. Now he can destroy entire worlds.";

		private const string FINAL_DESCRIPTION = "Fire S enters God of Death form. Now he will eliminate everything.";

		private static Button resumeTemplate;

		private static Button destructionButton;

		private static Button finalButton;

		private static Component textTemplate;

		private static TMP_Text tooltipTMP;

		private static Text tooltipLegacy;

		private static GameObject tooltipObject;

		internal static Component FindLabel(GameObject go)
		{
			TMP_Text componentInChildren = go.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				return (Component)(object)componentInChildren;
			}
			return (Component)(object)go.GetComponentInChildren<Text>(true);
		}

		internal static void SetLabel(Component label, string value)
		{
			if ((Object)(object)label == (Object)null)
			{
				return;
			}
			TMP_Text val = (TMP_Text)(object)((label is TMP_Text) ? label : null);
			if ((Object)(object)val != (Object)null)
			{
				val.text = value;
				return;
			}
			Text val2 = (Text)(object)((label is Text) ? label : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = value;
			}
		}

		internal static void DisableLocalization(GameObject go)
		{
			MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>(true);
			MonoBehaviour[] array = componentsInChildren;
			foreach (MonoBehaviour val in array)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "LocalizeText")
				{
					((Behaviour)val).enabled = false;
				}
			}
		}

		internal static void ResetButtonEvents(Button button)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			FieldInfo fieldInfo = AccessTools.Field(typeof(Button), "m_OnClick");
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(button, (object?)new ButtonClickedEvent());
			}
			else
			{
				((UnityEventBase)button.onClick).RemoveAllListeners();
			}
		}

		public static void Attach(EscapeMenuComponent menu)
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			if ((Object)(object)menu == (Object)null)
			{
				return;
			}
			object? value = AccessTools.Field(typeof(EscapeMenuComponent), "m_ButtonsContainer").GetValue(menu);
			Transform val = (Transform)((value is Transform) ? value : null);
			object? value2 = AccessTools.Field(typeof(EscapeMenuComponent), "m_ResumeButton").GetValue(menu);
			resumeTemplate = (Button)((value2 is Button) ? value2 : null);
			if ((Object)(object)val == (Object)null || (Object)(object)resumeTemplate == (Object)null)
			{
				Debug.LogError((object)"[FireSMythos] Escape menu references missing!");
				return;
			}
			textTemplate = FindLabel(((Component)resumeTemplate).gameObject);
			if ((Object)(object)textTemplate == (Object)null)
			{
				Debug.LogError((object)"[FireSMythos] Resume button label not found!");
				return;
			}
			Canvas val2 = ((Component)menu).GetComponentInParent<Canvas>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)menu).GetComponentInChildren<Canvas>(true);
			}
			if ((Object)(object)val2 != (Object)null)
			{
				CreateTooltip(val2, textTemplate);
			}
			destructionButton = FindOrCreateButton(val, "FireS_DestructionModeButton", "Destruction Mode", "Fire S enters Berserk form. Now he can destroy entire worlds.", new UnityAction(FireSModeController.ToggleDestructionMode));
			finalButton = FindOrCreateButton(val, "FireS_FinalModeButton", "Final Mode", "Fire S enters God of Death form. Now he will eliminate everything.", new UnityAction(EnterFinalMode));
			RefreshModeButton();
			MethodInfo methodInfo = AccessTools.Method(typeof(EscapeMenuComponent), "RebuildNavigation", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				methodInfo.Invoke(menu, null);
			}
			Debug.Log((object)"[FireSMythos] Custom ESC buttons attached!");
		}

		private static Button FindOrCreateButton(Transform container, string objectName, string label, string description, UnityAction action)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			Transform val = container.Find(objectName);
			Button val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Button>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(((Component)resumeTemplate).gameObject, container, false);
				((Object)val3).name = objectName;
				val2 = val3.GetComponent<Button>();
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			ResetButtonEvents(val2);
			DisableLocalization(((Component)val2).gameObject);
			SetLabel(FindLabel(((Component)val2).gameObject), label);
			((UnityEvent)val2.onClick).AddListener(action);
			((Selectable)val2).interactable = true;
			Navigation navigation = ((Selectable)val2).navigation;
			((Navigation)(ref navigation)).mode = (Mode)3;
			((Selectable)val2).navigation = navigation;
			FireSModeButtonEvents fireSModeButtonEvents = ((Component)val2).GetComponent<FireSModeButtonEvents>();
			if ((Object)(object)fireSModeButtonEvents == (Object)null)
			{
				fireSModeButtonEvents = ((Component)val2).gameObject.AddComponent<FireSModeButtonEvents>();
			}
			fireSModeButtonEvents.Initialize(description);
			((Component)val2).gameObject.SetActive(true);
			((Component)val2).transform.SetAsLastSibling();
			return val2;
		}

		private static void EnterFinalMode()
		{
			HideTooltip();
			FireSModeController.EnterFinalMode(resumeTemplate, textTemplate);
		}

		public static void RefreshModeButton()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)destructionButton == (Object)null) && (Object)(object)((Selectable)destructionButton).image != (Object)null)
			{
				((Graphic)((Selectable)destructionButton).image).color = (Color)(FireSModeController.DestructionModeEnabled ? new Color(0.85f, 0.22f, 0.12f, 1f) : Color.white);
			}
		}

		private static void CreateTooltip(Canvas canvas, Component template)
		{
			//IL_00b4: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tooltipObject != (Object)null)
			{
				return;
			}
			tooltipObject = Object.Instantiate<GameObject>(template.gameObject, ((Component)canvas).transform, false);
			((Object)tooltipObject).name = "FireS_ModeTooltip";
			DisableLocalization(tooltipObject);
			Component val = FindLabel(tooltipObject);
			tooltipTMP = (TMP_Text)(object)((val is TMP_Text) ? val : null);
			tooltipLegacy = (Text)(object)((val is Text) ? val : null);
			if ((Object)(object)tooltipTMP == (Object)null && (Object)(object)tooltipLegacy == (Object)null)
			{
				Object.Destroy((Object)(object)tooltipObject);
				tooltipObject = null;
				return;
			}
			RectTransform component = tooltipObject.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.08f, 0.045f);
			component.anchorMax = new Vector2(0.92f, 0.135f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			component.pivot = new Vector2(0.5f, 0.5f);
			if ((Object)(object)tooltipTMP != (Object)null)
			{
				tooltipTMP.alignment = (TextAlignmentOptions)514;
				((Graphic)tooltipTMP).raycastTarget = false;
			}
			else
			{
				tooltipLegacy.alignment = (TextAnchor)4;
				((Graphic)tooltipLegacy).raycastTarget = false;
			}
			SetLabel(val, "");
			tooltipObject.SetActive(false);
		}

		public static void ShowTooltip(string text)
		{
			if (!((Object)(object)tooltipObject == (Object)null))
			{
				Component label = (Component)(((Object)(object)tooltipTMP != (Object)null) ? ((object)tooltipTMP) : ((object)tooltipLegacy));
				SetLabel(label, text);
				tooltipObject.SetActive(true);
				tooltipObject.transform.SetAsLastSibling();
			}
		}

		public static void HideTooltip()
		{
			if ((Object)(object)tooltipObject != (Object)null)
			{
				tooltipObject.SetActive(false);
			}
		}
	}
	[HarmonyPatch(typeof(EscapeMenuComponent), "Awake")]
	internal static class FireSEscapeMenuAwakePatch
	{
		private static void Postfix(EscapeMenuComponent __instance)
		{
			FireSModeMenuUI.Attach(__instance);
		}
	}
	[HarmonyPatch(typeof(EscapeMenuComponent), "OnOpen")]
	internal static class FireSEscapeMenuOpenPatch
	{
		private static void Postfix(EscapeMenuComponent __instance)
		{
			FireSModeMenuUI.Attach(__instance);
		}
	}
	[HarmonyPatch(typeof(EscapeMenuComponent), "OnClose")]
	internal static class FireSEscapeMenuClosePatch
	{
		private static void Postfix()
		{
			FireSModeMenuUI.HideTooltip();
		}
	}
	internal static class FireSModOrigin
	{
		private static bool IsTrustedAssembly(string name)
		{
			int result;
			switch (name)
			{
			default:
				if (!name.StartsWith("System."))
				{
					switch (name)
					{
					case "Assembly-CSharp":
					case "Assembly-CSharp-firstpass":
					case "TFBGames":
					case "Unity.Entities":
					case "Unity.Mathematics":
					case "Unity.Collections":
						goto IL_00f3;
					}
					if (!name.StartsWith("UnityEngine") && !name.StartsWith("Unity.") && !name.StartsWith("Landfall.") && !name.StartsWith("Mono.") && !name.StartsWith("BepInEx.") && !name.StartsWith("MonoMod."))
					{
						result = (name.StartsWith("Harmony") ? 1 : 0);
						break;
					}
				}
				goto IL_00f3;
			case "mscorlib":
			case "netstandard":
			case "System":
				goto IL_00f3;
				IL_00f3:
				result = 1;
				break;
			}
			return (byte)result != 0;
		}

		public static bool TryFindExternalCaller(out string caller)
		{
			caller = null;
			StackFrame[] frames = new StackTrace(2, fNeedFileInfo: false).GetFrames();
			if (frames == null)
			{
				return false;
			}
			Assembly assembly = typeof(FireSModOrigin).Assembly;
			StackFrame[] array = frames;
			foreach (StackFrame stackFrame in array)
			{
				MethodBase method = stackFrame.GetMethod();
				if (method == null || method.DeclaringType == null)
				{
					continue;
				}
				Assembly assembly2 = method.DeclaringType.Assembly;
				if (!(assembly2 == assembly) && !assembly2.IsDynamic)
				{
					string text = assembly2.GetName().Name ?? "";
					if (!IsTrustedAssembly(text))
					{
						caller = text + " :: " + method.DeclaringType.FullName + "." + method.Name;
						return true;
					}
				}
			}
			return false;
		}
	}
	internal static class FireSMonoBatchDispatcher
	{
		private static bool updateFreezeLogged;

		private static bool fixedFreezeLogged;

		public static bool UpdatePrefix(MonoBatchService instance)
		{
			if (!FireSAttack.IsGameLoopPaused)
			{
				return true;
			}
			if (!updateFreezeLogged)
			{
				updateFreezeLogged = true;
				Debug.LogWarning((object)"[FireSMythos] MonoBatchService.OnUpdate SUPPRESSED during game freeze.");
			}
			return false;
		}

		public static bool FixedUpdatePrefix(MonoBatchService instance)
		{
			if (!FireSAttack.IsGameLoopPaused)
			{
				return true;
			}
			if (!fixedFreezeLogged)
			{
				fixedFreezeLogged = true;
				Debug.LogWarning((object)"[FireSMythos] MonoBatchService.OnFixedUpdate SUPPRESSED during game freeze.");
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(MonoBatchService), "OnUpdate")]
	internal static class FireSMonoBatchUpdatePatch
	{
		private static bool Prefix(MonoBatchService __instance)
		{
			return FireSMonoBatchDispatcher.UpdatePrefix(__instance);
		}
	}
	[HarmonyPatch(typeof(MonoBatchService), "OnFixedUpdate")]
	internal static class FireSMonoBatchFixedUpdatePatch
	{
		private static bool Prefix(MonoBatchService __instance)
		{
			return FireSMonoBatchDispatcher.FixedUpdatePrefix(__instance);
		}
	}
	internal static class FireSMutationGuard
	{
		public static bool ShouldBlock(Component target, string operation)
		{
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			if (!FireSProtection.IsProtectedObject((Object)(object)target))
			{
				return false;
			}
			if (!FireSCallerPolicy.TryGetModCaller(out var caller))
			{
				return false;
			}
			FireSCallerPolicy.LogBlocked(operation, caller);
			return true;
		}
	}
	[BepInPlugin("fires.mythos", "Fire S Mythos", "0.2.0")]
	public class FireSMythosPlugin : BaseUnityPlugin
	{
		private void Awake()
		{
			FireSRuntimeApiGuard.Initialize();
			Debug.Log((object)"[FireSMythos] Starting Fire S Mythos!");
			FireSSceneRespawnManager.Initialize((MonoBehaviour)(object)this);
			AssetImporter.Initialize();
			new FireSMythosMain();
		}
	}
	public class FireSMythosMain : Mod
	{
		private static bool harmonyInstalled;

		public FireSMythosMain()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			Mod.DEV_MODE = false;
			if (!harmonyInstalled)
			{
				Harmony val = new Harmony("FireSMythos.VictoryScreen");
				val.PatchAll();
				harmonyInstalled = true;
				Debug.Log((object)"[FireSMythos] Victory patches installed!");
			}
			ModFaction modFaction = Mod.CreateFaction("Fire S Mythos");
			modFaction.Icon = Mod.GetIcon("Hillary");
			modFaction.Color("#D8422F");
			ModUnit modUnit = modFaction.NewUnit("Fire S");
			modUnit.Health = float.PositiveInfinity;
			modUnit.Cost = 1000;
			modUnit.Icon = Mod.GetIcon("Teacher");
			modUnit.Size = 1.2f;
			modUnit.Mass = 20f;
			ModModel model = Mod.GetModel("FireS_Blockout8");
			if (model == null)
			{
				Debug.LogError((object)"[FireSMythos] Custom model not found!");
				return;
			}
			GameObject unitBase = modUnit.internalObject.UnitBase;
			if ((Object)(object)unitBase == (Object)null)
			{
				Debug.LogError((object)"[FireSMythos] Original UnitBase is NULL!");
				return;
			}
			GameObject val2 = Mod.CloneAndPoolObject(unitBase);
			val2.AddComponent<FireSBaseProbe>();
			val2.AddComponent<FireSAttack>();
			val2.AddComponent<FireSIndestructibleTag>();
			Debug.Log((object)("[FireSMythos] BASE PREFAB: ActiveSelf=" + val2.activeSelf + ", ActiveHierarchy=" + val2.activeInHierarchy + ", Parent=" + ((Object)val2.transform.parent).name));
			GameObject val3 = Object.Instantiate<GameObject>(model.internalObject, val2.transform, false);
			((Object)val3).name = "FireS_Visual";
			val3.transform.localRotation = Utilities.blenderToUnity;
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(0.03582494f, -0.0435576f, 2.443953f);
			val3.transform.localPosition = Utilities.blenderToUnity * val4;
			val3.transform.localScale = Vector3.one;
			val3.SetActive(true);
			MeshRenderer component = val3.GetComponent<MeshRenderer>();
			Debug.Log((object)("[FireSMythos] Visual position: " + ((object)val3.transform.localPosition/*cast due to .constrained prefix*/).ToString()));
			Debug.Log((object)("[FireSMythos] Visual bounds: " + ((object)((Renderer)component).bounds/*cast due to .constrained prefix*/).ToString()));
			Debug.Log((object)("[FireSMythos] Visual active: " + val3.activeInHierarchy));
			val3.SetActive(true);
			FireSBaseVisibility fireSBaseVisibility = val2.AddComponent<FireSBaseVisibility>();
			fireSBaseVisibility.Initialize(val3.transform);
			Debug.Log((object)"[FireSMythos] Default body hidden!");
			MeshFilter component2 = val3.GetComponent<MeshFilter>();
			MeshRenderer component3 = val3.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null)
			{
				Debug.LogError((object)"[FireSMythos] Visual has no MeshFilter or MeshRenderer!");
				return;
			}
			Debug.Log((object)("[FireSMythos] Visual vertices: " + component2.sharedMesh.vertexCount));
			ModBase modBase = new ModBase(val2);
			modUnit.Base = modBase;
			FireSSceneRespawnManager.SetBlueprint(modUnit.internalObject);
			Debug.Log((object)("[FireSMythos] BLUEPRINT BASE MATCH: " + ((Object)(object)modUnit.internalObject.UnitBase == (Object)(object)val2)));
			Debug.Log((object)"[FireSMythos] Custom UnitBase assigned!");
			Debug.Log((object)"[FireSMythos] Custom visual added to UnitBase!");
		}
	}
	public class FireSBaseProbe : MonoBehaviour
	{
		private bool visualCreated;

		private IEnumerator Start()
		{
			yield return null;
			AttachVisual();
		}

		private void AttachVisual()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if (visualCreated)
			{
				return;
			}
			if ((Object)(object)((Component)this).transform.Find("FireS_RuntimeVisual") != (Object)null)
			{
				visualCreated = true;
				return;
			}
			GameObject model = Utilities.GetModel("FireS_Blockout8");
			if ((Object)(object)model == (Object)null)
			{
				Debug.LogError((object)"[FireSMythos] Source model missing!");
				return;
			}
			MeshFilter component = model.GetComponent<MeshFilter>();
			MeshRenderer component2 = model.GetComponent<MeshRenderer>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
			{
				Debug.LogError((object)"[FireSMythos] Source mesh missing!");
				return;
			}
			GameObject val = new GameObject("FireS_RuntimeVisual");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localRotation = Utilities.blenderToUnity;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0.03582494f, -0.0435576f, 2.443953f);
			val.transform.localPosition = Utilities.blenderToUnity * val2;
			val.transform.localScale = Vector3.one;
			MeshFilter filter = val.AddComponent<MeshFilter>();
			MeshRenderer renderer = val.AddComponent<MeshRenderer>();
			FireSVisualIntegrity fireSVisualIntegrity = val.AddComponent<FireSVisualIntegrity>();
			fireSVisualIntegrity.Initialize(filter, renderer, component.sharedMesh, ((Renderer)component2).sharedMaterials);
			val.SetActive(true);
			visualCreated = true;
			Debug.Log((object)"[FireSMythos] Isolated runtime visual created!");
		}
	}
	internal static class FireSPersistentModObjectGuard
	{
		private const string QuarantineSceneName = "FireS_Quarantine";

		private static Scene quarantineScene;

		private static readonly HashSet<int> processed = new HashSet<int>();

		private static bool IsProtectedInfrastructure(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return true;
			}
			if (FireSProtection.IsProtectedObject((Object)(object)root))
			{
				return true;
			}
			if ((Object)(object)root.GetComponentInChildren<ServiceLocator>(true) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)root.GetComponentInChildren<Camera>(true) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)root.GetComponentInChildren<Canvas>(true) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)root.GetComponentInChildren<EventSystem>(true) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)root.GetComponentInChildren<AudioListener>(true) != (Object)null)
			{
				return true;
			}
			MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
			MonoBehaviour[] array = componentsInChildren;
			foreach (MonoBehaviour val in array)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().Assembly == typeof(FireSPersistentModObjectGuard).Assembly)
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsExternalModOwned(Object target)
		{
			if (target == (Object)null)
			{
				return false;
			}
			GameObject val = (GameObject)(object)((target is GameObject) ? target : null);
			Component val2 = (Component)(object)((target is Component) ? target : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val = val2.gameObject;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			GameObject gameObject = ((Component)val.transform.root).gameObject;
			if (IsProtectedInfrastructure(gameObject))
			{
				return false;
			}
			MonoBehaviour[] componentsInChildren = gameObject.GetComponentsInChildren<MonoBehaviour>(true);
			MonoBehaviour[] array = componentsInChildren;
			foreach (MonoBehaviour val3 in array)
			{
				if (!((Object)(object)val3 == (Object)null) && FireSRuntimeApiGuard.IsExternalModAssembly(((object)val3).GetType().Assembly))
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsPersistentScene(Scene scene)
		{
			return ((Scene)(ref scene)).IsValid() && ((Scene)(ref scene)).isLoaded && string.Equals(((Scene)(ref scene)).name, "DontDestroyOnLoad", StringComparison.OrdinalIgnoreCase);
		}

		private static Scene GetQuarantineScene()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (((Scene)(ref quarantineScene)).IsValid() && ((Scene)(ref quarantineScene)).isLoaded)
			{
				return quarantineScene;
			}
			quarantineScene = SceneManager.GetSceneByName("FireS_Quarantine");
			if (!((Scene)(ref quarantineScene)).IsValid() || !((Scene)(ref quarantineScene)).isLoaded)
			{
				quarantineScene = SceneManager.CreateScene("FireS_Quarantine");
			}
			return quarantineScene;
		}

		private static void DisableObjectComponents(GameObject root)
		{
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			Component[] array = componentsInChildren;
			foreach (Component val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
				if ((Object)(object)val2 != (Object)null)
				{
					try
					{
						MonoBehaviour val3 = (MonoBehaviour)(object)((val is MonoBehaviour) ? val : null);
						if ((Object)(object)val3 != (Object)null)
						{
							val3.StopAllCoroutines();
							((Behaviour)val3).enabled = false;
						}
						else if ((Object)(object)val2 != (Object)null)
						{
							val2.enabled = false;
						}
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[FireSIntegrityGuard] Behaviour disable failed: " + ex.Message));
					}
				}
				Renderer val4 = (Renderer)(object)((val is Renderer) ? val : null);
				if ((Object)(object)val4 != (Object)null)
				{
					val4.enabled = false;
				}
				Collider val5 = (Collider)(object)((val is Collider) ? val : null);
				if ((Object)(object)val5 != (Object)null)
				{
					val5.enabled = false;
				}
				AudioSource val6 = (AudioSource)(object)((val is AudioSource) ? val : null);
				if ((Object)(object)val6 != (Object)null)
				{
					val6.Stop();
				}
				ParticleSystem val7 = (ParticleSystem)(object)((val is ParticleSystem) ? val : null);
				if ((Object)(object)val7 != (Object)null)
				{
					val7.Stop(true, (ParticleSystemStopBehavior)0);
				}
				Rigidbody val8 = (Rigidbody)(object)((val is Rigidbody) ? val : null);
				if ((Object)(object)val8 != (Object)null)
				{
					val8.velocity = Vector3.zero;
					val8.angularVelocity = Vector3.zero;
					val8.isKinematic = true;
				}
			}
		}

		private static void Quarantine(GameObject root)
		{
			//IL_0058: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null || IsProtectedInfrastructure(root))
			{
				return;
			}
			int instanceID = ((Object)root).GetInstanceID();
			if (!processed.Add(instanceID))
			{
				return;
			}
			Debug.LogWarning((object)("[FireSIntegrityGuard] Persistent mod object quarantined: " + ((Object)root).name));
			DisableObjectComponents(root);
			try
			{
				Scene val = GetQuarantineScene();
				if ((Object)(object)root.transform.parent != (Object)null)
				{
					root.transform.SetParent((Transform)null, true);
				}
				SceneManager.MoveGameObjectToScene(root, val);
				((Object)root).hideFlags = (HideFlags)61;
				Object.Destroy((Object)(object)root, 0f);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[FireSIntegrityGuard] Quarantine failed: " + ((Object)root).name + " | " + ex));
			}
		}

		public static void QuarantinePersistentRoots()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (!FireSModeController.DestructionModeEnabled)
			{
				return;
			}
			processed.Clear();
			MonoBehaviour[] array = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			MonoBehaviour[] array2 = array;
			foreach (MonoBehaviour val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val).gameObject.scene;
				if (IsPersistentScene(scene))
				{
					GameObject gameObject = ((Component)((Component)val).transform.root).gameObject;
					if (IsExternalModOwned((Object)(object)gameObject))
					{
						hashSet.Add(gameObject);
					}
				}
			}
			foreach (GameObject item in hashSet)
			{
				if ((Object)(object)item != (Object)null)
				{
					Quarantine(item);
				}
			}
			Debug.LogWarning((object)("[FireSIntegrityGuard] Persistent mod roots processed: " + hashSet.Count));
			processed.Clear();
		}

		public static IEnumerator QuarantineBurst(float duration, float interval)
		{
			float end = Time.realtimeSinceStartup + duration;
			while (Time.realtimeSinceStartup < end && FireSModeController.DestructionModeEnabled)
			{
				QuarantinePersistentRoots();
				yield return (object)new WaitForSecondsRealtime(interval);
			}
		}
	}
	[HarmonyPatch(typeof(Object), "DontDestroyOnLoad", new Type[] { typeof(Object) })]
	internal static class FireSNoNewPersistentObjectsPatch
	{
		private static bool Prefix(Object target)
		{
			if (!FireSModeController.DestructionModeEnabled)
			{
				return true;
			}
			if (FireSPersistentModObjectGuard.IsExternalModOwned(target))
			{
				Debug.LogWarning((object)("[FireSIntegrityGuard] External persistent registration blocked: " + target.name));
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SceneManager), "MoveGameObjectToScene", new Type[]
	{
		typeof(GameObject),
		typeof(Scene)
	})]
	internal static class FireSNoPersistentSceneMovePatch
	{
		private static bool Prefix(GameObject __0, Scene __1)
		{
			if (!FireSModeController.DestructionModeEnabled)
			{
				return true;
			}
			if (!string.Equals(((Scene)(ref __1)).name, "DontDestroyOnLoad", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return !FireSPersistentModObjectGuard.IsExternalModOwned((Object)(object)__0);
		}
	}
	internal static class FireSPlayerLoopFreeze
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		private struct FireSTabPollSystem
		{
		}

		private static PlayerLoopSystem originalLoop;

		private static bool hasOriginalLoop;

		private static bool loopFrozen;

		private static PlayerLoopSystem frozenLoop;

		private static bool hasFrozenLoop;

		private static bool loopWatchdogLogged;

		public static bool IsFrozen => loopFrozen;

		private static void PollTab()
		{
			if (loopFrozen)
			{
				EnsureFrozenLoop();
			}
			if (Input.GetKeyDown((KeyCode)9))
			{
				Debug.Log((object)"[FireSMythos] TAB PRESSED. RESTORING PLAYER LOOP.");
				FireSAttack.ResumeFromPlayerLoop();
			}
		}

		private static bool IsMinimalLoop(PlayerLoopSystem loop)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (loop.subSystemList == null || loop.subSystemList.Length != 2)
			{
				return false;
			}
			bool flag = false;
			bool flag2 = false;
			PlayerLoopSystem[] subSystemList = loop.subSystemList;
			foreach (PlayerLoopSystem val in subSystemList)
			{
				if (val.type == null)
				{
					return false;
				}
				if (val.type.Name == "EarlyUpdate")
				{
					flag = true;
				}
				if (val.type.Name == "PostLateUpdate")
				{
					flag2 = true;
				}
			}
			return flag && flag2;
		}

		private static string DescribeLoop(PlayerLoopSystem loop)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (loop.subSystemList == null)
			{
				return "<NO ROOT SYSTEMS>";
			}
			StringBuilder stringBuilder = new StringBuilder();
			PlayerLoopSystem[] subSystemList = loop.subSystemList;
			foreach (PlayerLoopSystem val in subSystemList)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(" | ");
				}
				stringBuilder.Append((val.type == null) ? "<NULL>" : val.type.FullName);
			}
			return stringBuilder.ToString();
		}

		private static void EnsureFrozenLoop()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!loopFrozen || !hasFrozenLoop)
			{
				return;
			}
			try
			{
				PlayerLoopSystem currentPlayerLoop = PlayerLoop.GetCurrentPlayerLoop();
				if (!IsMinimalLoop(currentPlayerLoop))
				{
					Debug.LogError((object)"[FireSMythos] PLAYER LOOP WAS REPLACED DURING FREEZE!");
					Debug.LogError((object)("[FireSMythos] Unexpected roots: " + DescribeLoop(currentPlayerLoop)));
					PlayerLoop.SetPlayerLoop(frozenLoop);
					PlayerLoopSystem currentPlayerLoop2 = PlayerLoop.GetCurrentPlayerLoop();
					if (!IsMinimalLoop(currentPlayerLoop2))
					{
						Debug.LogError((object)"[FireSMythos] FAILED TO REASSERT MINIMAL PLAYER LOOP!");
					}
					else if (!loopWatchdogLogged)
					{
						loopWatchdogLogged = true;
						Debug.LogWarning((object)"[FireSMythos] MINIMAL PLAYER LOOP REASSERTED SUCCESSFULLY.");
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[FireSMythos] LOOP WATCHDOG FAILED: " + ex));
			}
		}

		private static bool TryFindSystem(PlayerLoopSystem root, string name, out PlayerLoopSystem result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (root.subSystemList != null)
			{
				PlayerLoopSystem[] subSystemList = root.subSystemList;
				foreach (PlayerLoopSystem val in subSystemList)
				{
					if (val.type != null && val.type.Name == name)
					{
						result = val;
						return true;
					}
				}
			}
			result = default(PlayerLoopSystem);
			return false;
		}

		private static bool BuildEarlyUpdate(PlayerLoopSystem original, out PlayerLoopSystem result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			result = original;
			if (original.subSystemList == null)
			{
				return false;
			}
			List<PlayerLoopSystem> list = new List<PlayerLoopSystem>();
			bool flag = false;
			PlayerLoopSystem[] subSystemList = original.subSystemList;
			foreach (PlayerLoopSystem val in subSystemList)
			{
				if (!(val.type == null) && !(val.type.Name != "UpdateInputManager"))
				{
					list.Add(val);
					list.Add(new PlayerLoopSystem
					{
						type = typeof(FireSTabPollSystem),
						updateDelegate = new UpdateFunction(PollTab)
					});
					flag = true;
				}
			}
			if (!flag)
			{
				return false;
			}
			result.subSystemList = list.ToArray();
			return true;
		}

		private static PlayerLoopSystem BuildPostLateUpdate(PlayerLoopSystem original)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			PlayerLoopSystem result = original;
			if (original.subSystemList == null)
			{
				result.subSystemList = (PlayerLoopSystem[])(object)new PlayerLoopSystem[0];
				return result;
			}
			string[] array = new string[15]
			{
				"PlayerSendFrameStarted", "UpdateRectTransform", "UpdateCanvasRectTransform", "PlayerUpdateCanvases", "UpdateAudio", "UpdateAllRenderers", "UpdateAllSkinnedMeshes", "FinishFrameRendering", "PlayerSendFrameComplete", "ClearImmediateRenderers",
				"UpdateCaptureScreenshot", "PresentAfterDraw", "PlayerSendFramePostPresent", "UpdateResolution", "XRPostLateUpdate"
			};
			List<PlayerLoopSystem> list = new List<PlayerLoopSystem>();
			PlayerLoopSystem[] subSystemList = original.subSystemList;
			foreach (PlayerLoopSystem val in subSystemList)
			{
				if (val.type == null)
				{
					continue;
				}
				string[] array2 = array;
				foreach (string text in array2)
				{
					if (val.type.Name == text)
					{
						list.Add(val);
						break;
					}
				}
			}
			result.subSystemList = list.ToArray();
			return result;
		}

		public static bool Freeze()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			if (loopFrozen)
			{
				return true;
			}
			try
			{
				originalLoop = PlayerLoop.GetCurrentPlayerLoop();
				hasOriginalLoop = true;
				List<PlayerLoopSystem> list = new List<PlayerLoopSystem>();
				bool flag = false;
				bool flag2 = false;
				if (originalLoop.subSystemList == null)
				{
					throw new Exception("PlayerLoop has no subsystems.");
				}
				PlayerLoopSystem[] subSystemList = originalLoop.subSystemList;
				foreach (PlayerLoopSystem val in subSystemList)
				{
					if (val.type == null)
					{
						continue;
					}
					if (val.type.Name == "EarlyUpdate")
					{
						if (!BuildEarlyUpdate(val, out var result))
						{
							throw new Exception("EarlyUpdate.UpdateInputManager not found.");
						}
						list.Add(result);
						flag = true;
					}
					else if (val.type.Name == "PostLateUpdate")
					{
						list.Add(BuildPostLateUpdate(val));
						flag2 = true;
					}
				}
				if (!flag)
				{
					throw new Exception("EarlyUpdate not found.");
				}
				if (!flag2)
				{
					throw new Exception("PostLateUpdate not found.");
				}
				PlayerLoopSystem val2 = originalLoop;
				val2.subSystemList = list.ToArray();
				frozenLoop = val2;
				hasFrozenLoop = true;
				loopFrozen = true;
				PlayerLoop.SetPlayerLoop(frozenLoop);
				PlayerLoopSystem currentPlayerLoop = PlayerLoop.GetCurrentPlayerLoop();
				Debug.LogWarning((object)("[FireSMythos] PLAYER LOOP AFTER FREEZE: " + DescribeLoop(currentPlayerLoop)));
				if (!IsMinimalLoop(currentPlayerLoop))
				{
					throw new Exception("Unity did not retain the minimal PlayerLoop.");
				}
				loopWatchdogLogged = false;
				Debug.Log((object)"[FireSMythos] MINIMAL PLAYER LOOP VERIFIED.");
				Debug.Log((object)"[FireSMythos] MINIMAL PLAYER LOOP INSTALLED.");
				Debug.Log((object)"[FireSMythos] Only input polling and rendering remain.");
				return true;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[FireSMythos] PLAYER LOOP FREEZE FAILED: " + ex));
				Restore();
				return false;
			}
		}

		public static void Restore()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (hasOriginalLoop)
			{
				try
				{
					PlayerLoop.SetPlayerLoop(originalLoop);
					Debug.Log((object)"[FireSMythos] ORIGINAL PLAYER LOOP RESTORED.");
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[FireSMythos] PLAYER LOOP RESTORE FAILED: " + ex));
				}
				loopFrozen = false;
				hasOriginalLoop = false;
			}
		}
	}
	[HarmonyPatch]
	internal static class FireSRendererPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodBase setter = AccessTools.PropertySetter(typeof(Renderer), "enabled");
			if (setter != null)
			{
				yield return setter;
			}
			foreach (MethodInfo method in AccessTools.GetDeclaredMethods(typeof(Renderer)))
			{
				if (method.Name == "SetPropertyBlock")
				{
					yield return method;
				}
			}
		}

		private static bool Prefix(Renderer __instance)
		{
			return !FireSMutationGuard.ShouldBlock((Component)(object)__instance, "Renderer mutation");
		}
	}
	public static class FireSRuntimeApiGuard
	{
		[Flags]
		private enum ApiMatch
		{
			None = 0,
			PlayerLoop = 1,
			AppDomain = 2,
			HarmonyUnpatch = 4,
			TimeScaleReset = 8,
			RigidbodyWakeUp = 0x10,
			DontMoveForReset = 0x20
		}

		private sealed class RuntimeGuardRunner : MonoBehaviour
		{
			private bool firstUpdateLogged;

			private void Update()
			{
				if (!firstUpdateLogged)
				{
					firstUpdateLogged = true;
					Debug.Log((object)"[FireSRuntimeApiGuard] Unity runner Update is ticking.");
				}
				GuardUpdate();
			}
		}

		private const string PlayerLoopType = "UnityEngine.LowLevel.PlayerLoop";

		private const string AppDomainType = "System.AppDomain";

		private const string TimeType = "UnityEngine.Time";

		private static readonly object Sync = new object();

		private static readonly Assembly OwnAssembly = typeof(FireSRuntimeApiGuard).Assembly;

		private static readonly HashSet<Assembly> ScannedAssemblies = new HashSet<Assembly>();

		private static readonly HashSet<Assembly> ScanningAssemblies = new HashSet<Assembly>();

		private static readonly HashSet<MethodBase> HookedMethods = new HashSet<MethodBase>();

		private static readonly HashSet<MethodBase> HookingMethods = new HashSet<MethodBase>();

		private static readonly HashSet<Type> BlockedPlayerLoopTypes = new HashSet<Type>();

		private static readonly List<ILHook> ActiveHooks = new List<ILHook>();

		private static readonly HashSet<string> RuntimeExecutionLogged = new HashSet<string>();

		private static readonly Dictionary<ushort, OpCode> OpCodeMap = BuildOpCodeMap();

		private static bool initialized;

		private static int unityMainThreadId;

		private static bool playerLoopCleanupPending;

		private static float nextPlayerLoopSweep;

		private const float PlayerLoopSweepInterval = 0.25f;

		private static GameObject runnerObject;

		public static bool IsExternalModAssembly(Assembly assembly)
		{
			return IsCandidateAssembly(assembly);
		}

		public static void ReportRuntimeExecution(string methodName)
		{
			bool flag;
			lock (Sync)
			{
				flag = RuntimeExecutionLogged.Add(methodName);
			}
			if (flag)
			{
				Debug.LogWarning((object)("[FireSRuntimeApiGuard] RUNTIME BODY ENTERED: " + methodName));
			}
		}

		private static void EmitRuntimeExecutionMarker(ILProcessor processor, MethodBody body, MethodBase target)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo method = typeof(FireSRuntimeApiGuard).GetMethod("ReportRuntimeExecution", BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				throw new MissingMethodException("ReportRuntimeExecution was not found.");
			}
			MethodReference val = ((MemberReference)body.Method).Module.ImportReference((MethodBase)method);
			string text = target.Module.Assembly.GetName().Name + " | " + ((target.DeclaringType == null) ? "<unknown>" : target.DeclaringType.FullName) + "." + target.Name;
			processor.Emit(OpCodes.Ldstr, text);
			processor.Emit(OpCodes.Call, val);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static int RuntimeDetourProbeTarget()
		{
			return 13579;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static int RuntimeDetourProbeCaller()
		{
			return RuntimeDetourProbeTarget();
		}

		private static bool VerifyRuntimeDetour()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			int num = RuntimeDetourProbeCaller();
			if (num != 13579)
			{
				throw new InvalidOperationException("Pre-JIT probe failed: " + num);
			}
			Debug.LogWarning((object)("[FireSRuntimeApiGuard] PRE-JIT COMPLETE. Original result=" + num));
			ILHook val = null;
			try
			{
				MethodInfo target = typeof(FireSRuntimeApiGuard).GetMethod("RuntimeDetourProbeTarget", BindingFlags.Static | BindingFlags.NonPublic);
				if (target == null)
				{
					throw new MissingMethodException("RuntimeDetourProbeTarget was not found.");
				}
				ILHookConfig val2 = new ILHookConfig
				{
					ManualApply = true,
					ID = "FireSMythos.RuntimeApiGuard.Probe",
					Priority = int.MinValue
				};
				val = new ILHook((MethodBase)target, (Manipulator)delegate(ILContext context)
				{
					RewriteMethod(context, target);
				}, ref val2);
				val.Apply();
				int num2 = RuntimeDetourProbeCaller();
				Debug.LogWarning((object)("[FireSRuntimeApiGuard] PRE-JIT DETOUR TEST: Before=" + num + ", After=" + num2));
				if (num2 != 0)
				{
					throw new InvalidOperationException("Detour did not intercept an already JIT-compiled callsite.");
				}
				if (!val.IsValid || !val.IsApplied)
				{
					throw new InvalidOperationException("Probe hook was not applied. Valid=" + val.IsValid + ", Applied=" + val.IsApplied);
				}
				int num3 = RuntimeDetourProbeTarget();
				if (num3 != 0)
				{
					throw new InvalidOperationException("ILHook reports IsApplied=true, but execution was not redirected. Expected=0, Actual=" + num3);
				}
				lock (Sync)
				{
					ActiveHooks.Add(val);
				}
				Debug.LogWarning((object)("[FireSRuntimeApiGuard] RUNTIME DETOUR SELF-TEST PASSED. Expected=0, Actual=" + num3 + ", IsApplied=" + val.IsApplied));
				return true;
			}
			catch (Exception ex)
			{
				if (val != null)
				{
					try
					{
						val.Dispose();
					}
					catch
					{
					}
				}
				Debug.LogError((object)("[FireSRuntimeApiGuard] RUNTIME DETOUR SELF-TEST FAILED: " + ex));
				return false;
			}
		}

		public static void Initialize()
		{
			lock (Sync)
			{
				if (initialized)
				{
					return;
				}
				initialized = true;
				unityMainThreadId = Thread.CurrentThread.ManagedThreadId;
			}
			Debug.Log((object)"[FireSRuntimeApiGuard] Runtime protection started.");
			AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
			EnsureRunner();
			Assembly assembly = typeof(ILHook).Assembly;
			Debug.Log((object)("[FireSRuntimeApiGuard] RuntimeDetour assembly: " + assembly.FullName));
			try
			{
				Debug.Log((object)("[FireSRuntimeApiGuard] RuntimeDetour location: " + assembly.Location));
			}
			catch
			{
			}
			if (!VerifyRuntimeDetour())
			{
				Debug.LogError((object)"[FireSRuntimeApiGuard] Protection disabled: RuntimeDetour execution test failed.");
				AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
				return;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			Assembly[] array = assemblies;
			foreach (Assembly assembly2 in array)
			{
				ScanAssembly(assembly2);
			}
			Debug.Log((object)"[FireSRuntimeApiGuard] Initial assembly scan completed.");
		}

		private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
		{
			if (args != null && !(args.LoadedAssembly == null))
			{
				ScanAssembly(args.LoadedAssembly);
			}
		}

		private static void EnsureRunner()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if (Thread.CurrentThread.ManagedThreadId != unityMainThreadId || (Object)(object)runnerObject != (Object)null)
			{
				return;
			}
			try
			{
				runnerObject = new GameObject("FireSMythos_RuntimeApiGuard");
				((Object)runnerObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)runnerObject);
				runnerObject.AddComponent<RuntimeGuardRunner>();
				Debug.Log((object)"[FireSRuntimeApiGuard] Unity runner created.");
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[FireSRuntimeApiGuard] Runner creation failed: " + ex));
			}
		}

		private static void GuardUpdate()
		{
			FireSSpawnHarmonyGuard.Refresh();
			if (!(Time.unscaledTime < nextPlayerLoopSweep))
			{
				nextPlayerLoopSweep = Time.unscaledTime + 0.25f;
				bool flag;
				lock (Sync)
				{
					flag = playerLoopCleanupPending || BlockedPlayerLoopTypes.Count > 0;
				}
				if (flag)
				{
					RemoveBlockedPlayerLoopNodes();
				}
			}
		}

		private static bool IsCandidateAssembly(Assembly assembly)
		{
			if (assembly == null)
			{
				return false;
			}
			if (assembly == OwnAssembly)
			{
				return false;
			}
			string text;
			try
			{
				text = assembly.GetName().Name ?? "";
			}
			catch
			{
				return false;
			}
			string[] array = new string[10] { "mscorlib", "netstandard", "System", "Microsoft", "Unity", "Mono", "MonoMod", "Mono.Cecil", "BepInEx", "TFBGames" };
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				if (text.Equals(text2, StringComparison.OrdinalIgnoreCase) |