Decompiled source of Procedural Narcotics Cases v0.1.4

BepInEx/plugins/Narcotics/Narcotics.dll

Decompiled 8 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;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Narcotics")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.4.0")]
[assembly: AssemblyInformationalVersion("0.1.4+316b87ca4ce6696c540a76ff1cbef8c4a1985798")]
[assembly: AssemblyProduct("Narcotics")]
[assembly: AssemblyTitle("Narcotics")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[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 Narcotics
{
	internal static class Anim
	{
		private static CitizenAnimationController AC(Human h)
		{
			try
			{
				return ((Object)(object)h != (Object)null) ? ((Actor)h).animationController : null;
			}
			catch
			{
				return null;
			}
		}

		internal static void Locking(Human h)
		{
			SetArms(h, (ArmsBoolSate)4);
		}

		internal static void Rest(Human h)
		{
			SetArms(h, (ArmsBoolSate)1);
		}

		private static void SetArms(Human h, ArmsBoolSate s)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			CitizenAnimationController val = AC(h);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				val.SetArmsBoolState(s);
			}
			catch
			{
			}
			try
			{
				val.ForceUpdateAnimationSate(true);
			}
			catch
			{
			}
		}

		internal static void Lean(Human h)
		{
			Idle(h, (IdleAnimationState)11);
		}

		internal static void IdleNone(Human h)
		{
			Idle(h, (IdleAnimationState)0);
		}

		private static void Idle(Human h, IdleAnimationState s)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			CitizenAnimationController val = AC(h);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				val.SetIdleAnimationState(s);
			}
			catch
			{
			}
			try
			{
				val.ForceUpdateAnimationSate(true);
			}
			catch
			{
			}
		}
	}
	internal static class Arrest
	{
		private enum Phase
		{
			Approach,
			Detain
		}

		private sealed class Posted
		{
			public Human Subject;

			public Human Enforcer;

			public NewGameLocation GuardLoc;

			public float NextWander;

			public float HoldUntil;

			public bool OpenCase;

			public bool Searched;
		}

		internal static bool Active;

		internal static Human Enforcer;

		internal static Human Subject;

		private static Phase _phase;

		private static bool _openCase;

		private static NewNode _subjectNode;

		private static NewGameLocation _subjectLoc;

		private static float _approachStartGT;

		private static float _nextReassert;

		internal static bool SubjectSearched;

		private static readonly List<Posted> _posted = new List<Posted>();

		private static readonly Random _rng = new Random();

		private const float ContactM = 1.8f;

		private const float ArrestApproachMinutes = 5f;

		private static float _nextApproachLog;

		internal static void Overdose()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Player instance = Player.Instance;
				NewNode val = null;
				try
				{
					val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentNode : null);
				}
				catch
				{
				}
				if (val == null)
				{
					Log("no player node (load a game).");
					return;
				}
				Human val2 = NearestNPC(val.position, -1);
				if ((Object)(object)val2 == (Object)null)
				{
					Log("no nearby NPC - move somewhere with people.");
				}
				else
				{
					Begin(val2, openCase: true);
				}
			}
			catch (Exception ex)
			{
				Log("Overdose error: " + ex.Message);
			}
		}

		internal static bool Begin(Human subject, bool openCase)
		{
			try
			{
				if ((Object)(object)subject == (Object)null || Dead(subject))
				{
					Log("Begin: no valid subject.");
					return false;
				}
				Reset();
				Subject = subject;
				Enforcer = null;
				Active = true;
				_phase = Phase.Approach;
				_openCase = openCase;
				_approachStartGT = Herd.NowHours();
				_nextReassert = 0f;
				_nextApproachLog = 0f;
				SubjectSearched = false;
				try
				{
					subject.AddDrunk(2f);
				}
				catch
				{
				}
				try
				{
					subject.AddSick(1.5f);
				}
				catch
				{
				}
				NewGameLocation val = null;
				try
				{
					val = ((Actor)subject).currentGameLocation;
				}
				catch
				{
				}
				string value = "?";
				try
				{
					if ((Object)(object)val != (Object)null)
					{
						value = ((Object)val).name;
					}
				}
				catch
				{
				}
				_subjectNode = null;
				_subjectLoc = val;
				try
				{
					_subjectNode = ((Actor)subject).currentNode;
				}
				catch
				{
				}
				if (_subjectNode != null)
				{
					try
					{
						Herd.ToNode(subject, _subjectNode, val, 0.5f);
					}
					catch
					{
					}
				}
				Log($"OVERDOSE: {NarcoticsPlugin.Name(subject)} is erratic at {value}; driving the nearest officer to arrest (openCase={openCase}). Teleport (F10) to watch.");
				return true;
			}
			catch (Exception ex)
			{
				Log("Begin error: " + ex.Message);
				return false;
			}
		}

		internal static void Tick()
		{
			try
			{
				TickPosted();
			}
			catch (Exception ex)
			{
				Log("TickPosted error: " + ex.Message);
			}
			if (!Active)
			{
				return;
			}
			try
			{
				if (Dead(Subject))
				{
					Log("arrest subject gone.");
					Reset();
					return;
				}
				if (Time.time >= _nextReassert)
				{
					_nextReassert = Time.time + 3f;
					try
					{
						Subject.AddDrunk(0.5f);
					}
					catch
					{
					}
					try
					{
						Subject.AddSick(0.4f);
					}
					catch
					{
					}
				}
				if (_phase != Phase.Approach)
				{
					return;
				}
				if (_subjectNode != null)
				{
					try
					{
						Herd.ToNode(Subject, _subjectNode, _subjectLoc, 0.5f);
					}
					catch
					{
					}
				}
				if (Dead(Enforcer))
				{
					Enforcer = NearestEnforcer(Subject);
				}
				if (Time.time >= _nextApproachLog)
				{
					_nextApproachLog = Time.time + 8f;
					Log("arrest: approaching - enforcer=" + (((Object)(object)Enforcer != (Object)null) ? NarcoticsPlugin.Name(Enforcer) : "<none available>") + ".");
				}
				bool flag = (Object)(object)Enforcer != (Object)null && _subjectNode != null && Herd.ToNode(Enforcer, _subjectNode, _subjectLoc, 1.8f, ResponseGoal());
				bool flag2 = Herd.NowHours() - _approachStartGT >= 1f / 12f;
				if (!flag && flag2)
				{
					if (!((Object)(object)Enforcer != (Object)null))
					{
						Log("arrest: no uniformed officer available - SELF-ARREST fallback so the case still opens.");
						EnterDetain(selfArrest: true);
						return;
					}
					try
					{
						((Actor)Enforcer).Teleport(AdjacentWalkable(_subjectNode) ?? _subjectNode, (UsagePoint)null, true, false, true);
					}
					catch (Exception ex2)
					{
						Log("enforcer teleport threw: " + ex2.Message);
					}
					Log("arrest: " + NarcoticsPlugin.Name(Enforcer) + " couldn't path in time - teleported to the scene.");
					flag = true;
				}
				if (flag)
				{
					EnterDetain(selfArrest: false);
				}
			}
			catch (Exception ex3)
			{
				Log("Tick error: " + ex3.Message);
				Reset();
			}
		}

		private static void TickPosted()
		{
			if (_posted.Count == 0)
			{
				return;
			}
			bool flag = false;
			try
			{
				flag = NarcCase.IsSolved();
			}
			catch
			{
			}
			for (int num = _posted.Count - 1; num >= 0; num--)
			{
				Posted posted = _posted[num];
				if (posted == null || Dead(posted.Subject))
				{
					if (posted != null)
					{
						ReleasePosted(posted);
					}
					_posted.RemoveAt(num);
				}
				else
				{
					try
					{
						((Actor)posted.Subject).ai.SetRestrained(true, 2f);
					}
					catch
					{
					}
					if ((Object)(object)posted.Enforcer != (Object)null && !Dead(posted.Enforcer) && Time.time >= posted.NextWander)
					{
						try
						{
							Herd.Release(posted.Enforcer);
						}
						catch
						{
						}
						try
						{
							if ((Object)(object)posted.GuardLoc != (Object)null)
							{
								((Actor)posted.Enforcer).ai.Patrol(posted.GuardLoc);
							}
						}
						catch
						{
						}
						posted.NextWander = Time.time + 20f;
					}
					if ((posted.OpenCase && flag) || Herd.NowHours() >= posted.HoldUntil)
					{
						Log($"{NarcoticsPlugin.Name(posted.Subject)} released (arrest complete; {_posted.Count - 1} scene(s) still active).");
						ReleasePosted(posted);
						_posted.RemoveAt(num);
					}
				}
			}
		}

		private static void ReleasePosted(Posted p)
		{
			try
			{
				if (p != null && (Object)(object)p.Subject != (Object)null)
				{
					try
					{
						Herd.Release(p.Subject);
					}
					catch
					{
					}
					try
					{
						((Actor)p.Subject).ai.SetRestrained(false, 0f);
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			try
			{
				if (p != null && (Object)(object)p.Enforcer != (Object)null)
				{
					Herd.Release(p.Enforcer);
				}
			}
			catch
			{
			}
			try
			{
				if (p != null && (Object)(object)p.Subject != (Object)null)
				{
					NarcCase.ClearLeadFor(p.Subject.humanID, "released from arrest");
				}
			}
			catch
			{
			}
		}

		private static void ReleaseAllPosted()
		{
			try
			{
				for (int i = 0; i < _posted.Count; i++)
				{
					if (_posted[i] != null)
					{
						ReleasePosted(_posted[i]);
					}
				}
			}
			catch
			{
			}
			_posted.Clear();
		}

		private static void EnterDetain(bool selfArrest)
		{
			try
			{
				Herd.Release(Subject);
			}
			catch
			{
			}
			try
			{
				((Actor)Subject).ai.SetRestrained(true, 2f);
			}
			catch
			{
			}
			if (_openCase)
			{
				try
				{
					NarcCase.OnSubjectArrested(Subject);
				}
				catch (Exception ex)
				{
					Log("case open error: " + ex.Message);
				}
			}
			try
			{
				Operation.OnArrestMade();
			}
			catch
			{
			}
			Posted posted = new Posted
			{
				Subject = Subject,
				Enforcer = (selfArrest ? null : Enforcer),
				OpenCase = _openCase,
				HoldUntil = Herd.NowHours() + Math.Max(0.25f, NarcoticsConfig.ArrestHoldHours),
				Searched = false
			};
			if ((Object)(object)posted.Enforcer != (Object)null)
			{
				try
				{
					posted.GuardLoc = ((Actor)Subject).currentGameLocation;
				}
				catch
				{
				}
				try
				{
					Herd.Release(Enforcer);
				}
				catch
				{
				}
				try
				{
					if ((Object)(object)posted.GuardLoc != (Object)null)
					{
						((Actor)Enforcer).ai.Patrol(posted.GuardLoc);
					}
				}
				catch
				{
				}
				Log($"ARREST: {NarcoticsPlugin.Name(Subject)} restrained; officer {NarcoticsPlugin.Name(Enforcer)} set to patrol the scene. Cuffed ~{NarcoticsConfig.ArrestHoldHours:0}h (or until solved). {_posted.Count + 1} scene(s) active.");
			}
			else
			{
				Log($"ARREST: {NarcoticsPlugin.Name(Subject)} restrained in place (no officer posted). {_posted.Count + 1} scene(s) active.");
			}
			_posted.Add(posted);
			ClearActive();
		}

		private static void ClearActive()
		{
			Active = false;
			Enforcer = null;
			Subject = null;
			_phase = Phase.Approach;
			_openCase = false;
			_subjectNode = null;
			_subjectLoc = null;
			SubjectSearched = false;
		}

		internal static bool IsArrestee(int id)
		{
			try
			{
				if (Active && (Object)(object)Subject != (Object)null && Subject.humanID == id)
				{
					return true;
				}
				for (int i = 0; i < _posted.Count; i++)
				{
					Posted posted = _posted[i];
					if (posted != null && (Object)(object)posted.Subject != (Object)null && posted.Subject.humanID == id)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static bool IsPostedEnforcer(int id)
		{
			try
			{
				if ((Object)(object)Enforcer != (Object)null && Enforcer.humanID == id)
				{
					return true;
				}
				for (int i = 0; i < _posted.Count; i++)
				{
					Posted posted = _posted[i];
					if (posted != null && (Object)(object)posted.Enforcer != (Object)null && posted.Enforcer.humanID == id)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static NewNode AdjacentWalkable(NewNode n)
		{
			try
			{
				if (n == null)
				{
					return n;
				}
				Dictionary<NewNode, NodeAccess> accessToOtherNodes = n.accessToOtherNodes;
				if (accessToOtherNodes != null)
				{
					Enumerator<NewNode, NodeAccess> enumerator = accessToOtherNodes.GetEnumerator();
					while (enumerator.MoveNext())
					{
						KeyValuePair<NewNode, NodeAccess> current = enumerator.Current;
						NewNode key = current.Key;
						NodeAccess value = current.Value;
						if (key == null || value == null)
						{
							continue;
						}
						bool flag = false;
						try
						{
							flag = value.walkingAccess;
						}
						catch
						{
						}
						if (flag)
						{
							bool flag2 = false;
							try
							{
								flag2 = key.isObstacle || key.isInaccessable || key.noAccess || !key.isConnected;
							}
							catch
							{
							}
							if (!flag2)
							{
								return key;
							}
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static void Finish()
		{
			try
			{
				if ((Object)(object)Subject != (Object)null)
				{
					try
					{
						((Actor)Subject).ai.SetRestrained(false, 0f);
					}
					catch
					{
					}
				}
				if ((Object)(object)Enforcer != (Object)null)
				{
					try
					{
						Herd.Release(Enforcer);
					}
					catch
					{
					}
				}
				Log("RELEASED " + NarcoticsPlugin.Name(Subject) + " - arrest complete.");
			}
			catch (Exception ex)
			{
				Log("Finish error: " + ex.Message);
			}
			finally
			{
				Reset();
			}
		}

		internal static void TeleportToPair()
		{
			try
			{
				if (!Active || (Object)(object)Subject == (Object)null)
				{
					Log("no active arrest (press the overdose key first).");
					return;
				}
				if (!Diagnostics.TeleportOnto(Subject))
				{
					Log("subject has no node yet.");
					return;
				}
				string value = (((Object)(object)Enforcer != (Object)null) ? NarcoticsPlugin.Name(Enforcer) : "(awaiting enforcer)");
				Log($"teleported to the arrest: subject {NarcoticsPlugin.Name(Subject)}, enforcer {value} (phase {_phase}).");
			}
			catch (Exception ex)
			{
				Log("TeleportToPair error: " + ex.Message);
			}
		}

		internal static void Stop()
		{
			try
			{
				ReleaseAllPosted();
			}
			catch
			{
			}
			if (Active)
			{
				Finish();
			}
		}

		internal static void NotifySearched(Human h)
		{
			try
			{
				if ((Object)(object)h == (Object)null)
				{
					return;
				}
				int humanID;
				try
				{
					humanID = h.humanID;
				}
				catch
				{
					return;
				}
				if (Active && (Object)(object)Subject != (Object)null && Subject.humanID == humanID)
				{
					if (!SubjectSearched)
					{
						SubjectSearched = true;
						Log("player searched " + NarcoticsPlugin.Name(h) + " - their dose is now known evidence.");
					}
					return;
				}
				for (int i = 0; i < _posted.Count; i++)
				{
					Posted posted = _posted[i];
					if (posted != null && (Object)(object)posted.Subject != (Object)null && posted.Subject.humanID == humanID)
					{
						if (!posted.Searched)
						{
							posted.Searched = true;
							Log("player searched " + NarcoticsPlugin.Name(h) + " - their dose is now known evidence. Pin it to the case board (they stay cuffed).");
						}
						break;
					}
				}
			}
			catch
			{
			}
		}

		private static void Reset()
		{
			try
			{
				if ((Object)(object)Subject != (Object)null)
				{
					try
					{
						Herd.Release(Subject);
					}
					catch
					{
					}
					try
					{
						((Actor)Subject).ai.SetRestrained(false, 0f);
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)Enforcer != (Object)null)
				{
					Herd.Release(Enforcer);
				}
			}
			catch
			{
			}
			Active = false;
			Enforcer = null;
			Subject = null;
			_phase = Phase.Approach;
			_openCase = false;
			_subjectNode = null;
			_subjectLoc = null;
			SubjectSearched = false;
		}

		internal static void ResetOnLoad()
		{
			Active = false;
			Enforcer = null;
			Subject = null;
			_phase = Phase.Approach;
			_openCase = false;
			_subjectNode = null;
			_subjectLoc = null;
			SubjectSearched = false;
			_posted.Clear();
		}

		private static Human NearestNPC(Vector3 pos, int skipId)
		{
			//IL_00a5: 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)
			try
			{
				CityData instance = CityData.Instance;
				List<Citizen> val = (((Object)(object)instance != (Object)null) ? instance.citizenDirectory : null);
				if (val == null)
				{
					return null;
				}
				int num = -1;
				try
				{
					if ((Object)(object)Player.Instance != (Object)null)
					{
						num = ((Human)Player.Instance).humanID;
					}
				}
				catch
				{
				}
				Human result = null;
				float num2 = float.MaxValue;
				for (int i = 0; i < val.Count; i++)
				{
					Human val2 = null;
					try
					{
						val2 = (Human)(object)val[i];
					}
					catch
					{
					}
					if ((Object)(object)val2 == (Object)null || Dead(val2))
					{
						continue;
					}
					int humanID;
					try
					{
						humanID = val2.humanID;
					}
					catch
					{
						continue;
					}
					if (humanID == num || humanID == skipId)
					{
						continue;
					}
					NewNode val3 = null;
					try
					{
						val3 = ((Actor)val2).currentNode;
					}
					catch
					{
					}
					if (val3 != null)
					{
						float num3;
						try
						{
							num3 = Vector3.Distance(pos, val3.position);
						}
						catch
						{
							continue;
						}
						if (num3 < num2)
						{
							num2 = num3;
							result = val2;
						}
					}
				}
				return result;
			}
			catch
			{
				return null;
			}
		}

		private static Human NearestEnforcer(Human subject)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				NewNode val = null;
				try
				{
					val = ((Actor)subject).currentNode;
				}
				catch
				{
				}
				if (val == null)
				{
					return null;
				}
				Vector3 position = val.position;
				GameplayController instance = GameplayController.Instance;
				List<Human> val2 = (((Object)(object)instance != (Object)null) ? instance.enforcers : null);
				if (val2 == null)
				{
					return null;
				}
				Human result = null;
				float num = float.MaxValue;
				for (int i = 0; i < val2.Count; i++)
				{
					Human val3 = null;
					try
					{
						val3 = val2[i];
					}
					catch
					{
					}
					if ((Object)(object)val3 == (Object)null || Dead(val3))
					{
						continue;
					}
					int humanID;
					try
					{
						humanID = val3.humanID;
					}
					catch
					{
						continue;
					}
					if (IsPostedEnforcer(humanID) || !IsUniformed(val3))
					{
						continue;
					}
					NewNode val4 = null;
					try
					{
						val4 = ((Actor)val3).currentNode;
					}
					catch
					{
					}
					if (val4 != null)
					{
						float num2;
						try
						{
							num2 = Vector3.Distance(position, val4.position);
						}
						catch
						{
							continue;
						}
						if (num2 < num)
						{
							num = num2;
							result = val3;
						}
					}
				}
				return result;
			}
			catch
			{
				return null;
			}
		}

		private static bool IsUniformed(Human h)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			try
			{
				CitizenOutfitController outfitController = h.outfitController;
				if ((Object)(object)outfitController == (Object)null)
				{
					return false;
				}
				OutfitCategory currentOutfit = outfitController.currentOutfit;
				return (int)currentOutfit == 1 || (int)currentOutfit == 4;
			}
			catch
			{
				return false;
			}
		}

		private static AIGoalPreset ResponseGoal()
		{
			try
			{
				RoutineControls instance = RoutineControls.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					return instance.enforcerResponse;
				}
			}
			catch
			{
			}
			return null;
		}

		private static bool Dead(Human h)
		{
			try
			{
				return (Object)(object)h == (Object)null || ((Actor)h).isDead;
			}
			catch
			{
				return false;
			}
		}

		private static void Log(string m)
		{
			NarcoticsPlugin.Log.LogInfo((object)("[Narcotics][arrest] " + m));
		}
	}
	internal static class Containers
	{
		private sealed class Cand
		{
			public FurnitureLocation Fl;

			public float Dist;

			public bool Outside;

			public string Name;

			public int Subs;
		}

		internal static Vector3 ExteriorAnchor(NewAddress lab, out NewBuilding building)
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			building = null;
			try
			{
				building = (((Object)(object)lab != (Object)null) ? ((NewGameLocation)lab).building : null);
			}
			catch
			{
			}
			if ((Object)(object)building != (Object)null)
			{
				try
				{
					NewWall mainEntrance = building.mainEntrance;
					if (mainEntrance != null)
					{
						NewNode val = null;
						NewNode val2 = null;
						try
						{
							val = mainEntrance.node;
						}
						catch
						{
						}
						try
						{
							NewWall otherWall = mainEntrance.otherWall;
							if (otherWall != null)
							{
								val2 = otherWall.node;
							}
						}
						catch
						{
						}
						NewNode val3 = null;
						try
						{
							if (val != null && val.isOutside)
							{
								val3 = val;
							}
						}
						catch
						{
						}
						if (val3 == null)
						{
							try
							{
								if (val2 != null && val2.isOutside)
								{
									val3 = val2;
								}
							}
							catch
							{
							}
						}
						if (val3 == null)
						{
							val3 = val ?? val2;
						}
						if (val3 != null)
						{
							try
							{
								return val3.position;
							}
							catch
							{
							}
						}
					}
				}
				catch
				{
				}
				try
				{
					return building.worldPosition;
				}
				catch
				{
				}
			}
			try
			{
				NodeAccess mainEntrance2 = ((NewGameLocation)lab).GetMainEntrance();
				if (mainEntrance2 != null)
				{
					return mainEntrance2.worldAccessPoint;
				}
			}
			catch
			{
			}
			try
			{
				NewNode anchorNode = ((NewGameLocation)lab).anchorNode;
				if (anchorNode != null)
				{
					return anchorNode.position;
				}
			}
			catch
			{
			}
			return Vector3.zero;
		}

		internal static List<FurnitureLocation> SiteContainersNearLab(NewAddress lab, int n)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			List<FurnitureLocation> list = new List<FurnitureLocation>();
			try
			{
				NewBuilding building;
				Vector3 anchor = ExteriorAnchor(lab, out building);
				List<NewGameLocation> list2 = new List<NewGameLocation>();
				if ((Object)(object)building != (Object)null)
				{
					try
					{
						StreetController street = building.street;
						if ((Object)(object)street != (Object)null)
						{
							list2.Add((NewGameLocation)(object)street);
						}
					}
					catch
					{
					}
				}
				AddNearbyStreets(anchor, list2);
				if (list2.Count == 0 && (Object)(object)lab != (Object)null)
				{
					list2.Add((NewGameLocation)(object)lab);
				}
				List<Cand> list3 = new List<Cand>();
				HashSet<IntPtr> seen = new HashSet<IntPtr>();
				for (int i = 0; i < list2.Count; i++)
				{
					CollectContainers(list2[i], anchor, list3, seen);
				}
				List<Cand> list4 = new List<Cand>();
				for (int j = 0; j < list3.Count; j++)
				{
					if (list3[j].Outside)
					{
						list4.Add(list3[j]);
					}
				}
				List<Cand> list5 = ((list4.Count > 0) ? list4 : list3);
				list5.Sort((Cand a, Cand b) => a.Dist.CompareTo(b.Dist));
				for (int num = 0; num < list5.Count; num++)
				{
					if (list.Count >= n)
					{
						break;
					}
					list.Add(list5[num].Fl);
				}
				Log($"sited {list.Count}/{n} container(s) near the lab ({list4.Count} outside / {list3.Count} total, {list2.Count} location(s) scanned; using {((list4.Count > 0) ? "outside" : "any")}).");
				for (int num2 = 0; num2 < list5.Count && num2 < 12; num2++)
				{
					Cand cand = list5[num2];
					Log($"  cand: '{cand.Name}' outside={cand.Outside} subs={cand.Subs} {cand.Dist:0}m{((num2 < list.Count) ? "  <= in pool" : "")}");
				}
				if (list.Count == 0)
				{
					DumpNearbyFurniture(list2, anchor);
				}
			}
			catch (Exception ex)
			{
				Log("SiteContainersNearLab error: " + ex.Message);
			}
			return list;
		}

		private static void AddNearbyStreets(Vector3 anchor, List<NewGameLocation> locs)
		{
			//IL_00a5: 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)
			try
			{
				CityData instance = CityData.Instance;
				List<StreetController> val = (((Object)(object)instance != (Object)null) ? instance.streetDirectory : null);
				if (val == null)
				{
					return;
				}
				HashSet<IntPtr> hashSet = new HashSet<IntPtr>();
				foreach (NewGameLocation loc in locs)
				{
					try
					{
						hashSet.Add(((Il2CppObjectBase)loc).Pointer);
					}
					catch
					{
					}
				}
				for (int i = 0; i < val.Count; i++)
				{
					StreetController val2 = val[i];
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					IntPtr pointer;
					try
					{
						pointer = ((Il2CppObjectBase)val2).Pointer;
					}
					catch
					{
						continue;
					}
					if (hashSet.Contains(pointer))
					{
						continue;
					}
					try
					{
						NewNode anchorNode = ((NewGameLocation)val2).anchorNode;
						if (anchorNode != null && Vector3.Distance(anchor, anchorNode.position) <= 140f)
						{
							locs.Add((NewGameLocation)(object)val2);
							hashSet.Add(pointer);
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}

		private static void CollectContainers(NewGameLocation loc, Vector3 anchor, List<Cand> found, HashSet<IntPtr> seen)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)loc == (Object)null)
				{
					return;
				}
				List<NewRoom> rooms = loc.rooms;
				if (rooms != null)
				{
					for (int i = 0; i < rooms.Count; i++)
					{
						NewRoom val = rooms[i];
						if ((Object)(object)val == (Object)null)
						{
							continue;
						}
						List<FurnitureLocation> individualFurniture = val.individualFurniture;
						if (individualFurniture != null)
						{
							for (int j = 0; j < individualFurniture.Count; j++)
							{
								Consider(individualFurniture[j], anchor, found, seen);
							}
						}
					}
				}
				List<NewNode> nodes = loc.nodes;
				if (nodes == null)
				{
					return;
				}
				for (int k = 0; k < nodes.Count; k++)
				{
					NewNode val2 = nodes[k];
					if (val2 == null)
					{
						continue;
					}
					List<FurnitureLocation> individualFurniture2 = val2.individualFurniture;
					if (individualFurniture2 != null)
					{
						for (int l = 0; l < individualFurniture2.Count; l++)
						{
							Consider(individualFurniture2[l], anchor, found, seen);
						}
					}
				}
			}
			catch
			{
			}
		}

		private static void Consider(FurnitureLocation fl, Vector3 anchor, List<Cand> found, HashSet<IntPtr> seen)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (fl == null)
				{
					return;
				}
				IntPtr pointer;
				try
				{
					pointer = ((Il2CppObjectBase)fl).Pointer;
				}
				catch
				{
					return;
				}
				if (seen.Add(pointer) && IsContainer(fl))
				{
					Cand cand = new Cand
					{
						Fl = fl,
						Dist = DistTo(anchor, fl)
					};
					try
					{
						NewNode anchorNode = fl.anchorNode;
						cand.Outside = anchorNode != null && anchorNode.isOutside;
					}
					catch
					{
					}
					try
					{
						cand.Name = (((SoCustomComparison)(object)fl.furniture != (SoCustomComparison)null) ? ((Object)fl.furniture).name : "?");
					}
					catch
					{
						cand.Name = "?";
					}
					try
					{
						cand.Subs = (((SoCustomComparison)(object)fl.furniture != (SoCustomComparison)null && fl.furniture.subObjects != null) ? fl.furniture.subObjects.Count : 0);
					}
					catch
					{
					}
					found.Add(cand);
				}
			}
			catch
			{
			}
		}

		internal static bool IsTrashBin(FurnitureLocation fl)
		{
			try
			{
				string text = ((fl != null && (SoCustomComparison)(object)fl.furniture != (SoCustomComparison)null) ? ((Object)fl.furniture).name : null);
				if (string.IsNullOrEmpty(text))
				{
					return false;
				}
				string text2 = text.ToLowerInvariant();
				if (text2.Contains("poster"))
				{
					return false;
				}
				if (text2.Contains("dumpster") || text2.Contains("skip") || text2.Contains("recycl") || text2.Contains("trash") || text2.Contains("garbage") || text2.Contains("waste"))
				{
					return true;
				}
				if (text2.Contains("bin") && !text2.Contains("cabinet"))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		internal static bool IsContainer(FurnitureLocation fl)
		{
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Invalid comparison between Unknown and I4
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Invalid comparison between Unknown and I4
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Invalid comparison between Unknown and I4
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Invalid comparison between Unknown and I4
			try
			{
				FurniturePreset furniture = fl.furniture;
				if ((SoCustomComparison)(object)furniture == (SoCustomComparison)null)
				{
					return false;
				}
				string text = null;
				try
				{
					text = ((Object)furniture).name;
				}
				catch
				{
				}
				if (!string.IsNullOrEmpty(text))
				{
					string text2 = text.ToLowerInvariant();
					if (!text2.Contains("poster") && (text2.Contains("bin") || text2.Contains("trash") || text2.Contains("waste") || text2.Contains("garbage") || text2.Contains("recycl") || text2.Contains("dumpster") || text2.Contains("mail") || text2.Contains("postbox") || text2.Contains("post box") || text2.Contains("locker") || text2.Contains("cabinet") || text2.Contains("drawer")))
					{
						return true;
					}
				}
				List<SubObject> subObjects = furniture.subObjects;
				if (subObjects == null || subObjects.Count <= 0)
				{
					return false;
				}
				List<FurnitureClass> furnitureClasses = fl.furnitureClasses;
				if (furnitureClasses != null)
				{
					for (int i = 0; i < furnitureClasses.Count; i++)
					{
						FurnitureClass val = furnitureClasses[i];
						if (!((SoCustomComparison)(object)val == (SoCustomComparison)null))
						{
							OwnershipClass ownershipClass;
							try
							{
								ownershipClass = val.ownershipClass;
							}
							catch
							{
								continue;
							}
							if ((int)ownershipClass == 7 || (int)ownershipClass == 3 || (int)ownershipClass == 4 || (int)ownershipClass == 6)
							{
								return true;
							}
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		internal static SubObject PickSlot(FurnitureLocation fl)
		{
			try
			{
				List<SubObject> subObjects = fl.furniture.subObjects;
				if (subObjects == null || subObjects.Count == 0)
				{
					return null;
				}
				SubObject val = null;
				for (int i = 0; i < subObjects.Count; i++)
				{
					SubObject val2 = subObjects[i];
					if (val2 != null)
					{
						if (val == null)
						{
							val = val2;
						}
						int num = 0;
						try
						{
							num = val2.security;
						}
						catch
						{
						}
						if (num == 0)
						{
							val = val2;
							break;
						}
					}
				}
				return val;
			}
			catch
			{
				return null;
			}
		}

		internal static NewNode ContainerNode(FurnitureLocation fl)
		{
			try
			{
				NewNode anchorNode = fl.anchorNode;
				if (anchorNode != null)
				{
					return anchorNode;
				}
			}
			catch
			{
			}
			try
			{
				List<NewNode> coversNodes = fl.coversNodes;
				if (coversNodes != null && coversNodes.Count > 0)
				{
					return coversNodes[0];
				}
			}
			catch
			{
			}
			return null;
		}

		internal static List<Human> PickNearestHomeless(NewAddress lab, int n, HashSet<int> used)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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)
			List<Human> list = new List<Human>();
			try
			{
				NewBuilding building;
				Vector3 val = ExteriorAnchor(lab, out building);
				CityData instance = CityData.Instance;
				List<Citizen> val2 = (((Object)(object)instance != (Object)null) ? instance.homelessDirectory : null);
				if (val2 == null)
				{
					Log("no homelessDirectory; can't pick dealers.");
					return list;
				}
				List<KeyValuePair<Human, float>> list2 = new List<KeyValuePair<Human, float>>();
				for (int i = 0; i < val2.Count; i++)
				{
					Human val3 = null;
					try
					{
						val3 = (Human)(object)val2[i];
					}
					catch
					{
					}
					if (!((Object)(object)val3 == (Object)null) && Alive(val3))
					{
						int humanID;
						try
						{
							humanID = val3.humanID;
						}
						catch
						{
							continue;
						}
						if (!used.Contains(humanID) && Measure(val3, out var p))
						{
							list2.Add(new KeyValuePair<Human, float>(val3, Vector3.Distance(val, p)));
						}
					}
				}
				list2.Sort((KeyValuePair<Human, float> x, KeyValuePair<Human, float> y) => x.Value.CompareTo(y.Value));
				for (int num = 0; num < list2.Count; num++)
				{
					if (list.Count >= n)
					{
						break;
					}
					list.Add(list2[num].Key);
					try
					{
						used.Add(list2[num].Key.humanID);
					}
					catch
					{
					}
				}
				Log($"picked {list.Count}/{n} nearest homeless dealer(s) to the lab.");
			}
			catch (Exception ex)
			{
				Log("PickNearestHomeless error: " + ex.Message);
			}
			return list;
		}

		private static void DumpNearbyFurniture(List<NewGameLocation> locs, Vector3 anchor)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Log("  (few containers found - dumping nearby furniture within 30m to identify bins:)");
				int num = 0;
				HashSet<IntPtr> hashSet = new HashSet<IntPtr>();
				for (int i = 0; i < locs.Count; i++)
				{
					if (num >= 30)
					{
						break;
					}
					NewGameLocation val = locs[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					List<NewNode> nodes = val.nodes;
					if (nodes == null)
					{
						continue;
					}
					for (int j = 0; j < nodes.Count; j++)
					{
						if (num >= 30)
						{
							break;
						}
						NewNode val2 = nodes[j];
						if (val2 == null)
						{
							continue;
						}
						List<FurnitureLocation> individualFurniture = val2.individualFurniture;
						if (individualFurniture == null)
						{
							continue;
						}
						for (int k = 0; k < individualFurniture.Count && num < 30; k++)
						{
							FurnitureLocation val3 = individualFurniture[k];
							if (val3 == null)
							{
								continue;
							}
							IntPtr pointer;
							try
							{
								pointer = ((Il2CppObjectBase)val3).Pointer;
							}
							catch
							{
								continue;
							}
							if (!hashSet.Add(pointer))
							{
								continue;
							}
							float num2 = DistTo(anchor, val3);
							if (num2 > 30f)
							{
								continue;
							}
							string value = "?";
							try
							{
								value = (((SoCustomComparison)(object)val3.furniture != (SoCustomComparison)null) ? ((Object)val3.furniture).name : "?");
							}
							catch
							{
							}
							int value2 = 0;
							try
							{
								value2 = (((SoCustomComparison)(object)val3.furniture != (SoCustomComparison)null && val3.furniture.subObjects != null) ? val3.furniture.subObjects.Count : 0);
							}
							catch
							{
							}
							bool value3 = false;
							try
							{
								NewNode anchorNode = val3.anchorNode;
								if (anchorNode != null)
								{
									value3 = anchorNode.isOutside;
								}
							}
							catch
							{
							}
							Log($"    furn: '{value}' outside={value3} subs={value2} {num2:0}m");
							num++;
						}
					}
				}
			}
			catch
			{
			}
		}

		private static bool Measure(Human h, out Vector3 p)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			p = Vector3.zero;
			try
			{
				Interactable sleepPosition = h.sleepPosition;
				if (sleepPosition != null)
				{
					NewNode node = sleepPosition.node;
					if (node != null)
					{
						p = node.position;
						return true;
					}
				}
			}
			catch
			{
			}
			try
			{
				NewNode currentNode = ((Actor)h).currentNode;
				if (currentNode != null)
				{
					p = currentNode.position;
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static float DistTo(Vector3 anchor, FurnitureLocation fl)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return Vector3.Distance(anchor, fl.GetWorldAveragePosition());
			}
			catch
			{
			}
			try
			{
				NewNode anchorNode = fl.anchorNode;
				if (anchorNode != null)
				{
					return Vector3.Distance(anchor, anchorNode.position);
				}
			}
			catch
			{
			}
			return float.MaxValue;
		}

		private static bool Alive(Human h)
		{
			if ((Object)(object)h == (Object)null)
			{
				return false;
			}
			try
			{
				return !((Actor)h).isDead;
			}
			catch
			{
				return true;
			}
		}

		private static void Log(string m)
		{
			NarcoticsPlugin.Log.LogInfo((object)("[Narcotics][sites] " + m));
		}
	}
	internal static class Cook
	{
		private static IntPtr _goalPtr = IntPtr.Zero;

		private static IntPtr _nodePtr = IntPtr.Zero;

		private static bool _nodeReachable;

		private static bool _loggedPin;

		private static bool _loggedUpgrade;

		private static IntPtr _herdGoalPtr = IntPtr.Zero;

		private static IntPtr _herdNodePtr = IntPtr.Zero;

		internal static void ResetState()
		{
			_goalPtr = IntPtr.Zero;
			_nodePtr = IntPtr.Zero;
			_nodeReachable = false;
			_loggedPin = false;
			_loggedUpgrade = false;
			_herdGoalPtr = IntPtr.Zero;
			_herdNodePtr = IntPtr.Zero;
		}

		internal static void Reassert(Human cook, NewGameLocation lab)
		{
			try
			{
				if ((Object)(object)cook == (Object)null || (Object)(object)lab == (Object)null)
				{
					return;
				}
				NewAIController val = null;
				try
				{
					val = ((Actor)cook).ai;
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				NewNode val2 = null;
				bool flag = false;
				try
				{
					val2 = cook.FindSafeTeleport(lab, false, true);
				}
				catch
				{
				}
				if (val2 != null)
				{
					flag = true;
				}
				if (val2 == null)
				{
					try
					{
						val2 = lab.anchorNode;
					}
					catch
					{
					}
				}
				if (val2 == null)
				{
					return;
				}
				NewAIGoal val3 = FindGoalForLocation(val, lab);
				if (val3 == null || (flag && !_nodeReachable))
				{
					RemoveAllSiteGoals(val, lab);
					AIGoalPreset val4 = null;
					try
					{
						RoutineControls instance = RoutineControls.Instance;
						if ((Object)(object)instance != (Object)null)
						{
							val4 = instance.toGoWalkGoal;
							if ((SoCustomComparison)(object)val4 == (SoCustomComparison)null)
							{
								val4 = instance.toGoGoal;
							}
						}
					}
					catch
					{
					}
					if ((SoCustomComparison)(object)val4 == (SoCustomComparison)null)
					{
						return;
					}
					NewAIGoal val5 = null;
					try
					{
						val5 = val.CreateNewGoal(val4, NowHours(), 9999f, val2, (Interactable)null, lab, (SocialGroup)null, (Murder)null, -2);
					}
					catch (Exception ex)
					{
						Log("CreateNewGoal threw: " + ex.Message);
						return;
					}
					if (val5 == null)
					{
						return;
					}
					val3 = val5;
					try
					{
						_nodePtr = ((Il2CppObjectBase)val2).Pointer;
					}
					catch
					{
					}
					try
					{
						_goalPtr = ((Il2CppObjectBase)val3).Pointer;
					}
					catch
					{
					}
					_nodeReachable = flag;
					if (!_loggedPin)
					{
						_loggedPin = true;
						Log($"pinned {NarcoticsPlugin.Name(cook)} to lab {LName(lab)} (node={(flag ? "reachable" : "anchor-fallback, will upgrade when the lab streams")}, priority 100000).");
					}
					else if (flag && !_loggedUpgrade)
					{
						_loggedUpgrade = true;
						Log("upgraded " + NarcoticsPlugin.Name(cook) + "'s lab pin to a reachable node; they can path now.");
					}
				}
				try
				{
					val3.basePriority = 100000f;
				}
				catch
				{
				}
				try
				{
					val3.priority = 100000f;
				}
				catch
				{
				}
				try
				{
					val3.isActive = true;
				}
				catch
				{
				}
				try
				{
					val.currentGoal = val3;
				}
				catch
				{
				}
			}
			catch (Exception ex2)
			{
				Log("Reassert error: " + ex2.Message);
			}
		}

		internal static void Release(Human cook, NewGameLocation lab)
		{
			try
			{
				if ((Object)(object)cook == (Object)null)
				{
					return;
				}
				NewAIController val = null;
				try
				{
					val = ((Actor)cook).ai;
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				int value = GoalCount(val);
				int num = 0;
				if ((Object)(object)lab != (Object)null)
				{
					num += RemoveAllSiteGoals(val, lab);
				}
				if (_goalPtr != IntPtr.Zero && RemoveGoalByPtr(val, _goalPtr))
				{
					num++;
				}
				try
				{
					NewAIGoal currentGoal = val.currentGoal;
					if (currentGoal == null || ((Il2CppObjectBase)currentGoal).Pointer == _goalPtr)
					{
						val.currentGoal = null;
					}
				}
				catch
				{
				}
				int value2 = GoalCount(val);
				Log($"released {NarcoticsPlugin.Name(cook)}: removed {num} pin goal(s), goals {value}->{value2}, currentGoal cleared; routine resumes.");
			}
			catch (Exception ex)
			{
				Log("Release error: " + ex.Message);
			}
			finally
			{
				ResetState();
			}
		}

		private static int GoalCount(NewAIController ai)
		{
			try
			{
				return ai.goals?.Count ?? (-1);
			}
			catch
			{
				return -1;
			}
		}

		internal static void RemoveLabGoal(Human cook)
		{
			try
			{
				NewAIController val = null;
				try
				{
					val = (((Object)(object)cook != (Object)null) ? ((Actor)cook).ai : null);
				}
				catch
				{
				}
				if (!((Object)(object)val == (Object)null))
				{
					if (_goalPtr != IntPtr.Zero)
					{
						RemoveGoalByPtr(val, _goalPtr);
						_goalPtr = IntPtr.Zero;
					}
					_nodePtr = IntPtr.Zero;
					_nodeReachable = false;
				}
			}
			catch
			{
			}
		}

		internal static bool HerdToActor(Human cook, Actor target, float rangeM)
		{
			//IL_01e6: 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)
			try
			{
				if ((Object)(object)cook == (Object)null || (Object)(object)target == (Object)null)
				{
					return false;
				}
				NewAIController val = null;
				try
				{
					val = ((Actor)cook).ai;
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				NewNode val2 = null;
				try
				{
					val2 = target.currentNode;
				}
				catch
				{
				}
				if (val2 == null)
				{
					return false;
				}
				NewAIGoal val3 = FindGoalByPtr(val, _herdGoalPtr);
				bool flag = false;
				try
				{
					flag = _herdNodePtr != IntPtr.Zero && ((Il2CppObjectBase)val2).Pointer == _herdNodePtr;
				}
				catch
				{
				}
				if (val3 == null || !flag)
				{
					if (_herdGoalPtr != IntPtr.Zero)
					{
						RemoveGoalByPtr(val, _herdGoalPtr);
						_herdGoalPtr = IntPtr.Zero;
					}
					AIGoalPreset val4 = null;
					try
					{
						RoutineControls instance = RoutineControls.Instance;
						if ((Object)(object)instance != (Object)null)
						{
							val4 = instance.toGoWalkGoal;
							if ((SoCustomComparison)(object)val4 == (SoCustomComparison)null)
							{
								val4 = instance.toGoGoal;
							}
						}
					}
					catch
					{
					}
					if ((SoCustomComparison)(object)val4 == (SoCustomComparison)null)
					{
						return false;
					}
					NewGameLocation val5 = null;
					try
					{
						val5 = target.currentGameLocation;
					}
					catch
					{
					}
					NewAIGoal val6 = null;
					try
					{
						val6 = val.CreateNewGoal(val4, NowHours(), 9999f, val2, (Interactable)null, val5, (SocialGroup)null, (Murder)null, -2);
					}
					catch (Exception ex)
					{
						Log("HerdToActor CreateNewGoal threw: " + ex.Message);
						return false;
					}
					if (val6 == null)
					{
						return false;
					}
					val3 = val6;
					try
					{
						_herdNodePtr = ((Il2CppObjectBase)val2).Pointer;
					}
					catch
					{
					}
					try
					{
						_herdGoalPtr = ((Il2CppObjectBase)val3).Pointer;
					}
					catch
					{
					}
				}
				try
				{
					val3.basePriority = 100000f;
				}
				catch
				{
				}
				try
				{
					val3.priority = 100000f;
				}
				catch
				{
				}
				try
				{
					val3.isActive = true;
				}
				catch
				{
				}
				try
				{
					val.currentGoal = val3;
				}
				catch
				{
				}
				try
				{
					NewNode currentNode = ((Actor)cook).currentNode;
					if (currentNode != null)
					{
						if (((Il2CppObjectBase)currentNode).Pointer == ((Il2CppObjectBase)val2).Pointer)
						{
							return true;
						}
						if (Vector3.Distance(currentNode.position, val2.position) <= rangeM)
						{
							return true;
						}
					}
				}
				catch
				{
				}
				return false;
			}
			catch (Exception ex2)
			{
				Log("HerdToActor error: " + ex2.Message);
				return false;
			}
		}

		internal static void ClearHerd(Human cook)
		{
			try
			{
				NewAIController val = null;
				try
				{
					val = (((Object)(object)cook != (Object)null) ? ((Actor)cook).ai : null);
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					_herdGoalPtr = IntPtr.Zero;
					_herdNodePtr = IntPtr.Zero;
					return;
				}
				if (_herdGoalPtr != IntPtr.Zero)
				{
					RemoveGoalByPtr(val, _herdGoalPtr);
					_herdGoalPtr = IntPtr.Zero;
				}
				_herdNodePtr = IntPtr.Zero;
			}
			catch
			{
			}
		}

		private static NewAIGoal FindGoalByPtr(NewAIController ai, IntPtr ptr)
		{
			if (ptr == IntPtr.Zero)
			{
				return null;
			}
			try
			{
				List<NewAIGoal> val = (((Object)(object)ai != (Object)null) ? ai.goals : null);
				if (val == null)
				{
					return null;
				}
				for (int i = 0; i < val.Count; i++)
				{
					NewAIGoal val2 = val[i];
					if (val2 == null)
					{
						continue;
					}
					try
					{
						if (((Il2CppObjectBase)val2).Pointer == ptr)
						{
							return val2;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return null;
		}

		internal static float NowHours()
		{
			try
			{
				SessionData instance = SessionData.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					return instance.gameTime;
				}
			}
			catch
			{
			}
			return 0f;
		}

		private static NewAIGoal FindGoalForLocation(NewAIController ai, NewGameLocation loc)
		{
			try
			{
				List<NewAIGoal> val = (((Object)(object)ai != (Object)null) ? ai.goals : null);
				if (val == null || (Object)(object)loc == (Object)null)
				{
					return null;
				}
				for (int i = 0; i < val.Count; i++)
				{
					NewAIGoal val2 = val[i];
					if (val2 == null)
					{
						continue;
					}
					NewGameLocation val3 = null;
					NewGameLocation val4 = null;
					try
					{
						val3 = val2.gameLocation;
					}
					catch
					{
					}
					try
					{
						val4 = val2.passedGameLocation;
					}
					catch
					{
					}
					try
					{
						if (((Object)(object)val3 != (Object)null && ((Il2CppObjectBase)val3).Pointer == ((Il2CppObjectBase)loc).Pointer) || ((Object)(object)val4 != (Object)null && ((Il2CppObjectBase)val4).Pointer == ((Il2CppObjectBase)loc).Pointer))
						{
							return val2;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static int RemoveAllSiteGoals(NewAIController ai, NewGameLocation loc)
		{
			int num = 0;
			try
			{
				HashSet<IntPtr> hashSet = new HashSet<IntPtr>();
				for (int i = 0; i < 16; i++)
				{
					NewAIGoal val = FindGoalForLocation(ai, loc);
					if (val == null)
					{
						return num;
					}
					IntPtr pointer;
					try
					{
						pointer = ((Il2CppObjectBase)val).Pointer;
					}
					catch
					{
						return num;
					}
					if (!hashSet.Add(pointer))
					{
						return num;
					}
					try
					{
						val.basePriority = 0f;
						val.priority = 0f;
						val.isActive = false;
					}
					catch
					{
					}
					try
					{
						val.Remove();
						num++;
					}
					catch
					{
						return num;
					}
				}
			}
			catch
			{
			}
			return num;
		}

		private static bool RemoveGoalByPtr(NewAIController ai, IntPtr ptr)
		{
			try
			{
				List<NewAIGoal> val = (((Object)(object)ai != (Object)null) ? ai.goals : null);
				if (val == null)
				{
					return false;
				}
				int num = 0;
				try
				{
					num = val.Count;
				}
				catch
				{
				}
				for (int i = 0; i < num; i++)
				{
					NewAIGoal val2 = val[i];
					if (val2 == null)
					{
						continue;
					}
					IntPtr pointer;
					try
					{
						pointer = ((Il2CppObjectBase)val2).Pointer;
					}
					catch
					{
						continue;
					}
					if (!(pointer != ptr))
					{
						try
						{
							val2.basePriority = 0f;
							val2.priority = 0f;
							val2.isActive = false;
						}
						catch
						{
						}
						try
						{
							val2.Remove();
						}
						catch
						{
						}
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		internal static string LName(NewGameLocation l)
		{
			try
			{
				return ((Object)(object)l != (Object)null) ? ((Object)l).name : "<null>";
			}
			catch
			{
				return "?";
			}
		}

		private static void Log(string m)
		{
			NarcoticsPlugin.Log.LogInfo((object)("[Narcotics][cook] " + m));
		}
	}
	internal static class Diagnostics
	{
		private static float _bannerRestoreAt = -1f;

		private static int _npcCycle;

		private static int _dropCycle;

		private static int _testDrugCycle;

		private static readonly Random _testRng = new Random();

		internal static void Register()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0015: 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_0037: Expected O, but got Unknown
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			bool flag = default(bool);
			try
			{
				ClassInjector.RegisterTypeInIl2Cpp<NarcoticsHotkey>();
				GameObject val = new GameObject("Narcotics_Debug");
				Object.DontDestroyOnLoad((Object)val);
				((Object)val).hideFlags = (HideFlags)61;
				val.AddComponent<NarcoticsHotkey>();
				ManualLogSource log = NarcoticsPlugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(361, 15, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics] Debug hotkeys (need [Debug] EnableDebugKeys): ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyTeleportNPC);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=teleport to next NPC, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyDropTeleport);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=teleport to next dead drop, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyForceSale);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=force a sale, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyStartOp);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=start op, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyStopOp);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=stop op, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyGodMode);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=god mode, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyOverdose);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=overdose nearest NPC, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyArrestTeleport);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=teleport to subject, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyLogPanel);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=log panel, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyTeleportLab);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=to lab, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyDressLab);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=dress lab, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyTimeBoost);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=fast-forward, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyUnlockComputer);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=log into the computer you're using (skip password), ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeySpawnFurniture);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=spawn lab furniture in your room (test), ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(NarcoticsConfig.KeyDump);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("=substrate dump.");
				}
				log.LogInfo(val2);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = NarcoticsPlugin.Log;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics] hotkey register failed: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val3);
			}
		}

		internal static void DumpSubstrate()
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Expected O, but got Unknown
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Expected O, but got Unknown
			ManualLogSource log = NarcoticsPlugin.Log;
			log.LogInfo((object)"[Narcotics] ===== SUBSTRATE DUMP =====");
			bool flag = default(bool);
			try
			{
				CityData instance = CityData.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					int num = -1;
					int num2 = -1;
					int num3 = -1;
					int num4 = -1;
					try
					{
						num = ((instance.homelessDirectory != null) ? instance.homelessDirectory.Count : (-1));
					}
					catch
					{
					}
					try
					{
						num2 = ((instance.citizenDirectory != null) ? instance.citizenDirectory.Count : (-1));
					}
					catch
					{
					}
					try
					{
						num4 = ((instance.homedDirectory != null) ? instance.homedDirectory.Count : (-1));
					}
					catch
					{
					}
					try
					{
						num3 = ((instance.addressDirectory != null) ? instance.addressDirectory.Count : (-1));
					}
					catch
					{
					}
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(53, 4, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Narcotics]  homeless=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  homed=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num4);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  citizens=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  addresses=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num3);
					}
					log.LogInfo(val);
				}
				else
				{
					log.LogInfo((object)"[Narcotics]  CityData.Instance null (load a game first)");
				}
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics]  city dump error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
			log.LogInfo((object)"[Narcotics]  --- drug-ish item presets (name scan) ---");
			DrugItem.FindBasePreset(logAll: true);
			log.LogInfo((object)"[Narcotics]  --- lab-reading furniture clusters (name scan) ---");
			try
			{
				Toolbox instance2 = Toolbox.Instance;
				if ((Object)(object)instance2 != (Object)null && instance2.allFurnitureClusters != null)
				{
					int num5 = 0;
					int num6 = 0;
					Enumerator<FurnitureCluster> enumerator = instance2.allFurnitureClusters.GetEnumerator();
					BepInExInfoLogInterpolatedStringHandler val;
					while (enumerator.MoveNext())
					{
						FurnitureCluster current = enumerator.Current;
						num5++;
						string text = null;
						try
						{
							text = (((SoCustomComparison)(object)current != (SoCustomComparison)null) ? ((Object)current).name : null);
						}
						catch
						{
						}
						if (string.IsNullOrEmpty(text))
						{
							continue;
						}
						string text2 = text.ToLowerInvariant();
						if (text2.Contains("lab") || text2.Contains("chem") || text2.Contains("kitchen") || text2.Contains("industr") || text2.Contains("medic") || text2.Contains("counter") || text2.Contains("workbench") || text2.Contains("bench") || text2.Contains("equip") || text2.Contains("machine") || text2.Contains("cook") || text2.Contains("science"))
						{
							num6++;
							val = new BepInExInfoLogInterpolatedStringHandler(26, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Narcotics]    cluster: '");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
							}
							log.LogInfo(val);
						}
					}
					val = new BepInExInfoLogInterpolatedStringHandler(49, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Narcotics]  furniture clusters: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num5);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" total, ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num6);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" lab-ish");
					}
					log.LogInfo(val);
				}
				else
				{
					log.LogInfo((object)"[Narcotics]  Toolbox.allFurnitureClusters null");
				}
			}
			catch (Exception ex2)
			{
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics]  furniture dump error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex2.Message);
				}
				log.LogWarning(val2);
			}
			log.LogInfo((object)"[Narcotics] ===== END DUMP =====");
		}

		internal static void DrugSmokeTest()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			ManualLogSource log = NarcoticsPlugin.Log;
			log.LogInfo((object)"[Narcotics] ===== DRUG SMOKE TEST =====");
			bool flag = default(bool);
			try
			{
				InteractablePreset val = DrugItem.CreateDrug("NarcMysteryDrugA", "Mystery Drug A");
				if ((SoCustomComparison)(object)val == (SoCustomComparison)null)
				{
					log.LogWarning((object)"[Narcotics]  drug create FAILED (see [item] logs; run the substrate dump for item names)");
					return;
				}
				Player instance = Player.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					Interactable val2 = Dose.Create((Human)(object)instance);
					BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(123, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  created a physical dose in your inventory: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>((val2 != null) ? "OK" : "FAILED");
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (you now hold x");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(Dose.CountIn((Human)(object)instance));
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("). Open your inventory to confirm 'Mystery Drug A'.");
					}
					log.LogInfo(val3);
					try
					{
						Interactable val4 = DrugItem.SpawnDoseAtActor(val, (Human)(object)instance, null);
						val3 = new BepInExInfoLogInterpolatedStringHandler(56, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  also placed a loose dose near you: name='");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>((val4 != null) ? SafeItemName(val4) : "<null>");
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'.");
						}
						log.LogInfo(val3);
					}
					catch (Exception ex)
					{
						BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Narcotics]  dose placement error: ");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
						}
						log.LogWarning(val5);
					}
				}
				else
				{
					log.LogInfo((object)"[Narcotics]  Player.Instance null");
				}
			}
			catch (Exception ex2)
			{
				BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Narcotics]  drug smoke test error: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<Exception>(ex2);
				}
				log.LogWarning(val5);
			}
			log.LogInfo((object)"[Narcotics] ===== END DRUG SMOKE TEST =====");
		}

		internal static void CaseSmokeTest()
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			ManualLogSource log = NarcoticsPlugin.Log;
			log.LogInfo((object)"[Narcotics] ===== CASE SMOKE TEST (direct construct, no popup) =====");
			bool flag2 = default(bool);
			try
			{
				CasePanelController instance = CasePanelController.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					log.LogWarning((object)"[Narcotics]  CasePanelController.Instance null (load a game)");
					return;
				}
				int num = -1;
				try
				{
					num = ((instance.activeCases != null) ? instance.activeCases.Count : (-1));
				}
				catch
				{
				}
				Case val = new Case("New Drug on the Street", (CaseType)3, (CaseStatus)0);
				int num2 = -1;
				try
				{
					num2 = ((instance.activeCases != null) ? instance.activeCases.Count : (-1));
				}
				catch
				{
				}
				bool flag = false;
				try
				{
					flag = instance.activeCases != null && instance.activeCases.Contains(val);
				}
				catch
				{
				}
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(63, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics]  activeCases before=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" afterCtor=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ctorSelfRegistered=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(flag);
				}
				log.LogInfo(val2);
				if (!flag)
				{
					try
					{
						instance.activeCases.Add(val);
						log.LogInfo((object)"[Narcotics]  manually added case to activeCases");
					}
					catch (Exception ex)
					{
						BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  activeCases.Add failed: ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
						}
						log.LogWarning(val3);
					}
				}
				try
				{
					instance.SetActiveCase(val);
				}
				catch (Exception ex2)
				{
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  SetActiveCase failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex2.Message);
					}
					log.LogWarning(val3);
				}
				try
				{
					instance.UpdateCaseButtonsActive();
				}
				catch (Exception ex3)
				{
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  UpdateCaseButtonsActive failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex3.Message);
					}
					log.LogWarning(val3);
				}
				try
				{
					instance.UpdateCaseControls();
				}
				catch (Exception ex4)
				{
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  UpdateCaseControls failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex4.Message);
					}
					log.LogWarning(val3);
				}
				int num3 = -1;
				try
				{
					num3 = ((instance.activeCases != null) ? instance.activeCases.Count : (-1));
				}
				catch
				{
				}
				val2 = new BepInExInfoLogInterpolatedStringHandler(110, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics]  built custom case type=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(SafeType(val));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" status=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(SafeStatus(val));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; activeCases now ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num3);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". Check the board (should appear with NO popup).");
				}
				log.LogInfo(val2);
				Announce("NEW NARCOTICS CASE");
			}
			catch (Exception ex5)
			{
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  case smoke test error: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex5);
				}
				log.LogWarning(val3);
			}
			log.LogInfo((object)"[Narcotics] ===== END CASE SMOKE TEST =====");
		}

		internal static void Announce(string message)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			ManualLogSource log = NarcoticsPlugin.Log;
			bool flag = default(bool);
			try
			{
				InterfaceController instance = InterfaceController.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					log.LogWarning((object)"[Narcotics]  Announce: InterfaceController.Instance null");
					return;
				}
				Patch_Strings_Get.BannerOverride = message;
				_bannerRestoreAt = Time.time + 2f;
				instance.NewMurderCaseDisplay();
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Narcotics]  fired big banner with text '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(message);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
				}
				log.LogInfo(val);
			}
			catch (Exception ex)
			{
				Patch_Strings_Get.BannerOverride = null;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics]  Announce error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogWarning(val2);
			}
		}

		internal static void TickBannerRestore()
		{
			if (_bannerRestoreAt < 0f)
			{
				return;
			}
			try
			{
				if (!(Time.time < _bannerRestoreAt))
				{
					Patch_Strings_Get.BannerOverride = null;
				}
			}
			catch
			{
			}
			finally
			{
				_bannerRestoreAt = -1f;
			}
		}

		internal static void RevealMurder()
		{
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Expected O, but got Unknown
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Expected O, but got Unknown
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Expected O, but got Unknown
			//IL_0114: 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_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			//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)
			ManualLogSource log = NarcoticsPlugin.Log;
			bool flag = default(bool);
			try
			{
				MurderController instance = MurderController.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					log.LogInfo((object)"[Narcotics][case] no MurderController (load a game first).");
					return;
				}
				List<Murder> activeMurders = instance.activeMurders;
				int num = 0;
				try
				{
					num = activeMurders?.Count ?? 0;
				}
				catch
				{
				}
				Murder val = null;
				try
				{
					val = instance.GetCurrentMurder();
				}
				catch
				{
				}
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(81, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics][case] ===== ACTIVE CASES (activeMurders=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; narcoticsCaseActive=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(Operation.Active);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") =====");
				}
				log.LogInfo(val2);
				if (num == 0)
				{
					log.LogInfo((object)"[Narcotics][case]  none right now - no active murder/sniper/kidnapping (wait for one, or it was solved).");
					return;
				}
				for (int i = 0; i < num; i++)
				{
					Murder val3 = null;
					try
					{
						val3 = activeMurders[i];
					}
					catch
					{
					}
					if (val3 == null)
					{
						continue;
					}
					string text = "?";
					try
					{
						MurderPreset preset = val3.preset;
						if ((SoCustomComparison)(object)preset != (SoCustomComparison)null)
						{
							text = ((object)preset.caseType/*cast due to .constrained prefix*/).ToString();
						}
					}
					catch
					{
					}
					string text2 = "?";
					try
					{
						text2 = ((object)val3.state/*cast due to .constrained prefix*/).ToString();
					}
					catch
					{
					}
					bool flag2 = false;
					try
					{
						flag2 = val != null && ((Il2CppObjectBase)val3).Pointer == ((Il2CppObjectBase)val).Pointer;
					}
					catch
					{
					}
					val2 = new BepInExInfoLogInterpolatedStringHandler(41, 4, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics][case] --- case ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(i);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text.ToUpperInvariant());
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("  state=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2);
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag2 ? "  [current]" : "");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ---");
					}
					log.LogInfo(val2);
					Human h = null;
					Human h2 = null;
					try
					{
						h = val3.murderer;
					}
					catch
					{
					}
					try
					{
						h2 = val3.victim;
					}
					catch
					{
					}
					val2 = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics][case]   ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>((text == "kidnap") ? "KIDNAPPER" : "PERPETRATOR");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(WhoAddr(h));
					}
					log.LogInfo(val2);
					val2 = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics][case]   VICTIM:     ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(WhoAddr(h2));
					}
					log.LogInfo(val2);
					string text3 = "?";
					try
					{
						if ((Object)(object)val3.location != (Object)null)
						{
							text3 = ((Object)val3.location).name;
						}
					}
					catch
					{
					}
					val2 = new BepInExInfoLogInterpolatedStringHandler(53, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics][case]   scene/held-at (Murder.location): ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text3);
					}
					log.LogInfo(val2);
					if (text == "kidnap")
					{
						bool flag3 = false;
						int num2 = -1;
						int num3 = -1;
						int num4 = -1;
						int num5 = -1;
						bool flag4 = false;
						try
						{
							flag3 = val3.kidnapKillPhase;
						}
						catch
						{
						}
						try
						{
							num2 = val3.victimSiteID;
						}
						catch
						{
						}
						try
						{
							flag4 = val3.victimSiteIsStreet;
						}
						catch
						{
						}
						try
						{
							num3 = val3.ransomSiteID;
						}
						catch
						{
						}
						try
						{
							num5 = val3.ransomAmount;
						}
						catch
						{
						}
						try
						{
							num4 = val3.addressID;
						}
						catch
						{
						}
						val2 = new BepInExInfoLogInterpolatedStringHandler(110, 9, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics][case]   KIDNAP: kidnapKillPhase=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(flag3);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("  victimSiteID=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("(street=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(flag4);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")->");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(LocNameById(num2));
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("  ransomSiteID=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num3);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("->");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(LocNameById(num3));
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("  ransom=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num5);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("  addressID=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num4);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("->");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(LocNameById(num4));
						}
						log.LogInfo(val2);
					}
				}
				log.LogInfo((object)"[Narcotics][case] ===== END =====");
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Narcotics][case] reveal error: ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val4);
			}
		}

		private static string WhoAddr(Human h)
		{
			if ((Object)(object)h == (Object)null)
			{
				return "<none>";
			}
			string value = "?";
			int value2 = -1;
			bool flag = false;
			try
			{
				value = h.citizenName;
			}
			catch
			{
			}
			try
			{
				value2 = h.humanID;
			}
			catch
			{
			}
			try
			{
				flag = ((Actor)h).isDead;
			}
			catch
			{
			}
			string value3 = "?";
			try
			{
				if ((Object)(object)h.home != (Object)null)
				{
					value3 = ((Object)h.home).name;
				}
			}
			catch
			{
			}
			string value4 = "-";
			try
			{
				Occupation job = h.job;
				if (job != null)
				{
					Company employer = job.employer;
					if (employer != null)
					{
						string text = "?";
						string text2 = "?";
						try
						{
							text = employer.name;
						}
						catch
						{
						}
						try
						{
							if ((Object)(object)employer.address != (Object)null)
							{
								text2 = ((Object)employer.address).name;
							}
						}
						catch
						{
						}
						value4 = text + " @ " + text2;
					}
				}
			}
			catch
			{
			}
			return $"{value} #{value2}{(flag ? " (DEAD)" : "")}  home: {value3}  work: {value4}";
		}

		private static string LocNameById(int id)
		{
			try
			{
				if (id < 0)
				{
					return "-";
				}
				CityData instance = CityData.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return "?";
				}
				try
				{
					List<NewGameLocation> gameLocationDirectory = instance.gameLocationDirectory;
					if (gameLocationDirectory != null && id < gameLocationDirectory.Count)
					{
						NewGameLocation val = gameLocationDirectory[id];
						if ((Object)(object)val != (Object)null)
						{
							return ((Object)val).name;
						}
					}
				}
				catch
				{
				}
				try
				{
					List<NewAddress> addressDirectory = instance.addressDirectory;
					if (addressDirectory != null && id < addressDirectory.Count)
					{
						NewAddress val2 = addressDirectory[id];
						if ((Object)(object)val2 != (Object)null)
						{
							return ((Object)val2).name;
						}
					}
				}
				catch
				{
				}
				return "?";
			}
			catch
			{
				return "?";
			}
		}

		internal static void TeleportToCityHall()
		{
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			ManualLogSource log = NarcoticsPlugin.Log;
			bool flag = default(bool);
			try
			{
				CityData instance = CityData.Instance;
				Player instance2 = Player.Instance;
				if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
				{
					log.LogInfo((object)"[Narcotics][cityhall] no city/player.");
					return;
				}
				List<NewGameLocation> gameLocationDirectory = instance.gameLocationDirectory;
				if (gameLocationDirectory == null)
				{
					log.LogInfo((object)"[Narcotics][cityhall] no location directory.");
					return;
				}
				for (int i = 0; i < gameLocationDirectory.Count; i++)
				{
					NewGameLocation val = gameLocationDirectory[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					string text = null;
					try
					{
						text = ((Object)val).name;
					}
					catch
					{
					}
					if (string.IsNullOrEmpty(text) || text.IndexOf("City Hall", StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					NewNode val2 = null;
					try
					{
						val2 = ((Human)instance2).FindSafeTeleport(val, false, true);
					}
					catch
					{
					}
					if (val2 == null)
					{
						try
						{
							val2 = val.anchorNode;
						}
						catch
						{
						}
					}
					if (val2 == null)
					{
						try
						{
							List<NewNode> nodes = val.nodes;
							if (nodes != null && nodes.Count > 0)
							{
								val2 = nodes[0];
							}
						}
						catch
						{
						}
					}
					if (val2 != null)
					{
						((Actor)instance2).Teleport(val2, (UsagePoint)null, true, false, true);
						BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics][cityhall] teleported to ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
						}
						log.LogInfo(val3);
						return;
					}
				}
				log.LogInfo((object)"[Narcotics][cityhall] found City Hall but no reachable node.");
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Narcotics][cityhall] teleport error: ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val4);
			}
		}

		internal static void TeleportToLab()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			ManualLogSource log = NarcoticsPlugin.Log;
			bool flag = default(bool);
			try
			{
				if (!Operation.Active || (Object)(object)Operation.LabLoc == (Object)null)
				{
					log.LogWarning((object)"[Narcotics]  no active lab (press Start first)");
					return;
				}
				Player instance = Player.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				NewNode val = null;
				try
				{
					val = ((Human)instance).FindSafeTeleport(Operation.LabLoc, false, true);
				}
				catch
				{
				}
				if (val == null)
				{
					log.LogWarning((object)"[Narcotics]  no safe teleport node at the lab");
					return;
				}
				((Actor)instance).Teleport(val, (UsagePoint)null, true, false, true);
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(31, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Narcotics]  teleported to lab ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Cook.LName(Operation.LabLoc));
				}
				log.LogInfo(val2);
				Operation.Status();
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics]  TeleportToLab error: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val3);
			}
		}

		internal static void UnlockActiveComputer()
		{
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			ManualLogSource log = NarcoticsPlugin.Log;
			bool flag2 = default(bool);
			try
			{
				Il2CppArrayBase<ComputerController> val = Object.FindObjectsOfType<ComputerController>();
				if (val == null || val.Length == 0)
				{
					log.LogWarning((object)"[Narcotics]  no computer in the loaded scene (sit at one first).");
					return;
				}
				int num = 0;
				for (int i = 0; i < val.Length; i++)
				{
					ComputerController val2 = val[i];
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					bool flag = false;
					try
					{
						flag = val2.playerControlled;
					}
					catch
					{
					}
					if (!flag)
					{
						continue;
					}
					Human val3 = null;
					try
					{
						val3 = (((Object)(object)val2.ic != (Object)null) ? val2.ic.belongsTo : null);
					}
					catch
					{
					}
					if ((Object)(object)val3 == (Object)null)
					{
						try
						{
							val3 = (Human)(object)Player.Instance;
						}
						catch
						{
						}
					}
					if ((Object)(object)val3 == (Object)null)
					{
						log.LogWarning((object)"[Narcotics]  computer has no owner account to log in as.");
						continue;
					}
					try
					{
						val2.SetLoggedIn(val3);
						num++;
						BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(89, 1, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Narcotics]  logged into the computer as ");
							((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(NarcoticsPlugin.Name(val3));
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" - password bypassed. Open the Surveillance app.");
						}
						log.LogInfo(val4);
					}
					catch (Exception ex)
					{
						BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Narcotics]  SetLoggedIn failed: ");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
						}
						log.LogWarning(val5);
					}
				}
				if (num == 0)
				{
					log.LogWarning((object)"[Narcotics]  you aren't using a computer right now - sit at one (the login screen), then press the key.");
				}
			}
			catch (Exception ex2)
			{
				BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Narcotics]  UnlockActiveComputer error: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex2.Message);
				}
				log.LogWarning(val5);
			}
		}

		internal static void DumpResolveQuestions()
		{
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = NarcoticsPlugin.Log;
			bool flag = default(bool);
			try
			{
				CasePanelController instance = CasePanelController.Instance;
				List<Case> val = (((Object)(object)instance != (Object)null) ? instance.activeCases : null);
				if (val == null || val.Count == 0)
				{
					log.LogWarning((object)"[Narcotics]  no active cases to dump");
					return;
				}
				for (int i = 0; i < val.Count; i++)
				{
					Case val2 = val[i];
					if (val2 == null)
					{
						continue;
					}
					string text = "?";
					try
					{
						text = ((object)val2.caseType/*cast due to .constrained prefix*/).ToString();
					}
					catch
					{
					}
					string text2 = "?";
					try
					{
						text2 = val2.name;
					}
					catch
					{
					}
					List<ResolveQuestion> resolveQuestions = val2.resolveQuestions;
					BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(42, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics][dump] CASE '");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text2);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' type=");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" questions=");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(resolveQuestions?.Count ?? 0);
					}
					log.LogInfo(val3);
					if (resolveQuestions == null)
					{
						continue;
					}
					for (int j = 0; j < resolveQuestions.Count; j++)
					{
						ResolveQuestion val4 = resolveQuestions[j];
						if (val4 == null)
						{
							continue;
						}
						string text3 = "?";
						string text4 = "?";
						string text5 = "";
						string text6 = "";
						string text7 = "";
						try
						{
							text3 = val4.name;
						}
						catch
						{
						}
						try
						{
							text4 = ((object)val4.inputType/*cast due to .constrained prefix*/).ToString();
						}
						catch
						{
						}
						try
						{
							if (val4.correctAnswers != null)
							{
								for (int k = 0; k < val4.correctAnswers.Count; k++)
								{
									text5 = text5 + ((k > 0) ? "|" : "") + val4.correctAnswers[k];
								}
							}
						}
						catch
						{
						}
						try
						{
							text6 = val4.input;
						}
						catch
						{
						}
						try
						{
							text7 = val4.inputtedEvidence;
						}
						catch
						{
						}
						bool flag2 = false;
						try
						{
							flag2 = val4.isOptional;
						}
						catch
						{
						}
						val3 = new BepInExInfoLogInterpolatedStringHandler(73, 7, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Narcotics][dump]   q");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(j);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": input=");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text4);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" opt=");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<bool>(flag2);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" name='");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text3);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' correct='");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text5);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' input='");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text6);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' inputEv='");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text7);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'");
						}
						log.LogInfo(val3);
					}
				}
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Narcotics]  DumpResolveQuestions error: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val5);
			}
		}

		internal static bool TeleportOnto(Human target)
		{
			try
			{
				Player instance = Player.Instance;
				if ((Object)(object)instance == (Object)null || (Object)(object)target == (Object)null)
				{
					return false;
				}
				NewNode val = null;
				try
				{
					val = ((Actor)target).currentNode;
				}
				catch
				{
				}
				if (val == null)
				{
					try
					{
						val = ((Human)instance).FindSafeTeleport(((Actor)target).currentGameLocation, false, true);
					}
					catch
					{
					}
				}
				if (val == null)
				{
					return false;