Decompiled source of AnarchyMode v0.1.1

BepInEx\plugins\AnarchyMode.dll

Decompiled 10 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AnarchyMode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+19ee0ece78f4c3ba8d9ef014d5917294dd01eb7c")]
[assembly: AssemblyProduct("AnarchyMode")]
[assembly: AssemblyTitle("AnarchyMode")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AnarchyMode
{
	public class AnarchyBehaviour : MonoBehaviour
	{
		internal Hud Hud;

		internal SpectatorMode Spectator;

		private WarDirector _war;

		private DeathTracker _deaths;

		private WeaponSpawner _weapons;

		private bool _cityReady;

		private bool _initialized;

		private bool _generationComplete;

		private string _seed;

		private int _initStage;

		private bool _autoStartTried;

		private float _autoStartTimer;

		private bool _citySizeApplied;

		private int _weaponIndex;

		private bool _wallHack;

		private bool _weaponMenuOpen;

		private bool _killingNpc;

		private bool _scoreboardDismissed;

		private bool _investigationWarned;

		private float _scoreboardTimer;

		private readonly Dictionary<int, Human> _lastAttacker = new Dictionary<int, Human>();

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

		internal static AnarchyBehaviour Instance { get; private set; }

		internal bool Enabled => ModConfig.Enabled.Value;

		public AnarchyBehaviour(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			Instance = this;
			_war = new WarDirector();
			_deaths = new DeathTracker();
			_weapons = new WeaponSpawner();
			_war.AttachWeapons(_weapons);
			Plugin.Logger.LogInfo((object)"AnarchyBehaviour ready");
		}

		private void Update()
		{
			if (!Enabled)
			{
				return;
			}
			try
			{
				if (ModConfig.AutoStartTestCity.Value)
				{
					TryAutoStartTestCity();
				}
				if ((Object)(object)CityData.Instance == (Object)null)
				{
					ApplyCitySize();
				}
				CityData instance = CityData.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					_generationComplete = false;
					Hud?.SetVisible(visible: false);
				}
				else
				{
					if ((Object)(object)Player.Instance == (Object)null)
					{
						return;
					}
					if (_cityReady && !string.IsNullOrEmpty(instance.seed) && instance.seed != _seed)
					{
						_cityReady = false;
						_initialized = false;
						_generationComplete = false;
					}
					if (!_cityReady)
					{
						if (!_generationComplete || !IsCityUsable(instance))
						{
							return;
						}
						BeginCity(instance);
					}
					if (!_initialized)
					{
						StepInitialization();
						return;
					}
					Player instance2 = Player.Instance;
					HandleControls();
					_war.Tick(Time.deltaTime);
					_deaths.Scan(instance, Hud, firstScan: false);
					UpdateScoreboard(instance2);
					Spectator.Update(Time.deltaTime);
					Hud.Tick(Time.deltaTime);
					if ((Object)(object)instance2 != (Object)null && ((Actor)instance2).isDead && !Spectator.Active)
					{
						Spectator.Enter(instance2);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Anarchy Update: " + ex));
			}
		}

		private void EnsureHud()
		{
			if (Hud == null || !Hud.IsAlive)
			{
				Hud = new Hud();
				Spectator = new SpectatorMode(Hud);
			}
			else if (Spectator == null)
			{
				Spectator = new SpectatorMode(Hud);
			}
		}

		internal void ApplyCitySize()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if (_citySizeApplied)
			{
				return;
			}
			try
			{
				RestartSafeController instance = RestartSafeController.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					int num = Math.Max(1, ModConfig.CityWidth.Value);
					int num2 = Math.Max(1, ModConfig.CityHeight.Value);
					instance.cityX = num + 2;
					instance.cityY = num2 + 2;
					_citySizeApplied = true;
					ManualLogSource logger = Plugin.Logger;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("City size set to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("x");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" blocks");
					}
					logger.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("ApplyCitySize: " + ex.Message));
			}
		}

		private void TryAutoStartTestCity()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			if (_autoStartTried)
			{
				return;
			}
			_autoStartTimer += Time.unscaledDeltaTime;
			if (_autoStartTimer < 8f)
			{
				return;
			}
			_autoStartTried = true;
			try
			{
				CityConstructor instance = CityConstructor.Instance;
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Auto-start check: constructor=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)instance != (Object)null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", city=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)CityData.Instance != (Object)null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", player=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)Player.Instance != (Object)null);
				}
				logger.LogInfo(val);
				if ((Object)(object)instance != (Object)null && (Object)(object)CityData.Instance == (Object)null)
				{
					Plugin.Logger.LogInfo((object)"Auto-starting test city");
					instance.GenerateNewCity();
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Auto-start test city: " + ex));
			}
		}

		private static bool IsCityUsable(CityData city)
		{
			if ((Object)(object)Player.Instance == (Object)null)
			{
				return false;
			}
			if (city.citizenDictionary != null && city.citizenDictionary.Count > 0 && city.gameLocationDirectory != null)
			{
				return city.gameLocationDirectory.Count > 0;
			}
			return false;
		}

		private void BeginCity(CityData city)
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			_seed = (string.IsNullOrEmpty(city.seed) ? city.cityName : city.seed);
			_cityReady = true;
			_initialized = false;
			_initStage = 0;
			_deaths.Reset();
			_war.Initialize(_seed);
			_weapons.Begin(_seed);
			EnsureHud();
			Spectator.Cancel();
			_weaponIndex = 0;
			_wallHack = false;
			_weaponMenuOpen = false;
			_scoreboardDismissed = false;
			_investigationWarned = false;
			_scoreboardTimer = 0f;
			_lastAttacker.Clear();
			_lastAttackTime.Clear();
			RefreshWeaponLabel();
			Hud.SetHealVisible(visible: true);
			Hud.SetWeaponMenuVisible(visible: false);
			Hud.HideScoreboard();
			DisableMissions();
			SuppressInvestigations();
			Hud.ClearFeed();
			Hud.SetVisible(visible: true);
			Hud.SetHudVisible(ModConfig.ShowHud.Value);
			Hud.SetStatus("ANARCHY BEGINS", 6f);
			Hud.SetRespawnVisible(visible: false);
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Anarchy city started: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_seed);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", citizens=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(city.citizenDictionary.Count);
			}
			logger.LogInfo(val);
		}

		private void StepInitialization()
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			try
			{
				if (_initStage == 0)
				{
					_weapons.SpawnStreetWeapons(12);
					if (_weapons.StreetSpawnDone)
					{
						_initStage = 1;
					}
					return;
				}
				if (_initStage == 1)
				{
					if (ModConfig.ArmNpcs.Value)
					{
						_weapons.ArmNpcs(24);
					}
					if (!ModConfig.ArmNpcs.Value || _weapons.ArmingDone)
					{
						_initStage = 2;
					}
					return;
				}
				_weapons.Finish();
				RefreshWeaponLabel();
				_deaths.Scan(CityData.Instance, Hud, firstScan: true);
				_initialized = true;
				Hud.SetStatus("ANARCHY BEGINS", 6f);
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Anarchy init done: street weapons=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_weapons.SpawnedWeaponCount);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", armed NPCs=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_weapons.ArmedNpcCount);
				}
				logger.LogInfo(val);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Anarchy init: " + ex));
				_initialized = true;
			}
		}

		private static void DisableMissions()
		{
			try
			{
				MurderController instance = MurderController.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SetProcGenKillerLoop(false);
					instance.activeMurders?.Clear();
					instance.inactiveMurders?.Clear();
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("Disable murders: " + ex.Message));
			}
			try
			{
				SideJobController instance2 = SideJobController.Instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					instance2.enableJobs = false;
					instance2.allJobsDictionary?.Clear();
				}
			}
			catch (Exception ex2)
			{
				Plugin.Logger.LogWarning((object)("Disable side jobs: " + ex2.Message));
			}
			try
			{
				CasePanelController instance3 = CasePanelController.Instance;
				if (!((Object)(object)instance3 != (Object)null))
				{
					return;
				}
				if (instance3.activeCases != null)
				{
					Enumerator<Case> enumerator = instance3.activeCases.GetEnumerator();
					while (enumerator.MoveNext())
					{
						Case current = enumerator.Current;
						if (current != null)
						{
							current.ClearAllObjectives();
							current.isActive = false;
						}
					}
					instance3.activeCases.Clear();
				}
				instance3.activeCase = null;
				instance3.UpdateCaseControls();
			}
			catch (Exception ex3)
			{
				Plugin.Logger.LogWarning((object)("Disable detective cases: " + ex3.Message));
			}
		}

		private void SuppressInvestigations()
		{
			if (!Enabled)
			{
				return;
			}
			try
			{
				CasePanelController instance = CasePanelController.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					List<Case> activeCases = instance.activeCases;
					if (activeCases != null)
					{
						for (int i = 0; i < activeCases.Count; i++)
						{
							Case val = activeCases[i];
							if (val != null)
							{
								try
								{
									val.ClearAllObjectives();
									val.isActive = false;
								}
								catch
								{
								}
							}
						}
						if (activeCases.Count > 0)
						{
							activeCases.Clear();
						}
					}
					instance.activeCase = null;
					instance.archivedCases?.Clear();
					instance.UpdateCaseControls();
				}
			}
			catch (Exception ex)
			{
				WarnInvestigation("Disable case panel: " + ex.Message);
			}
			try
			{
				MurderController instance2 = MurderController.Instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					instance2.activeMurders?.Clear();
					instance2.inactiveMurders?.Clear();
				}
			}
			catch (Exception ex2)
			{
				WarnInvestigation("Disable murder cases: " + ex2.Message);
			}
			try
			{
				GameplayController instance3 = GameplayController.Instance;
				if (!((Object)(object)instance3 != (Object)null))
				{
					return;
				}
				HashSet<NewGameLocation> crimeScenes = instance3.crimeScenes;
				if (crimeScenes != null && crimeScenes.Count > 0)
				{
					List<NewGameLocation> list = new List<NewGameLocation>();
					Enumerator<NewGameLocation> enumerator = crimeScenes.GetEnumerator();
					while (enumerator.MoveNext())
					{
						NewGameLocation current = enumerator.Current;
						if ((Object)(object)current != (Object)null)
						{
							list.Add(current);
						}
					}
					for (int j = 0; j < list.Count; j++)
					{
						try
						{
							list[j].SetAsCrimeScene(false);
						}
						catch
						{
						}
					}
					crimeScenes.Clear();
				}
				instance3.crimeSceneCleanups?.Clear();
			}
			catch (Exception ex3)
			{
				WarnInvestigation("Clear crime scenes: " + ex3.Message);
			}
		}

		private void WarnInvestigation(string message)
		{
			if (!_investigationWarned)
			{
				_investigationWarned = true;
				Plugin.Logger.LogWarning((object)message);
			}
		}

		internal void OnPlayerZeroHealth(Player player)
		{
			if (Enabled && !((Object)(object)player == (Object)null))
			{
				EnsureHud();
				Spectator.Enter(player);
			}
		}

		internal void OnCityGenerationComplete()
		{
			_generationComplete = true;
			Plugin.Logger.LogInfo((object)"City generation complete; waiting for player");
		}

		internal void RespawnPlayer()
		{
			Spectator.Respawn();
		}

		private void HandleControls()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Player instance = Player.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				if (Input.GetKeyDown(ParseKey(ModConfig.HealKey.Value, (KeyCode)104)))
				{
					HealPlayer();
				}
				if (Input.GetKeyDown(ParseKey(ModConfig.FreeCamKey.Value, (KeyCode)118)))
				{
					Spectator.ToggleFreeCam(instance);
				}
				if (Input.GetKeyDown(ParseKey(ModConfig.WallHackKey.Value, (KeyCode)288)))
				{
					_wallHack = !_wallHack;
					Hud.SetStatus(_wallHack ? "WALLHACK ON" : "WALLHACK OFF", 2f);
				}
				if (Input.GetKeyDown(ParseKey(ModConfig.WeaponMenuKey.Value, (KeyCode)98)))
				{
					_weaponMenuOpen = !_weaponMenuOpen;
					Hud.SetWeaponMenuVisible(_weaponMenuOpen);
					Hud.SetStatus(_weaponMenuOpen ? "WEAPON MENU" : "WEAPON MENU CLOSED", 1.5f);
				}
			}
		}

		internal void HealPlayer()
		{
			Player instance = Player.Instance;
			if (!Enabled || (Object)(object)instance == (Object)null || ((Actor)instance).isDead)
			{
				return;
			}
			try
			{
				((Actor)instance).ResetHealthToMaximum();
				((Actor)instance).ResetNerveToMaximum();
				try
				{
					instance.ResetNegativeStatuses(1f);
				}
				catch
				{
				}
				try
				{
					((Human)instance).nourishment = 1f;
					((Human)instance).hydration = 1f;
					((Human)instance).alertness = 1f;
					((Human)instance).energy = 1f;
					((Human)instance).excitement = 0f;
					((Human)instance).hygiene = 1f;
					((Human)instance).bladder = 0f;
					((Human)instance).breath = 1f;
					((Human)instance).heat = 0.5f;
					((Human)instance).drunk = 0f;
					((Human)instance).sick = 0f;
					((Human)instance).headache = 0f;
					((Human)instance).wet = 0f;
					((Human)instance).brokenLeg = 0f;
					((Human)instance).bruised = 0f;
					((Human)instance).blackEye = 0f;
					((Human)instance).blackedOut = 0f;
					((Human)instance).numb = 0f;
					((Human)instance).poisoned = 0f;
					((Human)instance).bleeding = 0f;
					((Human)instance).starchAddiction = 0f;
					((Human)instance).blinded = 0f;
				}
				catch
				{
				}
				try
				{
					StatusController instance2 = StatusController.Instance;
					HashSet<StatusPreset> val = ((instance2 != null) ? instance2.activeStatuses : null);
					if (val != null)
					{
						List<StatusPreset> val2 = new List<StatusPreset>();
						Enumerator<StatusPreset> enumerator = val.GetEnumerator();
						while (enumerator.MoveNext())
						{
							StatusPreset current = enumerator.Current;
							val2.Add(current);
						}
						Enumerator<StatusPreset> enumerator2 = val2.GetEnumerator();
						while (enumerator2.MoveNext())
						{
							StatusPreset current2 = enumerator2.Current;
							instance2.RemoveAllCounts(current2);
						}
					}
				}
				catch
				{
				}
				Hud.SetStatus("FULLY HEALED", 3f);
				Plugin.Logger.LogInfo((object)"Player fully healed");
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("HealPlayer: " + ex));
			}
		}

		internal void CycleWeapon(int delta)
		{
			int num = _weapons?.PresetCount ?? 0;
			if (num <= 0)
			{
				Hud.SetStatus("NO WEAPONS AVAILABLE", 2f);
				return;
			}
			_weaponIndex = (_weaponIndex + delta) % num;
			if (_weaponIndex < 0)
			{
				_weaponIndex += num;
			}
			RefreshWeaponLabel();
		}

		internal void GiveSelectedWeapon()
		{
			Player instance = Player.Instance;
			if (_weapons != null && !((Object)(object)instance == (Object)null))
			{
				if (_weapons.GivePresetToPlayer(_weaponIndex, instance))
				{
					Hud.SetStatus("ADDED: " + _weapons.PresetName(_weaponIndex), 3f);
				}
				else
				{
					Hud.SetStatus("COULD NOT ADD WEAPON", 2f);
				}
			}
		}

		private void RefreshWeaponLabel()
		{
			Hud?.SetWeaponLabel(_weapons?.PresetName(_weaponIndex));
		}

		internal void DismissScoreboard()
		{
			_scoreboardDismissed = true;
			Hud?.HideScoreboard();
		}

		private void UpdateScoreboard(Player player)
		{
			_scoreboardTimer -= Time.deltaTime;
			if (_scoreboardTimer > 0f)
			{
				return;
			}
			_scoreboardTimer = 1f;
			SuppressInvestigations();
			if (!((Object)(object)player == (Object)null))
			{
				if (!((Actor)player).isDead && !Spectator.Active && _deaths.Alive > 1)
				{
					_scoreboardDismissed = false;
					Hud.HideScoreboard();
				}
				else if (!_scoreboardDismissed)
				{
					Hud.SetScoreboard(_deaths.GetTopScores(50));
				}
			}
		}

		private void OnGUI()
		{
			if (_wallHack && _initialized)
			{
				Camera val = Spectator?.ActiveCamera ?? Camera.main;
				if ((Object)(object)val != (Object)null)
				{
					WallHack.Draw(val);
				}
			}
		}

		private static KeyCode ParseKey(string value, KeyCode fallback)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (!Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result))
			{
				return fallback;
			}
			return result;
		}

		internal void RecordDamage(Human victim, Actor fromWho)
		{
			if (!Enabled || (Object)(object)victim == (Object)null || ((Actor)victim).isPlayer)
			{
				return;
			}
			try
			{
				Human val = null;
				if ((Object)(object)fromWho != (Object)null)
				{
					val = ((Il2CppObjectBase)fromWho).TryCast<Human>();
				}
				if (!((Object)(object)val == (Object)null) && val.humanID != victim.humanID)
				{
					_lastAttacker[victim.humanID] = val;
					_lastAttackTime[victim.humanID] = Time.time;
				}
			}
			catch
			{
			}
		}

		internal void KillKnockedOut(Human human)
		{
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			if (!Enabled || (Object)(object)human == (Object)null || _killingNpc)
			{
				return;
			}
			try
			{
				if (((Actor)human).isPlayer || ((Actor)human).isDead)
				{
					return;
				}
			}
			catch
			{
				return;
			}
			_killingNpc = true;
			try
			{
				Human val = null;
				try
				{
					if (_lastAttacker.TryGetValue(human.humanID, out var value) && (Object)(object)value != (Object)null && value.humanID != human.humanID && Time.time - _lastAttackTime[human.humanID] <= 30f)
					{
						val = value;
					}
				}
				catch
				{
				}
				MurderController instance = MurderController.Instance;
				if ((Object)(object)instance == (Object)null || (SoCustomComparison)(object)instance.murderPreset == (SoCustomComparison)null)
				{
					Plugin.Logger.LogWarning((object)("KillKnockedOut missing MurderController preset for " + human.humanID));
					return;
				}
				Interactable murderWeapon = GetMurderWeapon(human, val);
				if (murderWeapon == null)
				{
					Plugin.Logger.LogWarning((object)("KillKnockedOut missing weapon for " + human.humanID));
					return;
				}
				Human val2 = val ?? human;
				Murder val3 = new Murder(human, human, instance.murderPreset, new MurderMO(), (NewGameLocation)null);
				val3.victim = human;
				val3.victimID = human.humanID;
				val3.murderer = val2;
				val3.murdererID = val2.humanID;
				val3.weapon = murderWeapon;
				val3.weaponStr = (string.IsNullOrEmpty(murderWeapon.name) ? "Blunt Object" : murderWeapon.name);
				val3.weaponID = murderWeapon.id;
				val3.weaponPreset = murderWeapon.preset;
				try
				{
					if ((SoCustomComparison)(object)val3.weaponPreset != (SoCustomComparison)null && (SoCustomComparison)(object)val3.weaponPreset.weapon == (SoCustomComparison)null)
					{
						val3.weaponPreset.weapon = Resources.Load<MurderWeaponPreset>("data/weapons/bluntobjects/Dumbell");
					}
				}
				catch
				{
				}
				try
				{
					NewGameLocation currentGameLocation = ((Actor)human).currentGameLocation;
					if ((Object)(object)currentGameLocation != (Object)null)
					{
						val3.location = (NewGameLocation)(object)currentGameLocation.thisAsAddress;
					}
				}
				catch
				{
				}
				try
				{
					((Actor)human).currentHealth = 0f;
					((Actor)human).SetHealth(0f);
				}
				catch
				{
				}
				if (!((Actor)human).isDead)
				{
					human.Murder(val2, true, val3, murderWeapon, 0f);
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("KillKnockedOut murder: " + ex));
			}
			finally
			{
				_killingNpc = false;
			}
			try
			{
				if (!((Actor)human).isDead)
				{
					Plugin.Logger.LogWarning((object)("KillKnockedOut failed for " + human.humanID));
				}
			}
			catch
			{
			}
		}

		private static Interactable GetMurderWeapon(Human victim, Human killer)
		{
			//IL_0019: 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_0033: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			Interactable val = FindInventoryWeapon(victim);
			if (val != null)
			{
				return val;
			}
			val = FindInventoryWeapon(killer);
			if (val != null)
			{
				return val;
			}
			try
			{
				return new Interactable(new InteractablePreset
				{
					weapon = Resources.Load<MurderWeaponPreset>("data/weapons/bluntobjects/Dumbell")
				});
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("KillKnockedOut weapon: " + ex.Message));
				return null;
			}
		}

		private static Interactable FindInventoryWeapon(Human human)
		{
			if ((Object)(object)human == (Object)null)
			{
				return null;
			}
			try
			{
				List<Interactable> inventory = ((Actor)human).inventory;
				if (inventory == null)
				{
					return null;
				}
				for (int i = 0; i < inventory.Count; i++)
				{
					Interactable val = inventory[i];
					if (val == null)
					{
						continue;
					}
					try
					{
						if ((SoCustomComparison)(object)val.preset != (SoCustomComparison)null && (SoCustomComparison)(object)val.preset.weapon != (SoCustomComparison)null)
						{
							return val;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return null;
		}
	}
	internal sealed class DeathTracker
	{
		internal sealed class ScoreEntry
		{
			internal int Id;

			internal string Name;

			internal int Kills;

			internal bool IsPlayer;
		}

		private readonly HashSet<int> _knownDead = new HashSet<int>();

		private readonly HashSet<int> _credited = new HashSet<int>();

		private readonly Dictionary<int, ScoreEntry> _scores = new Dictionary<int, ScoreEntry>();

		private readonly Dictionary<int, Human> _pending = new Dictionary<int, Human>();

		private float _timer;

		internal int Alive { get; private set; }

		internal void Reset()
		{
			_knownDead.Clear();
			_credited.Clear();
			_scores.Clear();
			_pending.Clear();
			_timer = 0f;
			Alive = 0;
		}

		internal void Scan(CityData city, Hud hud, bool firstScan)
		{
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			_timer -= Time.deltaTime;
			if (_timer > 0f)
			{
				return;
			}
			_timer = 1f;
			if (((city != null) ? city.citizenDictionary : null) == null)
			{
				return;
			}
			int num = city.citizenDirectory?.Count ?? 0;
			List<Human> list = new List<Human>();
			try
			{
				Enumerator<int, Human> enumerator = city.citizenDictionary.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Human value = enumerator.Current.Value;
					if ((Object)(object)value == (Object)null || ((Actor)value).isPlayer || !((Actor)value).isDead)
					{
						continue;
					}
					if (_knownDead.Add(value.humanID))
					{
						if (!firstScan)
						{
							list.Add(value);
							_pending[value.humanID] = value;
						}
					}
					else if (!_credited.Contains(value.humanID))
					{
						_pending[value.humanID] = value;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("DeathTracker: " + ex.Message));
			}
			Alive = Math.Max(0, num - _knownDead.Count);
			hud.SetCounters(Alive, _knownDead.Count);
			foreach (Human item in new List<Human>(_pending.Values))
			{
				if (TryCreditKill(item))
				{
					_pending.Remove(item.humanID);
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				Human val = list[i];
				Human val2 = GetKiller(val);
				if ((Object)(object)val2 != (Object)null && val2.humanID == val.humanID)
				{
					val2 = null;
				}
				string line = (((Object)(object)val2 != (Object)null) ? ((((Actor)val2).isPlayer ? "YOU" : WarDirector.Name(val2)) + " killed " + WarDirector.Name(val)) : (WarDirector.Name(val) + " is killed"));
				hud.AddKill(line);
			}
			if (list.Count > 0)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(list.Count);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" new death(s)");
				}
				logger.LogInfo(val3);
			}
		}

		internal List<ScoreEntry> GetTopScores(int count)
		{
			List<ScoreEntry> list = new List<ScoreEntry>(_scores.Values);
			list.Sort(delegate(ScoreEntry a, ScoreEntry b)
			{
				int num = b.Kills.CompareTo(a.Kills);
				return (num == 0) ? string.Compare(a.Name, b.Name, StringComparison.Ordinal) : num;
			});
			if (list.Count > count)
			{
				list.RemoveRange(count, list.Count - count);
			}
			return list;
		}

		private bool TryCreditKill(Human victim)
		{
			if ((Object)(object)victim == (Object)null)
			{
				return true;
			}
			if (_credited.Contains(victim.humanID))
			{
				return true;
			}
			Human killer = GetKiller(victim);
			if ((Object)(object)killer == (Object)null || killer.humanID == victim.humanID)
			{
				return false;
			}
			_credited.Add(victim.humanID);
			if (!_scores.TryGetValue(killer.humanID, out var value))
			{
				value = new ScoreEntry
				{
					Id = killer.humanID,
					Name = (((Actor)killer).isPlayer ? "YOU" : WarDirector.Name(killer)),
					IsPlayer = ((Actor)killer).isPlayer
				};
				_scores[killer.humanID] = value;
			}
			value.Kills++;
			return true;
		}

		private static Human GetKiller(Human victim)
		{
			try
			{
				Death obj = ((victim != null) ? victim.death : null);
				return (obj != null) ? obj.GetKiller() : null;
			}
			catch
			{
				return null;
			}
		}
	}
	internal sealed class Hud
	{
		private sealed class FeedLine
		{
			internal string Text;

			internal float Life;
		}

		private readonly Font _font;

		private readonly List<FeedLine> _feed = new List<FeedLine>();

		private GameObject _root;

		private Text _counters;

		private Text _feedText;

		private Text _status;

		private Text _hint;

		private GameObject _respawnButton;

		private GameObject _healButton;

		private GameObject _weaponPanel;

		private Text _weaponLabel;

		private bool _weaponMenuOpen;

		private bool _hudVisible = true;

		private GameObject _scoreboardPanel;

		private Text _scoreboardTitle;

		private Text _scoreboardLeft;

		private Text _scoreboardRight;

		private float _statusTimer;

		internal bool IsAlive
		{
			get
			{
				try
				{
					return (Object)(object)_root != (Object)null;
				}
				catch
				{
					return false;
				}
			}
		}

		internal Hud()
		{
			_font = LoadFont();
			Build();
		}

		private static Font LoadFont()
		{
			Font val = null;
			try
			{
				val = Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				try
				{
					val = Font.CreateDynamicFontFromOSFont(Il2CppStringArray.op_Implicit(new string[2] { "Segoe UI", "Arial" }), 16);
				}
				catch
				{
				}
			}
			return val;
		}

		private void Build()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0054: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			_root = new GameObject("AnarchyModeCanvas");
			Object.DontDestroyOnLoad((Object)(object)_root);
			Canvas obj = _root.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 2000;
			CanvasScaler obj2 = _root.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 0.5f;
			_root.AddComponent<GraphicRaycaster>();
			_counters = NewText("Counters", 24, Color.white, (TextAnchor)0);
			RectTransform rectTransform = ((Graphic)_counters).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.anchoredPosition = new Vector2(22f, -20f);
			rectTransform.sizeDelta = new Vector2(700f, 90f);
			_counters.text = "ANARCHY MODE\nALIVE 0    DEAD 0";
			_status = NewText("Status", 24, new Color(1f, 0.85f, 0.4f, 1f), (TextAnchor)1);
			RectTransform rectTransform2 = ((Graphic)_status).rectTransform;
			rectTransform2.anchorMin = new Vector2(0.5f, 1f);
			rectTransform2.anchorMax = new Vector2(0.5f, 1f);
			rectTransform2.pivot = new Vector2(0.5f, 1f);
			rectTransform2.anchoredPosition = new Vector2(0f, -28f);
			rectTransform2.sizeDelta = new Vector2(1100f, 48f);
			_status.text = "";
			_feedText = NewText("KillFeed", 19, Color.white, (TextAnchor)6);
			RectTransform rectTransform3 = ((Graphic)_feedText).rectTransform;
			rectTransform3.anchorMin = new Vector2(0f, 0f);
			rectTransform3.anchorMax = new Vector2(0f, 0f);
			rectTransform3.pivot = new Vector2(0f, 0f);
			rectTransform3.anchoredPosition = new Vector2(22f, 22f);
			rectTransform3.sizeDelta = new Vector2(900f, 300f);
			_feedText.text = "";
			_hint = NewText("ControlsHint", 17, new Color(0.82f, 0.86f, 0.95f, 1f), (TextAnchor)7);
			RectTransform rectTransform4 = ((Graphic)_hint).rectTransform;
			rectTransform4.anchorMin = new Vector2(0.5f, 0f);
			rectTransform4.anchorMax = new Vector2(0.5f, 0f);
			rectTransform4.pivot = new Vector2(0.5f, 0f);
			rectTransform4.anchoredPosition = new Vector2(0f, 18f);
			rectTransform4.sizeDelta = new Vector2(1300f, 30f);
			_hint.text = "V: FREECAM    H: FULL HEAL    B: WEAPONS    F7: WALLHACK    F5: SURFACE    F: PLACE HERE";
			BuildHealButton();
			BuildWeaponSelector();
			BuildRespawnButton();
			BuildScoreboard();
			_root.SetActive(false);
		}

		private void BuildRespawnButton()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_004d: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			_respawnButton = new GameObject("RespawnButton");
			_respawnButton.transform.SetParent(_root.transform, false);
			Image val = _respawnButton.AddComponent<Image>();
			((Graphic)val).color = new Color(0.45f, 0.06f, 0.06f, 0.95f);
			((Graphic)val).raycastTarget = true;
			Button obj = _respawnButton.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val;
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				AnarchyBehaviour.Instance?.RespawnPlayer();
			}));
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 0f);
			rectTransform.anchorMax = new Vector2(0.5f, 0f);
			rectTransform.pivot = new Vector2(0.5f, 0f);
			rectTransform.anchoredPosition = new Vector2(0f, 110f);
			rectTransform.sizeDelta = new Vector2(320f, 62f);
			GameObject val2 = new GameObject("Label");
			val2.transform.SetParent(_respawnButton.transform, false);
			Text obj2 = val2.AddComponent<Text>();
			obj2.font = _font;
			obj2.fontSize = 26;
			obj2.alignment = (TextAnchor)4;
			((Graphic)obj2).color = Color.white;
			((Graphic)obj2).raycastTarget = false;
			obj2.text = "RESPAWN";
			RectTransform rectTransform2 = ((Graphic)obj2).rectTransform;
			rectTransform2.anchorMin = Vector2.zero;
			rectTransform2.anchorMax = Vector2.one;
			rectTransform2.offsetMin = Vector2.zero;
			rectTransform2.offsetMax = Vector2.zero;
			_respawnButton.SetActive(false);
		}

		private void BuildHealButton()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			_healButton = NewButton("HealButton", "HEAL", new Color(0.08f, 0.42f, 0.16f, 0.95f), _root.transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-22f, 22f), new Vector2(190f, 54f), delegate
			{
				AnarchyBehaviour.Instance?.HealPlayer();
			});
		}

		private void BuildWeaponSelector()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_004c: 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_0097: 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_00c0: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: 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_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			_weaponPanel = new GameObject("WeaponSelector");
			_weaponPanel.transform.SetParent(_root.transform, false);
			Image obj = _weaponPanel.AddComponent<Image>();
			((Graphic)obj).color = new Color(0.03f, 0.03f, 0.04f, 0.88f);
			((Graphic)obj).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.anchorMin = new Vector2(1f, 0.5f);
			rectTransform.anchorMax = new Vector2(1f, 0.5f);
			rectTransform.pivot = new Vector2(1f, 0.5f);
			rectTransform.anchoredPosition = new Vector2(-22f, 0f);
			rectTransform.sizeDelta = new Vector2(420f, 150f);
			Text obj2 = NewText("WeaponTitle", 22, new Color(1f, 0.85f, 0.4f, 1f), (TextAnchor)4);
			((Component)obj2).transform.SetParent(_weaponPanel.transform, false);
			RectTransform rectTransform2 = ((Graphic)obj2).rectTransform;
			rectTransform2.anchorMin = new Vector2(0f, 1f);
			rectTransform2.anchorMax = new Vector2(1f, 1f);
			rectTransform2.pivot = new Vector2(0.5f, 1f);
			rectTransform2.anchoredPosition = new Vector2(0f, -8f);
			rectTransform2.sizeDelta = new Vector2(-16f, 32f);
			obj2.text = "WEAPON SELECT";
			_weaponLabel = NewText("WeaponName", 19, Color.white, (TextAnchor)4);
			((Component)_weaponLabel).transform.SetParent(_weaponPanel.transform, false);
			RectTransform rectTransform3 = ((Graphic)_weaponLabel).rectTransform;
			rectTransform3.anchorMin = new Vector2(0f, 1f);
			rectTransform3.anchorMax = new Vector2(1f, 1f);
			rectTransform3.pivot = new Vector2(0.5f, 1f);
			rectTransform3.anchoredPosition = new Vector2(0f, -46f);
			rectTransform3.sizeDelta = new Vector2(-16f, 34f);
			_weaponLabel.text = "WEAPON: ...";
			NewButton("PrevWeapon", "<", new Color(0.18f, 0.18f, 0.22f, 0.95f), _weaponPanel.transform, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(10f, 10f), new Vector2(42f, 40f), delegate
			{
				AnarchyBehaviour.Instance?.CycleWeapon(-1);
			});
			NewButton("GiveWeapon", "ADD TO INVENTORY", new Color(0.18f, 0.3f, 0.5f, 0.95f), _weaponPanel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 10f), new Vector2(230f, 40f), delegate
			{
				AnarchyBehaviour.Instance?.GiveSelectedWeapon();
			});
			NewButton("NextWeapon", ">", new Color(0.18f, 0.18f, 0.22f, 0.95f), _weaponPanel.transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-10f, 10f), new Vector2(42f, 40f), delegate
			{
				AnarchyBehaviour.Instance?.CycleWeapon(1);
			});
			_weaponPanel.SetActive(false);
		}

		private void BuildScoreboard()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_004c: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			_scoreboardPanel = new GameObject("Scoreboard");
			_scoreboardPanel.transform.SetParent(_root.transform, false);
			Image obj = _scoreboardPanel.AddComponent<Image>();
			((Graphic)obj).color = new Color(0.015f, 0.015f, 0.025f, 0.94f);
			((Graphic)obj).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
			rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = Vector2.zero;
			rectTransform.sizeDelta = new Vector2(980f, 820f);
			_scoreboardTitle = NewText("ScoreboardTitle", 30, new Color(1f, 0.85f, 0.35f, 1f), (TextAnchor)1);
			((Component)_scoreboardTitle).transform.SetParent(_scoreboardPanel.transform, false);
			RectTransform rectTransform2 = ((Graphic)_scoreboardTitle).rectTransform;
			rectTransform2.anchorMin = new Vector2(0f, 1f);
			rectTransform2.anchorMax = new Vector2(1f, 1f);
			rectTransform2.pivot = new Vector2(0.5f, 1f);
			rectTransform2.anchoredPosition = new Vector2(0f, -12f);
			rectTransform2.sizeDelta = new Vector2(-20f, 42f);
			_scoreboardTitle.text = "TOP 50 - KILLS";
			NewButton("CloseScoreboard", "X", new Color(0.5f, 0.08f, 0.08f, 0.95f), _scoreboardPanel.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-12f, -10f), new Vector2(42f, 34f), delegate
			{
				AnarchyBehaviour.Instance?.DismissScoreboard();
			});
			_scoreboardLeft = ScoreColumn("ScoreboardLeft", new Vector2(0f, 0f), new Vector2(0.5f, 1f), new Vector2(18f, 16f), new Vector2(-9f, -58f));
			_scoreboardRight = ScoreColumn("ScoreboardRight", new Vector2(0.5f, 0f), new Vector2(1f, 1f), new Vector2(9f, 16f), new Vector2(-18f, -58f));
			_scoreboardPanel.SetActive(false);
		}

		private Text ScoreColumn(string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0004: 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)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			Text obj = NewText(name, 18, Color.white, (TextAnchor)0);
			((Component)obj).transform.SetParent(_scoreboardPanel.transform, false);
			obj.lineSpacing = 1.05f;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.anchorMin = anchorMin;
			rectTransform.anchorMax = anchorMax;
			rectTransform.offsetMin = offsetMin;
			rectTransform.offsetMax = offsetMax;
			return obj;
		}

		private GameObject NewButton(string name, string labelText, Color color, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 position, Vector2 size, Action onClick)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_002b: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = color;
			((Graphic)val2).raycastTarget = true;
			Button obj = val.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val2;
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				onClick();
			}));
			RectTransform rectTransform = ((Graphic)val2).rectTransform;
			rectTransform.anchorMin = anchorMin;
			rectTransform.anchorMax = anchorMax;
			rectTransform.pivot = anchorMin;
			rectTransform.anchoredPosition = position;
			rectTransform.sizeDelta = size;
			GameObject val3 = new GameObject("Label");
			val3.transform.SetParent(val.transform, false);
			Text obj2 = val3.AddComponent<Text>();
			obj2.font = _font;
			obj2.fontSize = 18;
			obj2.alignment = (TextAnchor)4;
			((Graphic)obj2).color = Color.white;
			((Graphic)obj2).raycastTarget = false;
			obj2.text = labelText;
			RectTransform rectTransform2 = ((Graphic)obj2).rectTransform;
			rectTransform2.anchorMin = Vector2.zero;
			rectTransform2.anchorMax = Vector2.one;
			rectTransform2.offsetMin = Vector2.zero;
			rectTransform2.offsetMax = Vector2.zero;
			return val;
		}

		internal void SetHealVisible(bool visible)
		{
			if (IsAlive && !((Object)(object)_healButton == (Object)null))
			{
				_healButton.SetActive(visible);
			}
		}

		internal void SetWeaponLabel(string text)
		{
			if (IsAlive && (Object)(object)_weaponLabel != (Object)null)
			{
				_weaponLabel.text = "WEAPON: " + (string.IsNullOrEmpty(text) ? "..." : text);
			}
		}

		internal void SetWeaponMenuVisible(bool visible)
		{
			_weaponMenuOpen = visible;
			if (IsAlive && !((Object)(object)_weaponPanel == (Object)null))
			{
				_weaponPanel.SetActive(visible && _hudVisible);
			}
		}

		internal void SetScoreboard(List<DeathTracker.ScoreEntry> entries)
		{
			if (!IsAlive || (Object)(object)_scoreboardPanel == (Object)null)
			{
				return;
			}
			if (entries == null || entries.Count == 0)
			{
				_scoreboardLeft.text = "NO KILLS RECORDED";
				_scoreboardRight.text = "";
				_scoreboardPanel.SetActive(true);
				return;
			}
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			for (int i = 0; i < entries.Count; i++)
			{
				DeathTracker.ScoreEntry scoreEntry = entries[i];
				string item = $"{i + 1}. {scoreEntry.Name} - {scoreEntry.Kills}";
				if (i < 25)
				{
					list.Add(item);
				}
				else
				{
					list2.Add(item);
				}
			}
			_scoreboardLeft.text = string.Join("\n", list);
			_scoreboardRight.text = string.Join("\n", list2);
			_scoreboardPanel.SetActive(true);
		}

		internal void HideScoreboard()
		{
			if (IsAlive && (Object)(object)_scoreboardPanel != (Object)null)
			{
				_scoreboardPanel.SetActive(false);
			}
		}

		private Text NewText(string name, int size, Color color, TextAnchor align)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(_root.transform, false);
			Text obj = val.AddComponent<Text>();
			obj.font = _font;
			obj.fontSize = size;
			((Graphic)obj).color = color;
			obj.alignment = align;
			obj.horizontalOverflow = (HorizontalWrapMode)1;
			obj.verticalOverflow = (VerticalWrapMode)1;
			((Graphic)obj).raycastTarget = false;
			Outline obj2 = val.AddComponent<Outline>();
			((Shadow)obj2).effectColor = new Color(0f, 0f, 0f, 0.85f);
			((Shadow)obj2).effectDistance = new Vector2(1f, -1f);
			return obj;
		}

		internal void SetCounters(int alive, int dead)
		{
			if (IsAlive && !((Object)(object)_counters == (Object)null))
			{
				_counters.text = $"ANARCHY MODE\nALIVE {alive}    DEAD {dead}";
			}
		}

		internal void AddKill(string line)
		{
			if (!string.IsNullOrEmpty(line) && IsAlive)
			{
				_feed.Add(new FeedLine
				{
					Text = line,
					Life = ModConfig.KillFeedSeconds.Value
				});
				while (_feed.Count > 8)
				{
					_feed.RemoveAt(0);
				}
				RebuildFeed();
			}
		}

		internal void SetStatus(string text, float seconds = 4f)
		{
			if (IsAlive && !((Object)(object)_status == (Object)null))
			{
				_status.text = text ?? "";
				_statusTimer = seconds;
			}
		}

		internal void SetRespawnVisible(bool visible)
		{
			if (IsAlive && !((Object)(object)_respawnButton == (Object)null))
			{
				_respawnButton.SetActive(visible);
			}
		}

		internal void SetVisible(bool visible)
		{
			if (!IsAlive)
			{
				return;
			}
			try
			{
				if (_root.activeSelf != visible)
				{
					_root.SetActive(visible);
				}
			}
			catch
			{
			}
		}

		internal void SetHudVisible(bool visible)
		{
			if (IsAlive)
			{
				_hudVisible = visible;
				if ((Object)(object)_counters != (Object)null)
				{
					((Component)_counters).gameObject.SetActive(visible);
				}
				if ((Object)(object)_feedText != (Object)null)
				{
					((Component)_feedText).gameObject.SetActive(visible);
				}
				if ((Object)(object)_status != (Object)null)
				{
					((Component)_status).gameObject.SetActive(visible);
				}
				if ((Object)(object)_hint != (Object)null)
				{
					((Component)_hint).gameObject.SetActive(visible);
				}
				if ((Object)(object)_healButton != (Object)null)
				{
					_healButton.SetActive(visible);
				}
				if ((Object)(object)_weaponPanel != (Object)null)
				{
					_weaponPanel.SetActive(visible && _weaponMenuOpen);
				}
				if ((Object)(object)_scoreboardPanel != (Object)null && !visible)
				{
					_scoreboardPanel.SetActive(false);
				}
			}
		}

		internal void ClearFeed()
		{
			_feed.Clear();
			if (IsAlive)
			{
				if ((Object)(object)_feedText != (Object)null)
				{
					_feedText.text = "";
				}
				if ((Object)(object)_status != (Object)null)
				{
					_status.text = "";
				}
				_statusTimer = 0f;
				HideScoreboard();
			}
		}

		internal void Tick(float dt)
		{
			if (!IsAlive)
			{
				return;
			}
			if (_statusTimer > 0f)
			{
				_statusTimer -= dt;
				if (_statusTimer <= 0f)
				{
					_status.text = "";
				}
			}
			if (_feed.Count == 0)
			{
				return;
			}
			bool flag = false;
			for (int num = _feed.Count - 1; num >= 0; num--)
			{
				_feed[num].Life -= dt;
				if (_feed[num].Life <= 0f)
				{
					_feed.RemoveAt(num);
					flag = true;
				}
			}
			if (flag)
			{
				RebuildFeed();
			}
		}

		private void RebuildFeed()
		{
			if (_feed.Count == 0)
			{
				_feedText.text = "";
				return;
			}
			string[] array = new string[_feed.Count];
			for (int i = 0; i < _feed.Count; i++)
			{
				array[i] = _feed[i].Text;
			}
			_feedText.text = string.Join("\n", array);
		}
	}
	internal static class ModConfig
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<int> StreetWeaponCount;

		internal static ConfigEntry<bool> ArmNpcs;

		internal static ConfigEntry<float> ArmChance;

		internal static ConfigEntry<int> MaxNpcsToArm;

		internal static ConfigEntry<float> AggressionInterval;

		internal static ConfigEntry<float> ScanRadius;

		internal static ConfigEntry<float> AttackRadius;

		internal static ConfigEntry<int> MaxAttackersPerTick;

		internal static ConfigEntry<float> BraveryMin;

		internal static ConfigEntry<float> BraveryMax;

		internal static ConfigEntry<float> DoorUnlockDelay;

		internal static ConfigEntry<bool> ShowHud;

		internal static ConfigEntry<float> KillFeedSeconds;

		internal static ConfigEntry<bool> DisableRoutineGoals;

		internal static ConfigEntry<bool> AutoStartTestCity;

		internal static ConfigEntry<int> CityWidth;

		internal static ConfigEntry<int> CityHeight;

		internal static ConfigEntry<string> RespawnKey;

		internal static ConfigEntry<string> RespawnHereKey;

		internal static ConfigEntry<string> HealKey;

		internal static ConfigEntry<string> FreeCamKey;

		internal static ConfigEntry<string> WallHackKey;

		internal static ConfigEntry<string> WeaponMenuKey;

		internal static void Init(ConfigFile config)
		{
			Enabled = config.Bind<bool>("General", "Enabled", true, "Turn the anarchy simulation on or off.");
			ShowHud = config.Bind<bool>("General", "ShowHud", true, "Show the anarchy HUD.");
			KillFeedSeconds = config.Bind<float>("General", "KillFeedSeconds", 12f, "How long kill notifications stay on screen.");
			DisableRoutineGoals = config.Bind<bool>("General", "DisableRoutineGoals", false, "Stop NPCs from generating normal work routines.");
			AutoStartTestCity = config.Bind<bool>("Debug", "AutoStartTestCity", false, "Generate a new city automatically after the main menu loads. For testing only.");
			CityWidth = config.Bind<int>("City", "Width", 2, "City width in blocks. 2 means a 2x2 city. Requires DensityMod for sizes below vanilla limits.");
			CityHeight = config.Bind<int>("City", "Height", 2, "City height in blocks. 2 means a 2x2 city. Requires DensityMod for sizes below vanilla limits.");
			RespawnKey = config.Bind<string>("Respawn", "RespawnKey", "F5", "Key to respawn on the surface.");
			RespawnHereKey = config.Bind<string>("Respawn", "RespawnHereKey", "F", "Key to respawn at the spectator camera position.");
			HealKey = config.Bind<string>("Controls", "HealKey", "H", "Key to fully heal the player.");
			FreeCamKey = config.Bind<string>("Controls", "FreeCamKey", "V", "Key to toggle free camera.");
			WallHackKey = config.Bind<string>("Controls", "WallHackKey", "F7", "Key to toggle NPC wallhack markers.");
			WeaponMenuKey = config.Bind<string>("Controls", "WeaponMenuKey", "B", "Key to open the weapon selection menu.");
			if (string.Equals(WallHackKey.Value, "X", StringComparison.OrdinalIgnoreCase))
			{
				WallHackKey.Value = "F7";
			}
			StreetWeaponCount = config.Bind<int>("Weapons", "StreetWeaponCount", 300, "How many weapons to scatter on the streets when a city loads.");
			ArmNpcs = config.Bind<bool>("Weapons", "ArmNpcs", true, "Try to give every NPC a weapon when the city loads.");
			ArmChance = config.Bind<float>("Weapons", "ArmChance", 1f, "Chance for an NPC to be armed (0..1).");
			MaxNpcsToArm = config.Bind<int>("Weapons", "MaxNpcsToArm", 2000, "Safety cap for how many NPCs to arm at city load.");
			AggressionInterval = config.Bind<float>("Combat", "AggressionInterval", 0.5f, "Seconds between aggression ticks.");
			ScanRadius = config.Bind<float>("Combat", "ScanRadius", 120f, "Only NPCs within this distance of the player are managed.");
			AttackRadius = config.Bind<float>("Combat", "AttackRadius", 55f, "How far an NPC will look for a victim.");
			MaxAttackersPerTick = config.Bind<int>("Combat", "MaxAttackersPerTick", 30, "Maximum number of new attacks started per tick.");
			BraveryMin = config.Bind<float>("Combat", "BraveryMin", 0.15f, "Minimum deterministic bravery.");
			BraveryMax = config.Bind<float>("Combat", "BraveryMax", 0.95f, "Maximum deterministic bravery.");
			DoorUnlockDelay = config.Bind<float>("Combat", "DoorUnlockDelay", 1.5f, "Delay before an NPC forces a locked door.");
		}
	}
	[HarmonyPatch(typeof(Player), "OnZeroHealthReached")]
	internal static class PlayerDeathPatch
	{
		private static bool Prefix(Player __instance)
		{
			AnarchyBehaviour instance = AnarchyBehaviour.Instance;
			if ((Object)(object)instance == (Object)null || !instance.Enabled)
			{
				return true;
			}
			instance.OnPlayerZeroHealth(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(Citizen), "RecieveDamage")]
	internal static class CitizenDamagePatch
	{
		private static void Postfix(Citizen __instance, Actor fromWho)
		{
			AnarchyBehaviour.Instance?.RecordDamage((Human)(object)__instance, fromWho);
		}
	}
	[HarmonyPatch(typeof(Human), "GenerateRoutineGoals")]
	internal static class NoRoutineGoalsPatch
	{
		private static bool Prefix()
		{
			AnarchyBehaviour instance = AnarchyBehaviour.Instance;
			if ((Object)(object)instance == (Object)null || !instance.Enabled)
			{
				return true;
			}
			return !(ModConfig.DisableRoutineGoals?.Value ?? false);
		}
	}
	[HarmonyPatch(typeof(StatusController), "Pursued")]
	internal static class NoPursuedStatusPatch
	{
		private static bool Prefix()
		{
			return !(AnarchyBehaviour.Instance?.Enabled ?? false);
		}
	}
	[HarmonyPatch(typeof(NewAIController), "TriggerReactionIndicator")]
	internal static class NoReactionIndicatorPatch
	{
		private static bool Prefix()
		{
			return !(AnarchyBehaviour.Instance?.Enabled ?? false);
		}
	}
	[HarmonyPatch(typeof(MainMenuController), "SelectGenNewCity")]
	internal static class CitySizePatch
	{
		private static void Postfix()
		{
			AnarchyBehaviour.Instance?.ApplyCitySize();
		}
	}
	[HarmonyPatch(typeof(CityConstructor), "TriggerStartEvent")]
	internal static class CityGenerationCompletePatch
	{
		private static void Postfix()
		{
			AnarchyBehaviour.Instance?.OnCityGenerationComplete();
		}
	}
	[HarmonyPatch(typeof(NewAIController), "SetKO")]
	internal static class KillOnKnockoutPatch
	{
		private static void Postfix(NewAIController __instance, bool val)
		{
			if (val)
			{
				AnarchyBehaviour.Instance?.KillKnockedOut(__instance.human);
			}
		}
	}
	[HarmonyPatch(typeof(NewAIController), "SetStunned")]
	internal static class KillOnStunPatch
	{
		private static void Postfix(NewAIController __instance, bool val)
		{
			if (val)
			{
				AnarchyBehaviour.Instance?.KillKnockedOut(__instance.human);
			}
		}
	}
	[HarmonyPatch(typeof(GameplayController), "NewMurderCaseNotify")]
	internal static class NoNewMurderCasePatch
	{
		private static bool Prefix()
		{
			return !(AnarchyBehaviour.Instance?.Enabled ?? false);
		}
	}
	[HarmonyPatch(typeof(MurderController), "OnVictimDiscovery")]
	internal static class NoVictimDiscoveryPatch
	{
		private static bool Prefix()
		{
			return !(AnarchyBehaviour.Instance?.Enabled ?? false);
		}
	}
	[HarmonyPatch(typeof(MurderController), "AssignActiveCase")]
	internal static class NoAssignActiveCasePatch
	{
		private static bool Prefix()
		{
			return !(AnarchyBehaviour.Instance?.Enabled ?? false);
		}
	}
	[HarmonyPatch(typeof(CasePanelController), "SetActiveCase")]
	internal static class NoSetActiveCasePatch
	{
		private static bool Prefix()
		{
			return !(AnarchyBehaviour.Instance?.Enabled ?? false);
		}
	}
	[HarmonyPatch(typeof(InterfaceController), "NewMurderCaseDisplay")]
	internal static class NoNewMurderCaseDisplayPatch
	{
		private static bool Prefix()
		{
			return !(AnarchyBehaviour.Instance?.Enabled ?? false);
		}
	}
	[HarmonyPatch(typeof(NewGameLocation), "SetAsCrimeScene")]
	internal static class NoCrimeScenePatch
	{
		private static bool Prefix(bool val)
		{
			if (val)
			{
				return !(AnarchyBehaviour.Instance?.Enabled ?? false);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Toolbox), "Shoot")]
	internal static class NoBrassSpawnPatch
	{
		private static void Prefix(ref bool ejectBrass, ref bool forcePhysicsEjectBrass)
		{
			AnarchyBehaviour instance = AnarchyBehaviour.Instance;
			if (instance != null && instance.Enabled)
			{
				ejectBrass = false;
				forcePhysicsEjectBrass = false;
			}
		}
	}
	[BepInPlugin("com.avs.anarchymode", "Anarchy Mode", "0.1.1")]
	public class Plugin : BasePlugin
	{
		public const string Guid = "com.avs.anarchymode";

		public static ManualLogSource Logger;

		public override void Load()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BasePlugin)this).Log;
			((BasePlugin)this).Log.LogInfo((object)"Anarchy Mode: loading");
			ModConfig.Init(((BasePlugin)this).Config);
			ClassInjector.RegisterTypeInIl2Cpp<AnarchyBehaviour>();
			GameObject val = new GameObject("AnarchyMode")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<AnarchyBehaviour>();
			new Harmony("com.avs.anarchymode").PatchAll();
			((BasePlugin)this).Log.LogInfo((object)"Anarchy Mode: loaded");
		}
	}
	internal sealed class SpectatorMode
	{
		private readonly Hud _hud;

		private readonly Random _rng = new Random();

		private GameObject _cameraObject;

		private Camera _camera;

		private Camera _mainCamera;

		private Player _player;

		private float _yaw;

		private float _pitch;

		private bool _hadMainCamera;

		internal bool Active { get; private set; }

		internal bool FreeCam { get; private set; }

		internal Camera ActiveCamera
		{
			get
			{
				if (!((Object)(object)_camera != (Object)null))
				{
					return Camera.main;
				}
				return _camera;
			}
		}

		internal SpectatorMode(Hud hud)
		{
			_hud = hud;
		}

		internal void Enter(Player player)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (!Active && !((Object)(object)player == (Object)null))
			{
				if (FreeCam)
				{
					ExitFreeCam();
				}
				Active = true;
				_player = player;
				try
				{
					((Actor)player).isDead = false;
					((Actor)player).ResetHealthToMaximum();
					((Actor)player).ResetNerveToMaximum();
					player.EnablePlayerMovement(false, true);
					player.EnablePlayerMouseLook(false, false);
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogWarning((object)("Spectator player setup: " + ex.Message));
				}
				CreateCamera(((Component)player).transform.position + Vector3.up * 2.5f, ((Component)player).transform.eulerAngles.y);
				_hud.SetRespawnVisible(visible: true);
				_hud.SetHealVisible(visible: false);
				_hud.SetStatus("YOU ARE DEAD - F5: SURFACE | F: PLACE HERE | RMB: LOOK", 999f);
				Plugin.Logger.LogInfo((object)"Spectator mode entered");
			}
		}

		internal void ToggleFreeCam(Player player)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			if (Active)
			{
				return;
			}
			if (FreeCam)
			{
				ExitFreeCam();
			}
			else if (!((Object)(object)player == (Object)null) && !((Actor)player).isDead)
			{
				FreeCam = true;
				_player = player;
				try
				{
					player.EnablePlayerMovement(false, true);
					player.EnablePlayerMouseLook(false, false);
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogWarning((object)("FreeCam player setup: " + ex.Message));
				}
				CreateCamera(((Component)player).transform.position + Vector3.up * 1.7f, ((Component)player).transform.eulerAngles.y);
				_hud.SetRespawnVisible(visible: false);
				_hud.SetHealVisible(visible: true);
				_hud.SetStatus("FREECAM - V: EXIT | WASD: MOVE | SPACE/CTRL: UP/DOWN | RMB: LOOK", 999f);
				Plugin.Logger.LogInfo((object)"FreeCam entered");
			}
		}

		internal void Update(float dt)
		{
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: 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_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			if ((!Active && !FreeCam) || (Object)(object)_cameraObject == (Object)null)
			{
				return;
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			if (Active)
			{
				if (Input.GetKeyDown(ParseKey(ModConfig.RespawnKey.Value, (KeyCode)286)))
				{
					Respawn(null);
					return;
				}
				if (Input.GetKeyDown(ParseKey(ModConfig.RespawnHereKey.Value, (KeyCode)102)))
				{
					Respawn(_cameraObject.transform.position);
					return;
				}
				if ((Object)(object)_player != (Object)null)
				{
					try
					{
						if (((Actor)_player).currentHealth < 1f || ((Actor)_player).isDead)
						{
							((Actor)_player).isDead = false;
							((Actor)_player).ResetHealthToMaximum();
						}
					}
					catch
					{
					}
				}
			}
			if (Input.GetMouseButton(1))
			{
				_yaw += Input.GetAxis("Mouse X") * 3.2f;
				_pitch -= Input.GetAxis("Mouse Y") * 3.2f;
				_pitch = Mathf.Clamp(_pitch, -85f, 85f);
			}
			_cameraObject.transform.rotation = Quaternion.Euler(_pitch, _yaw, 0f);
			Vector3 val = Quaternion.Euler(_pitch, _yaw, 0f) * Vector3.forward;
			Vector3 val2 = Quaternion.Euler(0f, _yaw, 0f) * Vector3.right;
			Vector3 val3 = val * Input.GetAxisRaw("Vertical") + val2 * Input.GetAxisRaw("Horizontal");
			if (Input.GetKey((KeyCode)32))
			{
				val3 += Vector3.up;
			}
			if (Input.GetKey((KeyCode)306))
			{
				val3 += Vector3.down;
			}
			if (((Vector3)(ref val3)).sqrMagnitude > 0.001f)
			{
				float num = (Input.GetKey((KeyCode)304) ? 45f : 13f);
				Transform transform = _cameraObject.transform;
				transform.position += ((Vector3)(ref val3)).normalized * (num * unscaledDeltaTime);
			}
		}

		internal void Respawn()
		{
			Respawn(null);
		}

		private void Respawn(Vector3? atPosition)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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)
			if (Active && !((Object)(object)_player == (Object)null))
			{
				try
				{
					Vector3 val = (atPosition.HasValue ? SnapToGround(atPosition.Value) : FindSpawnPosition());
					((Actor)_player).isDead = false;
					((Actor)_player).ResetHealthToMaximum();
					((Actor)_player).ResetNerveToMaximum();
					_player.SetPosition(val, Quaternion.Euler(0f, (float)_rng.NextDouble() * 360f, 0f));
					_player.EnablePlayerMovement(true, true);
					_player.EnablePlayerMouseLook(true, false);
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)("Respawn: " + ex));
				}
				DestroyCamera();
				_player = null;
				Active = false;
				FreeCam = false;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				_hud.SetRespawnVisible(visible: false);
				_hud.SetHealVisible(visible: true);
				_hud.SetStatus("RESPAWNED", 3f);
				Plugin.Logger.LogInfo((object)"Player respawned");
			}
		}

		private void ExitFreeCam()
		{
			if (!FreeCam)
			{
				return;
			}
			if ((Object)(object)_player != (Object)null)
			{
				try
				{
					_player.EnablePlayerMovement(true, true);
					_player.EnablePlayerMouseLook(true, false);
				}
				catch
				{
				}
			}
			DestroyCamera();
			_player = null;
			FreeCam = false;
			_hud.SetRespawnVisible(visible: false);
			_hud.SetHealVisible(visible: true);
			_hud.SetStatus("", 0f);
			Plugin.Logger.LogInfo((object)"FreeCam exited");
		}

		internal void Cancel()
		{
			if (FreeCam && (Object)(object)_player != (Object)null)
			{
				try
				{
					_player.EnablePlayerMovement(true, true);
					_player.EnablePlayerMouseLook(true, false);
				}
				catch
				{
				}
			}
			DestroyCamera();
			_player = null;
			Active = false;
			FreeCam = false;
			_hud.SetRespawnVisible(visible: false);
			_hud.SetHealVisible(visible: true);
		}

		private void CreateCamera(Vector3 position, float yaw)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_00a8: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			_mainCamera = Camera.main;
			if ((Object)(object)_mainCamera == (Object)null)
			{
				try
				{
					CameraController instance = CameraController.Instance;
					_mainCamera = ((instance != null) ? instance.cam : null);
				}
				catch
				{
				}
			}
			if ((Object)(object)_mainCamera != (Object)null)
			{
				_hadMainCamera = true;
				((Behaviour)_mainCamera).enabled = false;
			}
			_cameraObject = new GameObject("AnarchyFreeCam");
			Object.DontDestroyOnLoad((Object)(object)_cameraObject);
			_camera = _cameraObject.AddComponent<Camera>();
			_camera.clearFlags = (CameraClearFlags)2;
			_camera.backgroundColor = new Color(0.02f, 0.02f, 0.03f, 1f);
			_camera.depth = 200f;
			_camera.nearClipPlane = 0.1f;
			_camera.farClipPlane = 1000f;
			_cameraObject.transform.position = position;
			_yaw = yaw;
			_pitch = 0f;
			_cameraObject.transform.rotation = Quaternion.Euler(_pitch, _yaw, 0f);
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}

		private void DestroyCamera()
		{
			if ((Object)(object)_cameraObject != (Object)null)
			{
				Object.Destroy((Object)(object)_cameraObject);
			}
			_cameraObject = null;
			_camera = null;
			if (_hadMainCamera && (Object)(object)_mainCamera != (Object)null)
			{
				((Behaviour)_mainCamera).enabled = true;
			}
			_hadMainCamera = false;
			_mainCamera = null;
		}

		private Vector3 FindSpawnPosition()
		{
			//IL_00e1: 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_00f0: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CityData instance = CityData.Instance;
				if (((instance != null) ? instance.gameLocationDirectory : null) != null)
				{
					List<NewGameLocation> list = new List<NewGameLocation>();
					Enumerator<NewGameLocation> enumerator = instance.gameLocationDirectory.GetEnumerator();
					while (enumerator.MoveNext())
					{
						NewGameLocation current = enumerator.Current;
						if ((Object)(object)current != (Object)null && current.isOutside && current.anchorNode != null)
						{
							list.Add(current);
						}
					}
					if (list.Count > 0)
					{
						return SnapToGround(list[_rng.Next(list.Count)].anchorNode.position + Vector3.up * 0.2f);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("FindSpawnPosition: " + ex.Message));
			}
			if (!((Object)(object)_player != (Object)null))
			{
				return Vector3.zero;
			}
			return ((Component)_player).transform.position + Vector3.up * 0.5f;
		}

		private static KeyCode ParseKey(string value, KeyCode fallback)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (!Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result))
			{
				return fallback;
			}
			return result;
		}

		private static Vector3 SnapToGround(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0015: 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_003b: 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_0045: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(position + Vector3.up * 120f, Vector3.down, ref val, 300f, -1, (QueryTriggerInteraction)1))
				{
					return ((RaycastHit)(ref val)).point + Vector3.up * 0.2f;
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("SnapToGround: " + ex.Message));
			}
			return position;
		}
	}
	internal static class WallHack
	{
		private static Texture2D _white;

		private static GUIStyle _label;

		internal static void Draw(Camera camera)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)camera == (Object)null || Event.current == null || (int)Event.current.type != 7)
			{
				return;
			}
			CityData instance = CityData.Instance;
			if (((instance != null) ? instance.citizenDictionary : null) == null)
			{
				return;
			}
			EnsureStyles();
			Enumerator<int, Human> enumerator = instance.citizenDictionary.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Human value = enumerator.Current.Value;
				if ((Object)(object)value == (Object)null || ((Actor)value).isPlayer || ((Actor)value).isDead)
				{
					continue;
				}
				Vector3 val2;
				float num;
				try
				{
					Vector3 val = ((Component)value).transform.position + Vector3.up * 1.35f;
					val2 = camera.WorldToScreenPoint(val);
					num = Vector3.Distance(((Component)camera).transform.position, val);
				}
				catch
				{
					continue;
				}
				if (!(val2.z <= 0f) && !(val2.x < -80f) && !(val2.x > (float)Screen.width + 80f) && !(val2.y < -80f) && !(val2.y > (float)Screen.height + 80f))
				{
					float num2 = Mathf.Clamp(1300f / Mathf.Max(1f, num), 18f, 150f);
					float num3 = num2 * 0.42f;
					float num4 = val2.x - num3 * 0.5f;
					float num5 = (float)Screen.height - val2.y - num2 * 0.5f;
					Rect val3 = new Rect(num4, num5, num3, num2);
					GUI.color = new Color(1f, 0.1f, 0.1f, 0.18f);
					GUI.DrawTexture(val3, (Texture)(object)_white);
					GUI.color = new Color(1f, 0.2f, 0.2f, 0.95f);
					DrawBorder(val3);
					if (num <= 160f)
					{
						GUI.color = Color.white;
						GUI.Label(new Rect(num4 - 40f, num5 - 20f, num3 + 80f, 20f), WarDirector.Name(value) + "  " + Mathf.RoundToInt(num) + "m", _label);
					}
				}
			}
			GUI.color = Color.white;
		}

		private static void DrawBorder(Rect rect)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, 1f), (Texture)(object)_white);
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - 1f, ((Rect)(ref rect)).width, 1f), (Texture)(object)_white);
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, 1f, ((Rect)(ref rect)).height), (Texture)(object)_white);
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 1f, ((Rect)(ref rect)).y, 1f, ((Rect)(ref rect)).height), (Texture)(object)_white);
		}

		private static void EnsureStyles()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0022: 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_004c: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_white == (Object)null)
			{
				_white = new Texture2D(1, 1, (TextureFormat)4, false);
				_white.SetPixel(0, 0, Color.white);
				_white.Apply();
			}
			if (_label == null)
			{
				_label = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					alignment = (TextAnchor)4,
					wordWrap = false
				};
				_label.normal.textColor = new Color(1f, 0.55f, 0.55f, 1f);
			}
		}
	}
	internal sealed class WarDirector
	{
		private sealed class DoorPlan
		{
			internal NewDoor Door;

			internal float At;
		}

		private readonly List<Human> _humans = new List<Human>();

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

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

		private readonly Dictionary<int, DoorPlan> _doorPlans = new Dictionary<int, DoorPlan>();

		private readonly HashSet<int> _humanIds = new HashSet<int>();

		private Random _rng;

		private string _seed;

		private float _timer;

		private int _scanCounter;

		private int _attackErrors;

		private WeaponSpawner _weapons;

		internal void Initialize(string seed)
		{
			_seed = seed ?? "anarchy";
			_rng = new Random(StableHash(_seed + "|war"));
			_bravery.Clear();
			_nextAttack.Clear();
			_doorPlans.Clear();
			_humans.Clear();
			_humanIds.Clear();
			_timer = 1f;
			_scanCounter = 0;
			_attackErrors = 0;
		}

		internal void AttachWeapons(WeaponSpawner weapons)
		{
			_weapons = weapons;
		}

		internal void Tick(float dt)
		{
			_timer -= dt;
			if (_timer > 0f)
			{
				return;
			}
			_timer = Math.Max(0.2f, ModConfig.AggressionInterval.Value);
			CityData instance = CityData.Instance;
			Player instance2 = Player.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				return;
			}
			CollectHumans(instance, instance2);
			if (_humans.Count == 0)
			{
				return;
			}
			float time = Time.time;
			int num = 0;
			int num2 = Math.Max(1, ModConfig.MaxAttackersPerTick.Value);
			for (int i = 0; i < _humans.Count; i++)
			{
				if (num >= num2)
				{
					break;
				}
				Human val = _humans[i];
				if ((Object)(object)val == (Object)null || ((Actor)val).isDead)
				{
					continue;
				}
				NewAIController ai = ((Actor)val).ai;
				if ((Object)(object)ai == (Object)null || (ai.attackActive && (Object)(object)ai.attackTarget != (Object)null && !ai.attackTarget.isDead) || (ai.persuit && (Object)(object)ai.persuitTarget != (Object)null && !ai.persuitTarget.isDead))
				{
					continue;
				}
				float num3 = NextAttackAt(val);
				if (time < num3)
				{
					continue;
				}
				Actor val2 = ChooseTarget(val, instance2);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				TryArm(val, ai);
				if (ai.currentWeapon == null)
				{
					continue;
				}
				try
				{
					ai.SetPersue(val2, false, 2, true, Math.Max(ModConfig.AttackRadius.Value, 500f));
				}
				catch (Exception ex)
				{
					if (_attackErrors++ < 5)
					{
						Plugin.Logger.LogWarning((object)("SetPersue: " + ex));
					}
				}
				try
				{
					ai.StartAttack(val2);
					_nextAttack[val.humanID] = time + Cooldown(val);
					num++;
				}
				catch (Exception ex2)
				{
					if (_attackErrors++ < 5)
					{
						Plugin.Logger.LogWarning((object)("StartAttack: " + ex2));
					}
					_nextAttack[val.humanID] = time + 3f;
				}
			}
			UpdateDoors(time);
		}

		private void CollectHumans(CityData city, Player player)
		{
			_humans.Clear();
			_humanIds.Clear();
			_scanCounter++;
			try
			{
				if (city.citizenDictionary != null)
				{
					Enumerator<int, Human> enumerator = city.citizenDictionary.GetEnumerator();
					while (enumerator.MoveNext())
					{
						KeyValuePair<int, Human> current = enumerator.Current;
						AddHuman((Actor)(object)current.Value, player);
						if (_humans.Count >= 5000)
						{
							break;
						}
					}
				}
				if (city.visibleActors == null)
				{
					return;
				}
				Enumerator<Actor> enumerator2 = city.visibleActors.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					Actor current2 = enumerator2.Current;
					AddHuman(current2, player);
					if (_humans.Count >= 5000)
					{
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("CollectHumans: " + ex.Message));
			}
		}

		private void AddHuman(Actor actor, Player player)
		{
			if ((Object)(object)actor == (Object)null)
			{
				return;
			}
			Human val = ((Il2CppObjectBase)actor).TryCast<Human>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				if (((Actor)val).isPlayer || ((Actor)val).isDead || (Object)(object)((Component)val).transform == (Object)null)
				{
					return;
				}
			}
			catch
			{
				return;
			}
			if (_humanIds.Add(val.humanID))
			{
				_humans.Add(val);
			}
		}

		private Actor ChooseTarget(Human attacker, Player player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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)
			Vector3 position = ((Component)attacker).transform.position;
			float num = Bravery(attacker);
			float num2 = Math.Max(ModConfig.AttackRadius.Value, 120f);
			float num3 = Vector3.Distance(position, ((Component)player).transform.position);
			if (!((Actor)player).isDead && num3 <= num2 && _rng.NextDouble() < 0.18 + (double)num * 0.25)
			{
				return (Actor)(object)player;
			}
			Actor val = null;
			float num4 = float.MaxValue;
			for (int i = 0; i < _humans.Count; i++)
			{
				Human val2 = _humans[i];
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)attacker) && !((Actor)val2).isDead)
				{
					float num5;
					try
					{
						num5 = Vector3.Distance(position, ((Component)val2).transform.position);
					}
					catch
					{
						continue;
					}
					float num6 = num5;
					if (SameBuilding(attacker, val2))
					{
						num6 -= 25f;
					}
					if (num6 < num4)
					{
						num4 = num6;
						val = (Actor)(object)val2;
					}
				}
			}
			if ((Object)(object)val == (Object)null && num3 <= num2 && !((Actor)player).isDead)
			{
				val = (Actor)(object)player;
			}
			return val;
		}

		private static bool SameBuilding(Human a, Human b)
		{
			try
			{
				NewAddress home = a.home;
				NewAddress home2 = b.home;
				if ((Object)(object)home == (Object)null || (Object)(object)home2 == (Object)null)
				{
					return false;
				}
				return (Object)(object)((NewGameLocation)home).building == (Object)(object)((NewGameLocation)home2).building;
			}
			catch
			{
				return false;
			}
		}

		private void TryArm(Human human, NewAIController ai)
		{
			//IL_001e: 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_0056: Expected O, but got Unknown
			if (_weapons == null || ai.currentWeapon != null)
			{
				return;
			}
			try
			{
				Interactable val = _weapons.TakeNearestWeapon(((Component)human).transform.position, 30f);
				if (val != null)
				{
					ai.SetCurrentWeapon(val);
					ai.UpdateCurrentWeapon();
					ai.RecalculateWeaponStats();
					ManualLogSource logger = Plugin.Logger;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(12, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Armed ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Name(human));
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" with ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(val.GetName());
					}
					logger.LogInfo(val2);
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("TryArm: " + ex.Message));
			}
		}

		private void UpdateDoors(float now)
		{
			for (int i = 0; i < _humans.Count; i++)
			{
				Human val = _humans[i];
				if ((Object)(object)((val != null) ? ((Actor)val).ai : null) == (Object)null)
				{
					continue;
				}
				NewDoor doorCheckDoor = ((Actor)val).ai.doorCheckDoor;
				if ((Object)(object)doorCheckDoor == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)doorCheckDoor).GetInstanceID();
				DoorPlan value;
				if (!doorCheckDoor.isLocked)
				{
					_doorPlans.Remove(instanceID);
				}
				else if (!_doorPlans.TryGetValue(instanceID, out value))
				{
					_doorPlans[instanceID] = new DoorPlan
					{
						Door = doorCheckDoor,
						At = now + ModConfig.DoorUnlockDelay.Value + (float)_rng.NextDouble()
					};
				}
				else if (!(now < value.At))
				{
					try
					{
						doorCheckDoor.SetLocked(false, (Actor)(object)val, false);
						doorCheckDoor.Barge((Actor)(object)val);
						_doorPlans.Remove(instanceID);
					}
					catch (Exception ex)
					{
						Plugin.Logger.LogWarning((object)("Door: " + ex.Message));
						_doorPlans.Remove(instanceID);
					}
				}
			}
		}

		private float Bravery(Human human)
		{
			if (_bravery.TryGetValue(human.humanID, out var value))
			{
				return value;
			}
			float value2 = ModConfig.BraveryMin.Value;
			float value3 = ModConfig.BraveryMax.Value;
			int num = StableHash(_seed + "|bravery|" + human.humanID);
			value = value2 + (value3 - value2) * ((float)(num & 0xFFFF) / 65535f);
			_bravery[human.humanID] = value;
			return value;
		}

		private float NextAttackAt(Human human)
		{
			if (_nextAttack.TryGetValue(human.humanID, out var value))
			{
				return value;
			}
			float num = 2f + (float)_rng.NextDouble() * 12f;
			value = Time.time + num;
			_nextAttack[human.humanID] = value;
			return value;
		}

		private float Cooldown(Human human)
		{
			float num = Bravery(human);
			return 4f + (1f - num) * 12f + (float)_rng.NextDouble() * 4f;
		}

		internal static string Name(Human human)
		{
			if ((Object)(object)human == (Object)null)
			{
				return "Unknown";
			}
			try
			{
				string citizenName = human.GetCitizenName();
				if (!string.IsNullOrEmpty(citizenName))
				{
					return citizenName;
				}
				citizenName = human.citizenName;
				if (!string.IsNullOrEmpty(citizenName))
				{
					return citizenName;
				}
				citizenName = (human.firstName + " " + human.surName).Trim();
				if (!string.IsNullOrEmpty(citizenName))
				{
					return citizenName;
				}
			}
			catch
			{
			}
			return "Citizen #" + human.humanID;
		}

		internal static int StableHash(string text)
		{
			uint num = 2166136261u;
			if (text == null)
			{
				return (int)num;
			}
			for (int i = 0; i < text.Length; i++)
			{
				num ^= text[i];
				num *= 16777619;
			}
			return (int)(num & 0x7FFFFFFF);
		}
	}
	internal sealed class WeaponSpawner
	{
		private readonly List<NewGameLocation> _outside = new List<NewGameLocation>();

		private readonly List<InteractablePreset> _presets = new List<InteractablePreset>();

		private readonly List<Citizen> _citizens = new List<Citizen>();

		private readonly List<Interactable> _streetWeapons = new List<Interactable>();

		private Random _rng;

		private int _streetSpawned;

		private int _streetTarget;

		private int _streetAttempts;

		private int _presetCursor;

		private int _armCursor;

		private int _armTarget;

		private int _armed;

		internal bool StreetSpawnDone { get; private set; }

		internal bool ArmingDone { get; private set; }

		internal int SpawnedWeaponCount => _streetSpawned;

		internal int ArmedNpcCount => _armed;

		internal int PresetCount => _presets.Count;

		private int _outdoorCount => _outside.Count;

		internal InteractablePreset GetPreset(int index)
		{
			if (index < 0 || index >= _presets.Count)
			{
				return null;
			}
			return _presets[index];
		}

		internal string PresetName(int index)
		{
			InteractablePreset preset = GetPreset(index);
			if ((SoCustomComparison)(object)preset == (SoCustomComparison)null)
			{
				return "No weapons";
			}
			string name = ((Object)preset).name;
			if (!string.IsNullOrEmpty(name))
			{
				return name;
			}
			return "Weapon";
		}

		internal bool GivePresetToPlayer(int index, Player player)
		{
			InteractablePreset preset = GetPreset(index);
			if ((SoCustomComparison)(object)preset == (SoCustomComparison)null || (Object)(object)player == (Object)null || ((Actor)player).isDead)
			{
				return false;
			}
			try
			{
				preset.SpawnIntoInventory();
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("GivePresetToPlayer: " + ex));
				return false;
			}
		}

		internal void Begin(string seed)
		{
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Expected O, but got Unknown
			_outside.Clear();
			_presets.Clear();
			_citizens.Clear();
			_streetWeapons.Clear();
			StreetSpawnDone = false;
			ArmingDone = false;
			_streetSpawned = 0;
			_streetAttempts = 0;
			_presetCursor = 0;
			_streetTarget = Math.Max(0, ModCon