Decompiled source of Procedural Narcotics Cases v0.1.4
BepInEx/plugins/Narcotics/Narcotics.dll
Decompiled 8 hours ago
The result has been truncated due to the large size, download it to view full contents!
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;