Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of NACops MONO v2.0.1
NACopsV1.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FishNet.Connection; using FishNet.Managing; using FishNet.Managing.Object; using FishNet.Object; using HarmonyLib; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using NACopsV1; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using ScheduleOne; using ScheduleOne.AvatarFramework; using ScheduleOne.AvatarFramework.Customization; using ScheduleOne.AvatarFramework.Equipping; using ScheduleOne.Building.Doors; using ScheduleOne.Combat; using ScheduleOne.DevUtilities; using ScheduleOne.Doors; using ScheduleOne.Economy; using ScheduleOne.Employees; using ScheduleOne.EntityFramework; using ScheduleOne.GameTime; using ScheduleOne.ItemFramework; using ScheduleOne.Law; using ScheduleOne.Management; using ScheduleOne.Map; using ScheduleOne.Money; using ScheduleOne.NPCs; using ScheduleOne.NPCs.Behaviour; using ScheduleOne.ObjectScripts; using ScheduleOne.Persistence; using ScheduleOne.PlayerScripts; using ScheduleOne.Police; using ScheduleOne.Product; using ScheduleOne.Property; using ScheduleOne.Quests; using ScheduleOne.Storage; using ScheduleOne.UI; using ScheduleOne.UI.Handover; using ScheduleOne.UI.MainMenu; using ScheduleOne.Vision; using ScheduleOne.VoiceOver; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(NACops), "NACopsV1", "2.0.1", "XOWithSauce", null)] [assembly: MelonColor] [assembly: MelonOptionalDependencies(new string[] { "FishNet.Runtime" })] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("XOWithSauce")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright XOWithSauce 2026 Source MIT")] [assembly: AssemblyDescription("Schedule I NACops Mod")] [assembly: AssemblyFileVersion("2.0.1.0")] [assembly: AssemblyInformationalVersion("2.0.1")] [assembly: AssemblyProduct("NACops")] [assembly: AssemblyTitle("NACopsV1")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/XOWithSauce/schedule-nacops")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NACopsV1 { public class FootPatrolGenerator { public static Dictionary<PatrolInstance, List<string>> generatedPatrolInstances = new Dictionary<PatrolInstance, List<string>>(); public static ConfigLoader.FootPatrolsSerialized serPatrols; public static PatrolInstance[] GeneratePatrol(LawActivitySettings template, string day = "") { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (generatedPatrolInstances.Count == 0) { DebugModule.Log("Generating new patrol routes", "GeneratePatrol"); Transform parent = ((Component)Singleton<LawController>.Instance).transform.Find("PatrolRoutes"); if (serPatrols == null) { serPatrols = ConfigLoader.LoadPatrolsConfig(); } foreach (SerializedFootPatrol loadedPatrol in serPatrols.loadedPatrols) { GameObject val = new GameObject(loadedPatrol.name); DebugModule.Log("Generate object for patrol: " + loadedPatrol.name, "GeneratePatrol"); DebugModule.Log("- Days: " + string.Join(" ", loadedPatrol.days), "GeneratePatrol"); FootPatrolRoute val2 = val.AddComponent<FootPatrolRoute>(); ((Object)val2).name = loadedPatrol.name; val2.StartWaypointIndex = 0; Transform[] array = (Transform[])(object)new Transform[loadedPatrol.waypoints.Count]; for (int i = 0; i < loadedPatrol.waypoints.Count; i++) { GameObject val3 = new GameObject((i == 0) ? "Waypoint" : $"Waypoint ({i})"); val3.transform.position = loadedPatrol.waypoints[i]; val3.transform.parent = val.transform; array[i] = val3.transform; } val2.Waypoints = array; val.transform.parent = parent; PatrolInstance val4 = new PatrolInstance(); val4.StartTime = loadedPatrol.startTime; val4.EndTime = loadedPatrol.endTime; val4.Members = loadedPatrol.members; val4.Route = val2; val4.OnlyIfCurfewEnabled = loadedPatrol.onlyIfCurfew; val4.IntensityRequirement = loadedPatrol.intensityRequirement; val.transform.parent = parent; val.SetActive(true); generatedPatrolInstances.Add(val4, loadedPatrol.days); } } if (day == "") { int num = template.Patrols.Length; int count = generatedPatrolInstances.Count; int num2 = num + count; PatrolInstance[] array2 = (PatrolInstance[])(object)new PatrolInstance[num2]; Array.Copy(template.Patrols, array2, num); int num3 = num; foreach (KeyValuePair<PatrolInstance, List<string>> generatedPatrolInstance in generatedPatrolInstances) { if (num3 >= num2) { break; } array2[num3] = generatedPatrolInstance.Key; num3++; } return array2; } int num4 = template.Patrols.Length; int num5 = 0; foreach (KeyValuePair<PatrolInstance, List<string>> generatedPatrolInstance2 in generatedPatrolInstances) { if (generatedPatrolInstance2.Value.Contains(day)) { num5++; } } if (num5 == 0) { return template.Patrols; } int num6 = num4 + num5; PatrolInstance[] array3 = (PatrolInstance[])(object)new PatrolInstance[num6]; Array.Copy(template.Patrols, array3, num4); int num7 = num4; foreach (KeyValuePair<PatrolInstance, List<string>> generatedPatrolInstance3 in generatedPatrolInstances) { if (num7 >= num6) { break; } if (generatedPatrolInstance3.Value.Contains(day)) { array3[num7] = generatedPatrolInstance3.Key; num7++; } } DebugModule.Log($" {day}: Added {num5} patrols ({num4} -> {num6})", "GeneratePatrol"); return array3; } } [Serializable] public class SerializedFootPatrol { public int startTime = 1900; public int endTime = 500; public int members = 1; public int intensityRequirement = 1; public bool onlyIfCurfew; public string name = "NACops Extra Loop"; public List<string> days; public List<Vector3> waypoints = new List<Vector3>(); } public class SentryGenerator { public static Dictionary<SentryInstance, List<string>> generatedSentryInstances = new Dictionary<SentryInstance, List<string>>(); public static ConfigLoader.SentrysSerialized serSentries; public static SentryInstance[] GenerateSentry(LawActivitySettings template, string day = "") { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown if (generatedSentryInstances.Count == 0) { DebugModule.Log("Generating new sentry spots", "GenerateSentry"); Transform val = ((Component)Singleton<LawController>.Instance).transform.Find("Sentry Locations"); if ((Object)(object)val == (Object)null) { DebugModule.Log(" Sentry Locations transform is null", "GenerateSentry"); } DebugModule.Log(" Load Sentry Config", "GenerateSentry"); if (serSentries == null) { serSentries = ConfigLoader.LoadSentryConfig(); } DebugModule.Log(" Loaded Patrols config count: " + serSentries.loadedSentrys.Count, "GenerateSentry"); foreach (SerializedSentry loadedSentry in serSentries.loadedSentrys) { GameObject val2 = new GameObject(loadedSentry.name); DebugModule.Log("Generate object for patrol: " + loadedSentry.name, "GenerateSentry"); DebugModule.Log("- Days: " + string.Join(" ", loadedSentry.days), "GenerateSentry"); SentryLocation val3 = val2.AddComponent<SentryLocation>(); val3.StandPoints = new List<Transform>(); GameObject val4 = new GameObject("Stand point"); val4.transform.parent = val2.transform; val4.transform.SetPositionAndRotation(loadedSentry.standPosition1, Quaternion.Euler(loadedSentry.pos1Rotation)); val3.StandPoints.Add(val4.transform); GameObject val5 = new GameObject("Stand point (1)"); val5.transform.parent = val2.transform; val5.transform.SetPositionAndRotation(loadedSentry.standPosition2, Quaternion.Euler(loadedSentry.pos2Rotation)); val3.StandPoints.Add(val5.transform); ((Component)val3).gameObject.SetActive(true); SentryInstance val6 = new SentryInstance(); val6.StartTime = loadedSentry.startTime; val6.EndTime = loadedSentry.endTime; val6.Members = loadedSentry.members; val6.Location = val3; val6.OnlyIfCurfewEnabled = loadedSentry.onlyIfCurfew; val6.IntensityRequirement = loadedSentry.intensityRequirement; val2.transform.parent = val; val2.SetActive(true); generatedSentryInstances.Add(val6, loadedSentry.days); } } if (day == "") { int num = template.Sentries.Length; int count = generatedSentryInstances.Count; int num2 = num + count; SentryInstance[] array = (SentryInstance[])(object)new SentryInstance[num2]; Array.Copy(template.Sentries, array, num); int num3 = num; foreach (KeyValuePair<SentryInstance, List<string>> generatedSentryInstance in generatedSentryInstances) { if (num3 >= num2) { break; } array[num3] = generatedSentryInstance.Key; num3++; } return array; } int num4 = template.Sentries.Length; int num5 = 0; foreach (KeyValuePair<SentryInstance, List<string>> generatedSentryInstance2 in generatedSentryInstances) { if (generatedSentryInstance2.Value.Contains(day)) { num5++; } } if (num5 == 0) { return template.Sentries; } int num6 = num4 + num5; SentryInstance[] array2 = (SentryInstance[])(object)new SentryInstance[num6]; Array.Copy(template.Sentries, array2, num4); int num7 = num4; foreach (KeyValuePair<SentryInstance, List<string>> generatedSentryInstance3 in generatedSentryInstances) { if (num7 >= num6) { break; } if (generatedSentryInstance3.Value.Contains(day)) { array2[num7] = generatedSentryInstance3.Key; num7++; } } DebugModule.Log($" {day}: Added {num5} sentries ({num4} -> {num6})", "GenerateSentry"); return array2; } } [Serializable] public class SerializedSentry { public int startTime = 1900; public int endTime = 500; public int members = 1; public int intensityRequirement = 1; public bool onlyIfCurfew; public string name; public List<string> days; public Vector3 standPosition1; public Vector3 pos1Rotation; public Vector3 standPosition2; public Vector3 pos2Rotation; } public class VehiclePatrolGenerator { public static Dictionary<VehiclePatrolInstance, List<string>> generatedVehiclePatrolInstances = new Dictionary<VehiclePatrolInstance, List<string>>(); public static ConfigLoader.VehiclePatrolsSerialized serVehiclePatrols; public static VehiclePatrolInstance[] GenerateVehiclePatrol(LawActivitySettings template, string day = "") { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (generatedVehiclePatrolInstances.Count == 0) { DebugModule.Log("Generating new vehicle patrol routes", "GenerateVehiclePatrol"); Transform parent = ((Component)Singleton<LawController>.Instance).transform.Find("VehiclePatrolRoutes"); if (serVehiclePatrols == null) { serVehiclePatrols = ConfigLoader.LoadVehiclePatrolsConfig(); } foreach (SerializedVehiclePatrol loadedVehiclePatrol in serVehiclePatrols.loadedVehiclePatrols) { GameObject val = new GameObject(loadedVehiclePatrol.name); DebugModule.Log("Generate object for patrol: " + loadedVehiclePatrol.name, "GenerateVehiclePatrol"); DebugModule.Log("- Days: " + string.Join(" ", loadedVehiclePatrol.days), "GenerateVehiclePatrol"); VehiclePatrolRoute val2 = val.AddComponent<VehiclePatrolRoute>(); ((Object)val2).name = loadedVehiclePatrol.name; val2.StartWaypointIndex = 0; Transform[] array = (Transform[])(object)new Transform[loadedVehiclePatrol.waypoints.Count]; for (int i = 0; i < loadedVehiclePatrol.waypoints.Count; i++) { GameObject val3 = new GameObject((i == 0) ? "Waypoint" : $"Waypoint ({i})"); val3.transform.position = loadedVehiclePatrol.waypoints[i]; val3.transform.parent = val.transform; array[i] = val3.transform; } val2.Waypoints = array; val.transform.parent = parent; VehiclePatrolInstance val4 = new VehiclePatrolInstance(); val4.StartTime = loadedVehiclePatrol.startTime; val4.Route = val2; val4.IntensityRequirement = loadedVehiclePatrol.intensityRequirement; val4.OnlyIfCurfewEnabled = loadedVehiclePatrol.onlyIfCurfew; val.transform.parent = parent; val.SetActive(true); generatedVehiclePatrolInstances.Add(val4, loadedVehiclePatrol.days); } } if (day == "") { int num = template.VehiclePatrols.Length; int count = generatedVehiclePatrolInstances.Count; int num2 = num + count; VehiclePatrolInstance[] array2 = (VehiclePatrolInstance[])(object)new VehiclePatrolInstance[num2]; Array.Copy(template.VehiclePatrols, array2, num); int num3 = num; foreach (KeyValuePair<VehiclePatrolInstance, List<string>> generatedVehiclePatrolInstance in generatedVehiclePatrolInstances) { if (num3 >= num2) { break; } array2[num3] = generatedVehiclePatrolInstance.Key; num3++; } return array2; } int num4 = template.VehiclePatrols.Length; int num5 = 0; foreach (KeyValuePair<VehiclePatrolInstance, List<string>> generatedVehiclePatrolInstance2 in generatedVehiclePatrolInstances) { if (generatedVehiclePatrolInstance2.Value.Contains(day)) { num5++; } } if (num5 == 0) { return template.VehiclePatrols; } int num6 = num4 + num5; VehiclePatrolInstance[] array3 = (VehiclePatrolInstance[])(object)new VehiclePatrolInstance[num6]; Array.Copy(template.VehiclePatrols, array3, num4); int num7 = num4; foreach (KeyValuePair<VehiclePatrolInstance, List<string>> generatedVehiclePatrolInstance3 in generatedVehiclePatrolInstances) { if (num7 >= num6) { break; } if (generatedVehiclePatrolInstance3.Value.Contains(day)) { array3[num7] = generatedVehiclePatrolInstance3.Key; num7++; } } DebugModule.Log($" {day}: Added {num5} vehicle patrols ({num4} -> {num6})", "GenerateVehiclePatrol"); return array3; } } [Serializable] public class SerializedVehiclePatrol { public int startTime = 2300; public int intensityRequirement = 1; public bool onlyIfCurfew; public string name = "NACops Vehicle Extra Loop"; public List<string> days; public List<Vector3> waypoints = new List<Vector3>(); } [HarmonyPatch(typeof(Customer), "ProcessHandover")] public static class Customer_ProcessHandover_Patch { [CompilerGenerated] private sealed class <DisposeSummoned>d__5 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PoliceOfficer offc; public bool instant; public Player target; private int <lifeTime>5__2; private int <maxTime>5__3; private NPC <npc>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DisposeSummoned>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <npc>5__4 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = NACops.Wait1; <>1__state = 1; return true; case 1: <>1__state = -1; if (!NACops.registered) { return false; } <lifeTime>5__2 = 0; <maxTime>5__3 = 20; <npc>5__4 = ((Component)((NetworkBehaviour)offc).NetworkObject).GetComponent<NPC>(); if (instant || !((Object)(object)target != (Object)null) || !((Object)(object)<npc>5__4 != (Object)null)) { break; } goto IL_00cb; case 2: { <>1__state = -1; if (!NACops.registered) { return false; } goto IL_00cb; } IL_00cb: if (<lifeTime>5__2 <= <maxTime>5__3 || target.IsArrested || <npc>5__4.Health.IsDead || <npc>5__4.Health.IsKnockedOut) { <lifeTime>5__2++; <>2__current = NACops.Wait1; <>1__state = 2; return true; } break; } try { if (NACops.currentSummoned.Contains(offc)) { NACops.currentSummoned.Remove(offc); } if ((Object)(object)<npc>5__4 != (Object)null && NPCManager.NPCRegistry.Contains(<npc>5__4)) { NPCManager.NPCRegistry.Remove(<npc>5__4); } if ((Object)(object)<npc>5__4 != (Object)null && (Object)(object)((Component)<npc>5__4).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)<npc>5__4).gameObject); } } catch (Exception ex) { MelonLogger.Error((object)ex); } DebugModule.Log("Disposed summoned bustcop", "DisposeSummoned"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LateEnableArrest>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PoliceOfficer offc; private float <maxWait>5__2; private float <current>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LateEnableArrest>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if (offc.PursuitBehaviour.arrestingEnabled) { offc.PursuitBehaviour.arrestingEnabled = false; } <current>5__3 += 0.5f; } else { <>1__state = -1; <maxWait>5__2 = 8f; <current>5__3 = 0f; } if (!NACops.registered) { return false; } if (!(<current>5__3 >= <maxWait>5__2)) { <>2__current = NACops.Wait05; <>1__state = 1; return true; } offc.PursuitBehaviour.arrestingEnabled = true; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PreProcessHandover>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public bool handoverByPlayer; public Customer __instance; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PreProcessHandover>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!handoverByPlayer) { return false; } if (NACops.currentConfig.BuyBusts) { NACops.coros.Add(MelonCoroutines.Start(SummonBustCop(__instance))); } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SetTaser>d__4 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PoliceOfficer offc; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SetTaser>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; ((NPC)offc).Behaviour.CombatBehaviour.SetWeapon(((Object)(object)offc.TaserPrefab != (Object)null) ? offc.TaserPrefab.AssetPath : string.Empty); if ((Object)(object)((NPC)offc).Behaviour.CombatBehaviour.currentWeapon == (Object)null) { return false; } AvatarWeapon currentWeapon = ((NPC)offc).Behaviour.CombatBehaviour.currentWeapon; AvatarRangedWeapon val = (AvatarRangedWeapon)(object)((currentWeapon is AvatarRangedWeapon) ? currentWeapon : null); if ((Object)(object)val != (Object)null) { val.CanShootWhileMoving = true; val.MagazineSize = 20; val.MaxFireRate = 0.3f; ((AvatarWeapon)val).MaxUseRange = 24f; val.ReloadTime = 0.2f; val.RaiseTime = 0.1f; val.HitChance_MaxRange = 0.6f; val.HitChance_MinRange = 0.9f; ((AvatarWeapon)val).CooldownDuration = 0.3f; } <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SummonBustCop>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Customer customer; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SummonBustCop>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00b4: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown if (<>1__state != 0) { return false; } <>1__state = -1; int value = Mathf.RoundToInt(customer.NPC.RelationData.RelationDelta * 10f); var (num, num2) = ThresholdUtils.Evaluate(NACops.thresholdConfig.BuyBustProbability, value); if (!NACops.currentConfig.DebugMode && Random.Range(num, num2) < 0.5f) { return false; } PoliceOfficer val = OfficerOverrides.SpawnOfficerRuntime(autoDeactivate: false); ((NPC)val).Movement.PauseMovement(); AvatarUtility.SetRandomAvatar(val); ((NPC)val).Behaviour.ScheduleManager.DisableSchedule(); NACops.currentSummoned.Add(val); Player val2 = null; Vector3 val3 = ((Component)customer).transform.position + ((Component)customer).transform.forward * 3f; Vector3 val4 = default(Vector3); if (((NPC)val).Movement.GetClosestReachablePoint(val3, ref val4) && val4 != Vector3.zero) { NACops.coros.Add(MelonCoroutines.Start(SetTaser(val))); ((NPC)val).Movement.Warp(val4); ((NPC)val).Movement.ResumeMovement(); Vector3 centerPoint = ((NPC)val).CenterPoint; DebugModule.Log("Drug bust officer spawned now at " + ((object)(Vector3)(ref centerPoint)).ToString(), "SummonBustCop"); ((VOEmitter)val.ChatterVO).Play((EVOLineType)2); ((NPC)val).Movement.FacePoint(((Component)customer).transform.position, 0.5f); float num3 = default(float); val2 = Player.GetClosestPlayer(val4, ref num3, (List<Player>)null); val2.CrimeData.SetPursuitLevel((EPursuitLevel)3); val.BeginFootPursuit(val2.PlayerCode); ((Behaviour)val.PursuitBehaviour).Enable_Networked(); NACops.coros.Add(MelonCoroutines.Start(LateEnableArrest(val))); val2.CrimeData.AddCrime((Crime)new AttemptingToSell(), 10); } else { DebugModule.Log("Failed to Get closest reachable position for drug bust", "SummonBustCop"); NACops.coros.Add(MelonCoroutines.Start(DisposeSummoned(val, instant: true, val2))); } NACops.coros.Add(MelonCoroutines.Start(DisposeSummoned(val, instant: false, val2))); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPrefix] public static bool Prefix(Customer __instance, EHandoverOutcome outcome, Contract contract, List<ItemInstance> items, bool handoverByPlayer, bool giveBonuses = true) { NACops.coros.Add(MelonCoroutines.Start(PreProcessHandover(__instance, handoverByPlayer))); return true; } [IteratorStateMachine(typeof(<PreProcessHandover>d__1))] public static IEnumerator PreProcessHandover(Customer __instance, bool handoverByPlayer) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PreProcessHandover>d__1(0) { __instance = __instance, handoverByPlayer = handoverByPlayer }; } [IteratorStateMachine(typeof(<SummonBustCop>d__2))] public static IEnumerator SummonBustCop(Customer customer) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SummonBustCop>d__2(0) { customer = customer }; } [IteratorStateMachine(typeof(<LateEnableArrest>d__3))] public static IEnumerator LateEnableArrest(PoliceOfficer offc) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LateEnableArrest>d__3(0) { offc = offc }; } [IteratorStateMachine(typeof(<SetTaser>d__4))] public static IEnumerator SetTaser(PoliceOfficer offc) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SetTaser>d__4(0) { offc = offc }; } [IteratorStateMachine(typeof(<DisposeSummoned>d__5))] public static IEnumerator DisposeSummoned(PoliceOfficer offc, bool instant, Player target) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DisposeSummoned>d__5(0) { offc = offc, instant = instant, target = target }; } } public class UnityContractResolver : DefaultContractResolver { protected override JsonObjectContract CreateObjectContract(Type objectType) { JsonObjectContract val = ((DefaultContractResolver)this).CreateObjectContract(objectType); if (objectType == typeof(Vector3)) { for (int num = ((Collection<JsonProperty>)(object)val.Properties).Count - 1; num >= 0; num--) { JsonProperty val2 = ((Collection<JsonProperty>)(object)val.Properties)[num]; if (val2.PropertyName == "normalized" || val2.PropertyName == "magnitude" || val2.PropertyName == "sqrMagnitude") { ((Collection<JsonProperty>)(object)val.Properties).RemoveAt(num); } } } return val; } } public static class ConfigLoader { [Serializable] public class ModConfig { public bool DebugMode; public bool RaidsEnabled = true; public bool ExtraOfficerPatrols = true; public bool ExtraVehiclePatrols = true; public bool ExtraOfficerSentries = true; public bool NoOpenCarryWeapons = true; public bool PrivateInvestigator = true; public bool WeedInvestigator = true; public bool CorruptCops = true; public bool SnitchingSamples = true; public bool BuyBusts = true; public bool NearbyCrazyCops = true; public bool LethalCops = true; public bool RacistCops; } [Serializable] public class NAOfficerConfig { public int ModAddedVehicleCount = 3; public int ModAddedOfficersCount = 8; public bool CanEnterBuildings = true; public bool OverrideArresting = true; public float ArrestTime = 1.25f; public float ArrestRange = 3.5f; public bool OverrideMovement = true; public float MovementSpeedMultiplier = 1.7f; public bool OverrideWeapon = true; public string WeaponPath = "Avatar/Equippables/M1911"; public float WeaponDamage = 46f; public int WeaponMagSize = 20; public float WeaponFireRate = 0.33f; public float WeaponMaxRange = 25f; public float WeaponReloadTime = 0.5f; public float WeaponRaiseTime = 0.2f; public float WeaponHitChanceMax = 0.3f; public float WeaponHitChanceMin = 0.8f; public bool OverrideMaxHealth = true; public float OfficerMaxHealth = 175f; public bool OverrideBodySearch = true; public float BodySearchDuration = 6f; public float BodySearchChance = 1f; public bool OverrideCombatBeh = true; public float CombatGiveUpRange = 40f; public float CombatGiveUpTime = 60f; public float CombatSearchTime = 60f; public float CombatMoveSpeed = 6.8f; public int CombatEndAfterHits = 40; } [Serializable] public class RaidConfig { public float TraverseToPropertySpeed = 0.47f; public float ClearPropertySpeed = 0.38f; public int MaxDestroyIters = 4; public int RaidCopsCount = 3; public int DaysUntilCanRaid = 8; public int PropertyHeatThreshold = 14; } [Serializable] public class FootPatrolsSerialized { public List<SerializedFootPatrol> loadedPatrols = new List<SerializedFootPatrol>(); } [Serializable] public class VehiclePatrolsSerialized { public List<SerializedVehiclePatrol> loadedVehiclePatrols = new List<SerializedVehiclePatrol>(); } [Serializable] public class SentrysSerialized { public List<SerializedSentry> loadedSentrys = new List<SerializedSentry>(); } private static string modConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "config.json"); private static string officerConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "officer.json"); private static string patrolsConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "Spawn", "patrols.json"); private static string sentrysConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "Spawn", "sentrys.json"); private static string vehiclePatrolsConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "Spawn", "vehiclepatrols.json"); private static string eventFrequencyConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "progression.json"); private static string raidConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "raid.json"); private static string propertyHeatConfig = Path.Combine(MelonEnvironment.ModsDirectory, "NACops", "HeatData"); public static ModConfig LoadModConfig() { ModConfig modConfig; if (File.Exists(ConfigLoader.modConfig)) { try { modConfig = JsonConvert.DeserializeObject<ModConfig>(File.ReadAllText(ConfigLoader.modConfig)); } catch (Exception ex) { modConfig = new ModConfig(); MelonLogger.Warning("Failed to read NACops Mod config: " + ex); } } else { MelonLogger.Warning("Missing NACops Mod config, creating directory and template."); modConfig = new ModConfig(); Save(modConfig); } return modConfig; } public static void Save(ModConfig config) { try { string contents = JsonConvert.SerializeObject((object)config, (Formatting)1); Directory.CreateDirectory(Path.GetDirectoryName(modConfig)); File.WriteAllText(modConfig, contents); MelonLogger.Warning(" NACops Mod config, written to: " + modConfig); } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Mod config: " + ex); } } public static NAOfficerConfig LoadOfficerConfig() { NAOfficerConfig nAOfficerConfig; if (File.Exists(officerConfig)) { try { nAOfficerConfig = JsonConvert.DeserializeObject<NAOfficerConfig>(File.ReadAllText(officerConfig)); nAOfficerConfig.ModAddedOfficersCount = Mathf.Clamp(nAOfficerConfig.ModAddedOfficersCount, 0, 20); } catch (Exception ex) { nAOfficerConfig = new NAOfficerConfig(); MelonLogger.Warning("Failed to read NACops config: " + ex); } } else { MelonLogger.Warning("Missing NACops Officers config, creating directory and template."); nAOfficerConfig = new NAOfficerConfig(); Save(nAOfficerConfig); } return nAOfficerConfig; } public static void Save(NAOfficerConfig config) { try { string contents = JsonConvert.SerializeObject((object)config); Directory.CreateDirectory(Path.GetDirectoryName(officerConfig)); File.WriteAllText(officerConfig, contents); MelonLogger.Warning(" NACops Officers config, written to: " + officerConfig); } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Officers config: " + ex); } } public static FootPatrolsSerialized LoadPatrolsConfig() { FootPatrolsSerialized footPatrolsSerialized; if (File.Exists(patrolsConfig)) { try { footPatrolsSerialized = JsonConvert.DeserializeObject<FootPatrolsSerialized>(File.ReadAllText(patrolsConfig)); List<string> list = new List<string> { "mon", "tue", "wed", "thu", "fri", "sat", "sun" }; foreach (SerializedFootPatrol loadedPatrol in footPatrolsSerialized.loadedPatrols) { loadedPatrol.members = Mathf.Clamp(loadedPatrol.members, 1, 4); loadedPatrol.name = (string.IsNullOrEmpty(loadedPatrol.name) ? "NaCopsPatrol " : loadedPatrol.name); loadedPatrol.intensityRequirement = Mathf.Clamp(loadedPatrol.intensityRequirement, 0, 10); if (!TimeManager.IsValid24HourTime(loadedPatrol.startTime.ToString())) { MelonLogger.Warning("FootPatrolsConfig '" + loadedPatrol.name + "' has invalid start time"); loadedPatrol.startTime = 1900; } if (!TimeManager.IsValid24HourTime(loadedPatrol.endTime.ToString())) { MelonLogger.Warning("FootPatrolsConfig '" + loadedPatrol.name + "' has invalid end time"); loadedPatrol.endTime = 2330; } if (loadedPatrol.waypoints.Count == 0) { MelonLogger.Warning("FootPatrolsConfig is missing Waypoints for " + loadedPatrol.name); } for (int num = loadedPatrol.days.Count - 1; num != -1; num--) { if (loadedPatrol.days[num] != string.Empty) { loadedPatrol.days[num] = loadedPatrol.days[num].ToLower(); if (!list.Contains(loadedPatrol.days[num])) { MelonLogger.Warning("FootPatrolsConfig '" + loadedPatrol.name + "' has invalid weekday: '" + loadedPatrol.days[num] + "'"); loadedPatrol.days.RemoveAt(num); } } else { loadedPatrol.days.RemoveAt(num); } } } } catch (Exception ex) { footPatrolsSerialized = new FootPatrolsSerialized(); MelonLogger.Warning("Failed to read FootPatrolsSerialized config: " + ex); } } else { footPatrolsSerialized = new FootPatrolsSerialized(); footPatrolsSerialized.loadedPatrols = new List<SerializedFootPatrol>(); Save(footPatrolsSerialized); } return footPatrolsSerialized; } public static void Save(FootPatrolsSerialized config) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown try { JsonSerializerSettings val = new JsonSerializerSettings { ContractResolver = (IContractResolver)(object)new UnityContractResolver() }; string contents = JsonConvert.SerializeObject((object)config, (Formatting)1, val); Directory.CreateDirectory(Path.GetDirectoryName(patrolsConfig)); File.WriteAllText(patrolsConfig, contents); MelonLogger.Warning(" Foot Patrols Config has been saved!"); } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Foot Patrols config: " + ex); } } public static VehiclePatrolsSerialized LoadVehiclePatrolsConfig() { VehiclePatrolsSerialized vehiclePatrolsSerialized; if (File.Exists(vehiclePatrolsConfig)) { try { vehiclePatrolsSerialized = JsonConvert.DeserializeObject<VehiclePatrolsSerialized>(File.ReadAllText(vehiclePatrolsConfig)); List<string> list = new List<string> { "mon", "tue", "wed", "thu", "fri", "sat", "sun" }; foreach (SerializedVehiclePatrol loadedVehiclePatrol in vehiclePatrolsSerialized.loadedVehiclePatrols) { loadedVehiclePatrol.name = (string.IsNullOrEmpty(loadedVehiclePatrol.name) ? "NaCopsVehiclePatrol " : loadedVehiclePatrol.name); loadedVehiclePatrol.intensityRequirement = Mathf.Clamp(loadedVehiclePatrol.intensityRequirement, 0, 10); if (!TimeManager.IsValid24HourTime(loadedVehiclePatrol.startTime.ToString())) { MelonLogger.Warning("Vehicle Patrol Config '" + loadedVehiclePatrol.name + "' has invalid start time"); loadedVehiclePatrol.startTime = 1900; } if (loadedVehiclePatrol.waypoints.Count == 0) { MelonLogger.Warning("Vehicle Patrol Config is missing Waypoints for " + loadedVehiclePatrol.name); } for (int num = loadedVehiclePatrol.days.Count - 1; num != -1; num--) { if (loadedVehiclePatrol.days[num] != string.Empty) { loadedVehiclePatrol.days[num] = loadedVehiclePatrol.days[num].ToLower(); if (!list.Contains(loadedVehiclePatrol.days[num])) { MelonLogger.Warning("Vehicle Patrol Config '" + loadedVehiclePatrol.name + "' has invalid weekday: '" + loadedVehiclePatrol.days[num] + "'"); loadedVehiclePatrol.days.RemoveAt(num); } } else { loadedVehiclePatrol.days.RemoveAt(num); } } } } catch (Exception ex) { vehiclePatrolsSerialized = new VehiclePatrolsSerialized(); MelonLogger.Warning("Failed to read Vehicle Patrol config: " + ex); } } else { vehiclePatrolsSerialized = new VehiclePatrolsSerialized(); vehiclePatrolsSerialized.loadedVehiclePatrols = new List<SerializedVehiclePatrol>(); Save(vehiclePatrolsSerialized); } return vehiclePatrolsSerialized; } public static void Save(VehiclePatrolsSerialized config) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown try { JsonSerializerSettings val = new JsonSerializerSettings { ContractResolver = (IContractResolver)(object)new UnityContractResolver() }; string contents = JsonConvert.SerializeObject((object)config, (Formatting)1, val); Directory.CreateDirectory(Path.GetDirectoryName(vehiclePatrolsConfig)); File.WriteAllText(vehiclePatrolsConfig, contents); MelonLogger.Warning(" Vehicle Patrols config has been saved!"); } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Vehicle Patrols config: " + ex); } } public static SentrysSerialized LoadSentryConfig() { SentrysSerialized sentrysSerialized; if (File.Exists(sentrysConfig)) { try { sentrysSerialized = JsonConvert.DeserializeObject<SentrysSerialized>(File.ReadAllText(sentrysConfig)); List<string> list = new List<string> { "mon", "tue", "wed", "thu", "fri", "sat", "sun" }; foreach (SerializedSentry loadedSentry in sentrysSerialized.loadedSentrys) { loadedSentry.members = Mathf.Clamp(loadedSentry.members, 1, 2); loadedSentry.name = (string.IsNullOrEmpty(loadedSentry.name) ? "NACopsSentry " : loadedSentry.name); loadedSentry.intensityRequirement = Mathf.Clamp(loadedSentry.intensityRequirement, 0, 10); if (!TimeManager.IsValid24HourTime(loadedSentry.startTime.ToString())) { MelonLogger.Warning("Sentry Config '" + loadedSentry.name + "' has invalid start time"); loadedSentry.startTime = 1900; } if (!TimeManager.IsValid24HourTime(loadedSentry.endTime.ToString())) { MelonLogger.Warning("Sentry Config '" + loadedSentry.name + "' has invalid end time"); loadedSentry.endTime = 2330; } for (int num = loadedSentry.days.Count - 1; num != -1; num--) { if (loadedSentry.days[num] != string.Empty) { loadedSentry.days[num] = loadedSentry.days[num].ToLower(); if (!list.Contains(loadedSentry.days[num])) { MelonLogger.Warning("Sentry Config '" + loadedSentry.name + "' has invalid weekday: '" + loadedSentry.days[num] + "'"); loadedSentry.days.RemoveAt(num); } } else { loadedSentry.days.RemoveAt(num); } } } } catch (Exception ex) { sentrysSerialized = new SentrysSerialized(); MelonLogger.Warning("Failed to read SentrysSerialized config: " + ex); } } else { sentrysSerialized = new SentrysSerialized(); sentrysSerialized.loadedSentrys = new List<SerializedSentry>(); Save(sentrysSerialized); } return sentrysSerialized; } public static void Save(SentrysSerialized config) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown try { JsonSerializerSettings val = new JsonSerializerSettings { ContractResolver = (IContractResolver)(object)new UnityContractResolver() }; string contents = JsonConvert.SerializeObject((object)config, (Formatting)1, val); Directory.CreateDirectory(Path.GetDirectoryName(sentrysConfig)); File.WriteAllText(sentrysConfig, contents); MelonLogger.Warning(" Sentry config has been saved!"); } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Sentry config: " + ex); } } public static string SanitizeAndFormatName(string orgName) { string text = orgName; if (text != null) { text = text.Replace(" ", "_").ToLower(); text = text.Replace(",", ""); text = text.Replace(".", ""); text = text.Replace("<", ""); text = text.Replace(">", ""); text = text.Replace(":", ""); text = text.Replace("\"", ""); text = text.Replace("/", ""); text = text.Replace("\\", ""); text = text.Replace("|", ""); text = text.Replace("?", ""); text = text.Replace("*", ""); } return text + ".json"; } public static PropertiesHeatSerialized LoadPropertyHeats() { string path = SanitizeAndFormatName(Singleton<LoadManager>.Instance.ActiveSaveInfo?.OrganisationName); PropertiesHeatSerialized propertiesHeatSerialized; if (File.Exists(Path.Combine(propertyHeatConfig, path))) { try { propertiesHeatSerialized = JsonConvert.DeserializeObject<PropertiesHeatSerialized>(File.ReadAllText(Path.Combine(propertyHeatConfig, path))); } catch (Exception ex) { propertiesHeatSerialized = new PropertiesHeatSerialized(); propertiesHeatSerialized.loadedPropertyHeats = new List<PropertyHeat>(); string[] array = new string[6] { "sweatshop", "bungalow", "storageunit", "dockswarehouse", "barn", "manor" }; foreach (string propertyCode in array) { PropertyHeat propertyHeat = new PropertyHeat(); propertyHeat.propertyCode = propertyCode; propertiesHeatSerialized.loadedPropertyHeats.Add(propertyHeat); } MelonLogger.Warning("Failed to read NACops Property Heat config: " + ex); } } else { MelonLogger.Warning("Missing NACops Property Heat config, creating directory and template."); propertiesHeatSerialized = new PropertiesHeatSerialized(); Save(propertiesHeatSerialized, generateTemplate: true); } return propertiesHeatSerialized; } public static void Save(PropertiesHeatSerialized config, bool generateTemplate = false) { if (generateTemplate) { config.loadedPropertyHeats = new List<PropertyHeat>(); string[] array = new string[6] { "sweatshop", "bungalow", "storageunit", "dockswarehouse", "barn", "manor" }; foreach (string propertyCode in array) { PropertyHeat propertyHeat = new PropertyHeat(); propertyHeat.propertyCode = propertyCode; config.loadedPropertyHeats.Add(propertyHeat); } } try { string path = SanitizeAndFormatName(Singleton<LoadManager>.Instance.ActiveSaveInfo?.OrganisationName); string path2 = Path.Combine(propertyHeatConfig, path); string contents = JsonConvert.SerializeObject((object)config, (Formatting)1); Directory.CreateDirectory(Path.GetDirectoryName(path2)); File.WriteAllText(path2, contents); if (generateTemplate) { MelonLogger.Warning(" NACops Property Heat config, written to: " + propertyHeatConfig); } } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Property Heat config: " + ex); } } public static ThresholdMappings LoadFrequencyConfig() { ThresholdMappings thresholdMappings; if (File.Exists(eventFrequencyConfig)) { try { thresholdMappings = JsonConvert.DeserializeObject<ThresholdMappings>(File.ReadAllText(eventFrequencyConfig)); foreach (MinMaxThreshold item in thresholdMappings.LethalCopFrequency) { if (item.MinOf < 0) { item.MinOf = 0; } if (item.Min >= item.Max) { MelonLogger.Warning("Found invalid value in progression.json at LethalCopFreq Min value, must be smaller than Max value"); if (item.Max > 0f) { item.Min = item.Max * 0.5f; } } } foreach (MinMaxThreshold item2 in thresholdMappings.LethalCopRange) { if (item2.MinOf < 0) { item2.MinOf = 0; } if (item2.Min >= item2.Max) { MelonLogger.Warning("Found invalid value in progression.json at LethalCopRange Min value, must be smaller than Max value"); if (item2.Max > 0f) { item2.Min = item2.Max * 0.5f; } } } foreach (MinMaxThreshold item3 in thresholdMappings.NearbyCrazyFrequency) { if (item3.MinOf < 0) { item3.MinOf = 0; } if (item3.Min >= item3.Max) { MelonLogger.Warning("Found invalid value in progression.json at NearbyCrazFreq Min value, must be smaller than Max value"); if (item3.Max > 0f) { item3.Min = item3.Max * 0.5f; } } } foreach (MinMaxThreshold item4 in thresholdMappings.NearbyCrazyRange) { if (item4.MinOf < 0) { item4.MinOf = 0; } if (item4.Min >= item4.Max) { MelonLogger.Warning("Found invalid value in progression.json at NearbyCrazRange Min value, must be smaller than Max value"); if (item4.Max > 0f) { item4.Min = item4.Max * 0.5f; } } } foreach (MinMaxThreshold item5 in thresholdMappings.PIFrequency) { if (item5.MinOf < 0) { item5.MinOf = 0; } if (item5.Min >= item5.Max) { MelonLogger.Warning("Found invalid value in progression.json at PIFreq Min value, must be smaller than Max value"); if (item5.Max > 0f) { item5.Min = item5.Max * 0.5f; } } } foreach (MinMaxThreshold item6 in thresholdMappings.SnitchProbability) { if (item6.MinOf < 0) { item6.MinOf = 0; } if (item6.Min >= item6.Max) { MelonLogger.Warning("Found invalid value in progression.json at SnitchProbability Min value, must be smaller than Max value"); if (item6.Max > 0f) { item6.Min = item6.Max * 0.5f; } } } foreach (MinMaxThreshold item7 in thresholdMappings.BuyBustProbability) { if (item7.MinOf < 0) { item7.MinOf = 0; } if (item7.Min >= item7.Max) { MelonLogger.Warning("Found invalid value in progression.json at BuyBustProbability Min value, must be smaller than Max value"); if (item7.Max > 0f) { item7.Min = item7.Max * 0.5f; } } } } catch (Exception ex) { thresholdMappings = new ThresholdMappings(); MelonLogger.Warning("Failed to read NACops Event Frequency config: " + ex); } } else { MelonLogger.Warning("Missing NACops Event Frequency config, creating directory and template."); thresholdMappings = new ThresholdMappings(); Save(thresholdMappings); } return thresholdMappings; } public static void Save(ThresholdMappings config) { try { string contents = JsonConvert.SerializeObject((object)config, (Formatting)1); Directory.CreateDirectory(Path.GetDirectoryName(eventFrequencyConfig)); File.WriteAllText(eventFrequencyConfig, contents); MelonLogger.Warning(" NACops Event Frequency config, written to: " + eventFrequencyConfig); } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Event Frequency config: " + ex); } } public static RaidConfig LoadRaidConfig() { RaidConfig raidConfig; if (File.Exists(ConfigLoader.raidConfig)) { try { raidConfig = JsonConvert.DeserializeObject<RaidConfig>(File.ReadAllText(ConfigLoader.raidConfig)); raidConfig.TraverseToPropertySpeed = Mathf.Clamp(raidConfig.TraverseToPropertySpeed, 0.1f, 1f); raidConfig.ClearPropertySpeed = Mathf.Clamp(raidConfig.ClearPropertySpeed, 0.1f, 1f); raidConfig.MaxDestroyIters = Mathf.Clamp(raidConfig.MaxDestroyIters, 1, 10); raidConfig.RaidCopsCount = Mathf.Clamp(raidConfig.RaidCopsCount, 1, 10); raidConfig.DaysUntilCanRaid = Mathf.Clamp(raidConfig.DaysUntilCanRaid, 1, 20); raidConfig.PropertyHeatThreshold = Mathf.Clamp(raidConfig.PropertyHeatThreshold, 1, 100); } catch (Exception ex) { raidConfig = new RaidConfig(); MelonLogger.Warning("Failed to read NACops Raid config: " + ex); } } else { MelonLogger.Warning("Missing NACops Raid config, creating directory and template."); raidConfig = new RaidConfig(); Save(raidConfig); } return raidConfig; } public static void Save(RaidConfig config) { try { string contents = JsonConvert.SerializeObject((object)config, (Formatting)1); Directory.CreateDirectory(Path.GetDirectoryName(raidConfig)); File.WriteAllText(raidConfig, contents); MelonLogger.Warning(" NACops Raid config, written to: " + raidConfig); } catch (Exception ex) { MelonLogger.Warning("Failed to save NACops Raid config: " + ex); } } } public static class ConsoleModule { [Flags] public enum CommandSupport { None = 0, List = 1, Spawn = 2, SpawnNoIndex = 4, Visualize = 8, Build = 0x10 } public abstract class ConsoleCommandBase { public virtual string Name { get; } public virtual CommandSupport SupportedMethods { get; } public virtual void List() { DebugModule.Log("Not implemented", "List"); } public virtual void Spawn(int index) { DebugModule.Log("Not implemented", "Spawn"); } public virtual void Visualize(int index) { DebugModule.Log("Not implemented", "Visualize"); } public virtual void Build(string arg) { DebugModule.Log("Build Argument: " + arg + " Not implemented", "Build"); } protected static void CleanVisual() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if (DebugModule.pathVisualizer != null && DebugModule.pathVisualizer.Count > 0) { foreach (GameObject item in DebugModule.pathVisualizer) { Object.Destroy((Object)(object)item); } } DebugModule.pathVisualizer.Clear(); if ((Object)(object)DebugModule.lineRenderMat == (Object)null) { DebugModule.lineRenderMat = new Material(Shader.Find("Sprites/Default")); } } protected static void DrawPath(string name, Vector3[] points) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Path_" + name); DebugModule.pathVisualizer.Add(val); LineRenderer obj = val.AddComponent<LineRenderer>(); ((Renderer)obj).material = DebugModule.lineRenderMat; obj.widthMultiplier = 0.5f; obj.startColor = Color.blue; obj.endColor = Color.red; obj.positionCount = points.Length; obj.SetPositions(points); } } public class FootPatrolTarget : ConsoleCommandBase { [CompilerGenerated] private sealed class <>c__DisplayClass5_0 { public PatrolInstance instance; public int originalStart; public int originalEnd; } [CompilerGenerated] private sealed class <FollowPlayer>d__11 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public FootPatrolTarget <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FollowPlayer>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; FootPatrolTarget footPatrolTarget = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; Transform centerPointTransform = Player.Local.CenterPointTransform; GameObject val = new GameObject("Path"); DebugModule.pathVisualizer.Add(val); footPatrolTarget.recordedPathNodes.Add(Player.Local.CenterPointTransform.position); LineRenderer val2 = val.AddComponent<LineRenderer>(); ((Renderer)val2).material = DebugModule.lineRenderMat; val2.widthMultiplier = 0.5f; val2.startColor = Color.blue; val2.endColor = Color.red; val2.positionCount = footPatrolTarget.recordedPathNodes.Count; val2.SetPositions(footPatrolTarget.recordedPathNodes.ToArray()); while (NACops.registered && isBuilding) { if (Vector3.Distance(centerPointTransform.position, footPatrolTarget.recordedPathNodes[footPatrolTarget.recordedPathNodes.Count - 1]) > 6f) { footPatrolTarget.BuildNode(val2); } } <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public List<Vector3> recordedPathNodes = new List<Vector3>(); public string currentPathName; public override string Name => "footpatrol"; public override CommandSupport SupportedMethods => CommandSupport.List | CommandSupport.Spawn | CommandSupport.Visualize | CommandSupport.Build; public override void List() { string text = ""; int num = 0; text += "\nIndex: Name"; foreach (PatrolInstance key in FootPatrolGenerator.generatedPatrolInstances.Keys) { text += $"\n{num}: {((Object)key.Route).name}"; num++; } text += "\n-------"; DebugModule.Log(text, "List"); } public override void Spawn(int index) { <>c__DisplayClass5_0 CS$<>8__locals0 = new <>c__DisplayClass5_0(); List<PatrolInstance> list = FootPatrolGenerator.generatedPatrolInstances.Keys.ToList(); if (index < list.Count) { CS$<>8__locals0.instance = list[index]; if (CS$<>8__locals0.instance.ActiveGroup != null) { DebugModule.Log("Foot patrol group is already active", "Spawn"); return; } CS$<>8__locals0.originalStart = CS$<>8__locals0.instance.StartTime; CS$<>8__locals0.originalEnd = CS$<>8__locals0.instance.EndTime; CS$<>8__locals0.instance.StartTime = NetworkSingleton<TimeManager>.Instance.CurrentTime; CS$<>8__locals0.instance.EndTime = TimeManager.AddMinutesTo24HourTime(CS$<>8__locals0.originalStart, 240); CS$<>8__locals0.instance.StartPatrol(); DebugModule.Log("Patrol " + ((Object)CS$<>8__locals0.instance.Route).name + " Spawned", "Spawn"); NACops.coros.Add(MelonCoroutines.Start(EndSoon())); } [IteratorStateMachine(typeof(<>c__DisplayClass5_0.<<Spawn>g__EndSoon|0>d))] IEnumerator EndSoon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass5_0.<<Spawn>g__EndSoon|0>d(0) { <>4__this = CS$<>8__locals0 }; } } public override void Visualize(int index) { ConsoleCommandBase.CleanVisual(); List<PatrolInstance> list = FootPatrolGenerator.generatedPatrolInstances.Keys.ToList(); if (index >= 0 && index < list.Count) { FootPatrolRoute route = list[index].Route; Vector3[] points = route.Waypoints.Select((Transform waypoint) => waypoint.position + Vector3.up * 8f).ToArray(); ConsoleCommandBase.DrawPath(((Object)route).name, points); DebugModule.Log("Patrol " + ((Object)route).name + " Visualized", "Visualize"); } } public override void Build(string arg) { if (arg.ToLower() == "start") { BuildStart(); } else if (isBuilding) { BuildEnd(); } } public void BuildStart() { if (isBuilding) { DebugModule.Log("Already building a path or a sentry!\n Use: nacops build " + Name + " stop\n to stop building", "BuildStart"); return; } isBuilding = true; currentPathName = $"{Name}_{Guid.NewGuid()}"; DebugModule.Log("Started building path with name " + currentPathName + "\nWalk around to create new path nodes!", "BuildStart"); NACops.coros.Add(MelonCoroutines.Start(FollowPlayer())); } [IteratorStateMachine(typeof(<FollowPlayer>d__11))] public IEnumerator FollowPlayer() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FollowPlayer>d__11(0) { <>4__this = this }; } public void BuildNode(LineRenderer lineRenderer) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) recordedPathNodes.Add(Player.Local.CenterPointTransform.position); lineRenderer.positionCount = recordedPathNodes.Count; lineRenderer.SetPositions(recordedPathNodes.ToArray()); } public void BuildEnd() { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) isBuilding = false; ConsoleCommandBase.CleanVisual(); if (recordedPathNodes.Count == 0) { DebugModule.Log("No recorded nodes found.", "BuildEnd"); return; } if (recordedPathNodes.Count < 4) { DebugModule.Log("Build more path nodes to save.", "BuildEnd"); recordedPathNodes.Clear(); return; } SerializedFootPatrol serializedFootPatrol = new SerializedFootPatrol(); serializedFootPatrol.startTime = 1900; serializedFootPatrol.endTime = 500; serializedFootPatrol.members = 1; serializedFootPatrol.intensityRequirement = 1; serializedFootPatrol.onlyIfCurfew = false; serializedFootPatrol.name = currentPathName; serializedFootPatrol.days = new List<string> { "mon", "tue", "wed", "thu", "fri", "sat", "sun" }; List<Vector3> list = new List<Vector3>(); list.Add(recordedPathNodes[0]); foreach (Vector3 recordedPathNode in recordedPathNodes) { if (Vector3.Distance(recordedPathNode, list[list.Count - 1]) > 24f) { list.Add(recordedPathNode); } } serializedFootPatrol.waypoints = new List<Vector3>(list); FootPatrolGenerator.serPatrols.loadedPatrols.Add(serializedFootPatrol); DebugModule.Log("Finished building: " + currentPathName, "BuildEnd"); DebugModule.Log($"Recorded path nodes: {recordedPathNodes.Count}\n Reload the game to apply changes.", "BuildEnd"); ConfigLoader.Save(FootPatrolGenerator.serPatrols); recordedPathNodes.Clear(); } } public class VehiclePatrolTarget : ConsoleCommandBase { [CompilerGenerated] private sealed class <>c__DisplayClass5_0 { public VehiclePatrolInstance instance; public int originalStart; } [CompilerGenerated] private sealed class <FollowPlayer>d__11 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public VehiclePatrolTarget <>4__this; private Transform <tr>5__2; private LineRenderer <lineRenderer>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FollowPlayer>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <tr>5__2 = null; <lineRenderer>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; VehiclePatrolTarget vehiclePatrolTarget = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <tr>5__2 = Player.Local.CenterPointTransform; GameObject val = new GameObject("Path"); DebugModule.pathVisualizer.Add(val); vehiclePatrolTarget.recordedPathNodes.Add(Player.Local.CenterPointTransform.position); <lineRenderer>5__3 = val.AddComponent<LineRenderer>(); ((Renderer)<lineRenderer>5__3).material = DebugModule.lineRenderMat; <lineRenderer>5__3.widthMultiplier = 0.5f; <lineRenderer>5__3.startColor = Color.blue; <lineRenderer>5__3.endColor = Color.red; <lineRenderer>5__3.positionCount = vehiclePatrolTarget.recordedPathNodes.Count; <lineRenderer>5__3.SetPositions(vehiclePatrolTarget.recordedPathNodes.ToArray()); goto IL_0139; } case 1: <>1__state = -1; if (Vector3.Distance(<tr>5__2.position, vehiclePatrolTarget.recordedPathNodes[vehiclePatrolTarget.recordedPathNodes.Count - 1]) > 6f) { vehiclePatrolTarget.BuildNode(<lineRenderer>5__3); } goto IL_0139; case 2: { <>1__state = -1; return false; } IL_0139: if (NACops.registered && isBuilding) { <>2__current = NACops.Wait1; <>1__state = 1; return true; } <>2__current = null; <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public List<Vector3> recordedPathNodes = new List<Vector3>(); public string currentPathName; public override string Name => "vehiclepatrol"; public override CommandSupport SupportedMethods => CommandSupport.List | CommandSupport.Spawn | CommandSupport.Visualize | CommandSupport.Build; public override void List() { string text = ""; int num = 0; text += "\nIndex: Name"; foreach (VehiclePatrolInstance key in VehiclePatrolGenerator.generatedVehiclePatrolInstances.Keys) { text += $"\n{num}: {((Object)key.Route).name}"; num++; } text += "\n-------"; DebugModule.Log(text, "List"); } public override void Spawn(int index) { <>c__DisplayClass5_0 CS$<>8__locals0 = new <>c__DisplayClass5_0(); List<VehiclePatrolInstance> list = VehiclePatrolGenerator.generatedVehiclePatrolInstances.Keys.ToList(); if (index < list.Count) { CS$<>8__locals0.instance = list[index]; if ((Object)(object)CS$<>8__locals0.instance.activeOfficer != (Object)null) { DebugModule.Log("Vehicle patrol is already active", "Spawn"); return; } CS$<>8__locals0.originalStart = CS$<>8__locals0.instance.StartTime; CS$<>8__locals0.instance.StartTime = NetworkSingleton<TimeManager>.Instance.CurrentTime; CS$<>8__locals0.instance.StartPatrol(); DebugModule.Log("Vehicle Patrol " + ((Object)CS$<>8__locals0.instance.Route).name + " Spawned", "Spawn"); NACops.coros.Add(MelonCoroutines.Start(EndSoon())); } [IteratorStateMachine(typeof(<>c__DisplayClass5_0.<<Spawn>g__EndSoon|0>d))] IEnumerator EndSoon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass5_0.<<Spawn>g__EndSoon|0>d(0) { <>4__this = CS$<>8__locals0 }; } } public override void Visualize(int index) { ConsoleCommandBase.CleanVisual(); List<VehiclePatrolInstance> list = VehiclePatrolGenerator.generatedVehiclePatrolInstances.Keys.ToList(); if (index >= 0 && index < list.Count) { VehiclePatrolRoute route = list[index].Route; Vector3[] points = route.Waypoints.Select((Transform waypoint) => waypoint.position + Vector3.up * 8f).ToArray(); ConsoleCommandBase.DrawPath(((Object)route).name, points); DebugModule.Log("Veicle Patrol " + ((Object)route).name + " Visualized", "Visualize"); } } public override void Build(string arg) { if (arg.ToLower() == "start") { BuildStart(); } else if (isBuilding) { BuildEnd(); } } public void BuildStart() { if (isBuilding) { DebugModule.Log("Already building a path or a sentry!\n Use: nacops build " + Name + " stop\n to stop building", "BuildStart"); return; } isBuilding = true; currentPathName = $"{Name}_{Guid.NewGuid()}"; DebugModule.Log("Started building path with name " + currentPathName + "\nWalk on the road to create new path nodes!", "BuildStart"); NACops.coros.Add(MelonCoroutines.Start(FollowPlayer())); } [IteratorStateMachine(typeof(<FollowPlayer>d__11))] public IEnumerator FollowPlayer() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FollowPlayer>d__11(0) { <>4__this = this }; } public void BuildNode(LineRenderer lineRenderer) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) recordedPathNodes.Add(Player.Local.CenterPointTransform.position); lineRenderer.positionCount = recordedPathNodes.Count; lineRenderer.SetPositions(recordedPathNodes.ToArray()); } public void BuildEnd() { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) isBuilding = false; ConsoleCommandBase.CleanVisual(); if (recordedPathNodes.Count == 0) { DebugModule.Log("No recorded nodes found.", "BuildEnd"); return; } if (recordedPathNodes.Count < 4) { DebugModule.Log("Build more path nodes to save.", "BuildEnd"); recordedPathNodes.Clear(); return; } SerializedVehiclePatrol serializedVehiclePatrol = new SerializedVehiclePatrol(); serializedVehiclePatrol.startTime = 1900; serializedVehiclePatrol.intensityRequirement = 1; serializedVehiclePatrol.onlyIfCurfew = false; serializedVehiclePatrol.name = currentPathName; serializedVehiclePatrol.days = new List<string> { "mon", "tue", "wed", "thu", "fri", "sat", "sun" }; List<Vector3> list = new List<Vector3>(); list.Add(recordedPathNodes[0]); foreach (Vector3 recordedPathNode in recordedPathNodes) { if (Vector3.Distance(recordedPathNode, list[list.Count - 1]) > 24f) { list.Add(recordedPathNode); } } serializedVehiclePatrol.waypoints = new List<Vector3>(list); VehiclePatrolGenerator.serVehiclePatrols.loadedVehiclePatrols.Add(serializedVehiclePatrol); DebugModule.Log("Finished building: " + currentPathName, "BuildEnd"); DebugModule.Log($"Recorded path nodes: {recordedPathNodes.Count}\n Reload the game to apply changes.", "BuildEnd"); ConfigLoader.Save(VehiclePatrolGenerator.serVehiclePatrols); recordedPathNodes.Clear(); } } public class SentryTarget : ConsoleCommandBase { [CompilerGenerated] private sealed class <>c__DisplayClass5_0 { public SentryInstance instance; public int originalStart; public int originalEnd; } [CompilerGenerated] private sealed class <BuildEnd>d__12 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SentryTarget <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <BuildEnd>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; SentryTarget sentryTarget = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; sentryTarget.recordedPathNodes.Add(Player.Local.CenterPointTransform.position); isBuilding = false; if (sentryTarget.recordedPathNodes.Count == 0) { DebugModule.Log("No recorded nodes found.", "BuildEnd"); return false; } if (sentryTarget.recordedPathNodes.Count != 2) { DebugModule.Log("Build more sentry nodes to save.", "BuildEnd"); sentryTarget.recordedPathNodes.Clear(); return false; } SerializedSentry item = new SerializedSentry { startTime = 1900, endTime = 500, members = 1, intensityRequirement = 1, onlyIfCurfew = false, name = sentryTarget.currentPathName, days = new List<string> { "mon", "tue", "wed", "thu", "fri", "sat", "sun" }, standPosition1 = sentryTarget.recordedPathNodes[0], standPosition2 = sentryTarget.recordedPathNodes[1] }; SentryGenerator.serSentries.loadedSentrys.Add(item); DebugModule.Log("Finished building: " + sentryTarget.currentPathName, "BuildEnd"); DebugModule.Log($"Recorded path nodes: {sentryTarget.recordedPathNodes.Count}\n Reload the game to apply changes.", "BuildEnd"); ConfigLoader.Save(SentryGenerator.serSentries); sentryTarget.recordedPathNodes.Clear(); <>2__current = NACops.Wait5; <>1__state = 1; return true; } case 1: <>1__state = -1; ConsoleCommandBase.CleanVisual(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public List<Vector3> recordedPathNodes = new List<Vector3>(); public string currentPathName; public override string Name => "sentry"; public override CommandSupport SupportedMethods => CommandSupport.List | CommandSupport.Spawn | CommandSupport.Visualize | CommandSupport.Build; public override void List() { string text = ""; int num = 0; text += "\nIndex: Name"; foreach (SentryInstance key in SentryGenerator.generatedSentryInstances.Keys) { text += $"\n{num}: {((Object)((Component)key.Location).gameObject).name}"; num++; } text += "\n-------"; DebugModule.Log(text, "List"); } public override void Spawn(int index) { <>c__DisplayClass5_0 CS$<>8__locals0 = new <>c__DisplayClass5_0(); List<SentryInstance> list = SentryGenerator.generatedSentryInstances.Keys.ToList(); if (index < list.Count) { CS$<>8__locals0.instance = list[index]; if (CS$<>8__locals0.instance.Location.AssignedOfficers.Count > 0) { DebugModule.Log("Sentry is already active", "Spawn"); return; } CS$<>8__locals0.originalStart = CS$<>8__locals0.instance.StartTime; CS$<>8__locals0.originalEnd = CS$<>8__locals0.instance.EndTime; CS$<>8__locals0.instance.StartTime = NetworkSingleton<TimeManager>.Instance.CurrentTime; CS$<>8__locals0.instance.EndTime = TimeManager.AddMinutesTo24HourTime(CS$<>8__locals0.originalStart, 240); CS$<>8__locals0.instance.StartEntry(); DebugModule.Log("Sentry " + ((Object)((Component)CS$<>8__locals0.instance.Location).gameObject).name + " Spawned", "Spawn"); NACops.coros.Add(MelonCoroutines.Start(EndSoon())); } [IteratorStateMachine(typeof(<>c__DisplayClass5_0.<<Spawn>g__EndSoon|0>d))] IEnumerator EndSoon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass5_0.<<Spawn>g__EndSoon|0>d(0) { <>4__this = CS$<>8__locals0 }; } } public override void Visualize(int index) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) ConsoleCommandBase.CleanVisual(); List<SentryInstance> list = SentryGenerator.generatedSentryInstances.Keys.ToList(); if (index >= 0 && index < list.Count) { SentryInstance val = list[index]; for (int i = 0; i < val.Location.StandPoints.Count; i++) { Vector3 position = val.Location.StandPoints[i].position; Vector3[] points = (Vector3[])(object)new Vector3[2] { position, position + Vector3.up * 8f }; ConsoleCommandBase.DrawPath($"{((Object)((Component)val.Location).gameObject).name}_{i}", points); } DebugModule.Log("Sentry " + ((Object)((Component)val.Location).gameObject).name + " Visualized", "Visualize"); } } public override void Build(string arg) { if (arg.ToLower() == "start") { BuildStart(); } else if (isBuilding) { NACops.coros.Add(MelonCoroutines.Start(BuildEnd())); } } public void BuildStart() { if (isBuilding) { DebugModule.Log("Already building a path or sentry!\n Use: nacops build " + Name + " stop\n to stop building", "BuildStart"); return; } isBuilding = true; currentPathName = $"{Name}_{Guid.NewGuid()}"; DebugModule.Log(currentPathName + ": Set 1st Sentry Point\n Walk to 2nd sentry point and type:\nnacops build " + Name + " stop", "BuildStart"); MakeVertBeam(); } public void MakeVertBeam() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Transform centerPointTransform = Player.Local.CenterPointTransform; GameObject val = new GameObject("Path"); DebugModule.pathVisualizer.Add(val); recordedPathNodes.Add(Player.Local.CenterPointTransform.position); LineRenderer val2 = val.AddComponent<LineRenderer>(); ((Renderer)val2).material = DebugModule.lineRenderMat; val2.widthMultiplier = 0.5f; val2.startColor = Color.blue; val2.endColor = Color.red; val2.positionCount = 2; Vector3[] positions = (Vector3[])(object)new Vector3[2] { centerPointTransform.position, centerPointTransform.position + Vector3.up * 5f }; val2.SetPositions(positions); } [IteratorStateMachine(typeof(<BuildEnd>d__12))] public IEnumerator BuildEnd() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <BuildEnd>d__12(0) { <>4__this = this }; } } public class RaidTarget : ConsoleCommandBase { public override string Name => "raid"; public override CommandSupport SupportedMethods => CommandSupport.List | CommandSupport.Spawn; public override void List() { lock (NACops.heatConfigLock) { List<PropertyHeat> list = new List<PropertyHeat>(NACops.heatConfig); string text = ""; int num = 0; text += "\nIndex: Name"; foreach (PropertyHeat item in list) { text += $"\n{num}: {item.propertyCode}\n DaysSinceRaid: {item.daysSinceLastRaid}\n Heat: {item.propertyHeat}"; num++; } text += "\n-------"; DebugModule.Log(text, "List"); } } public override void Spawn(int index) { if (index < 0 || index >= NACops.heatConfig.Count) { return; } Property val = null; foreach (Property property in Property.Properties) { if (property.PropertyCode == NACops.heatConfig[index].propertyCode) { val = property; } } if (Object.op_Implicit((Object)(object)val)) { if ((Object)(object)val.NPCSpawnPoint == (Object)null) { DebugModule.Log("No valid destination for property: " + val.propertyName, "Spawn"); } else if (val is Business) { DebugModule.Log("Cant start raid on a business", "Spawn"); } else { NACops.coros.Add(MelonCoroutines.Start(RaidPropertyEvent.BeginRaidEvent(val))); } } } public override void Visualize(int index) { DebugModule.Log("Not supported", "Visualize"); } } public class InvestigatorTarget : ConsoleCommandBase { public override string Name => "investigator"; public override CommandSupport SupportedMethods => CommandSupport.SpawnNoIndex; public override void List() { DebugModule.Log("Not supported", "List"); } public override void Spawn(int index) { DebugModule.Log("Spawning Private Investigator", "Spawn"); NACops.coros.Add(MelonCoroutines.Start(PrivateInvestigator.HandlePIMonitor())); } public override void Visualize(int index) { DebugModule.Log("Not supported", "Visualize"); } } public static bool isBuilding = false; public static bool isLoggingEnabled = false; public static readonly HashSet<string> ConsoleMethodNames = new HashSet<string> { "Help", "List", "Spawn", "Visualize", "BuildStart", "BuildEnd", "RunCommand" }; } public static class DebugModule { public static int origCount = 0; public static Material lineRenderMat; public static List<GameObject> pathVisualizer = new List<GameObject>(); public static Dictionary<string, ConsoleModule.ConsoleCommandBase> consoleTargets = new Dictionary<string, ConsoleModule.ConsoleCommandBase> { { "footpatrol", new ConsoleModule.FootPatrolTarget() }, { "vehiclepatrol", new ConsoleModule.VehiclePatrolTarget() }, { "sentry", new ConsoleModule.SentryTarget() }, { "raid", new ConsoleModule.RaidTarget() }, { "investigator", new ConsoleModule.InvestigatorTarget() } }; public static void Log(string msg, [CallerMemberName] string memberName = "") { if (ConsoleModule.isLoggingEnabled || ConsoleModule.ConsoleMethodNames.Contains(memberName)) { MelonLogger.Msg("[" + memberName + "] " + msg); } } public static void RunCommand(List<string> args) { if (args.Count == 2 && args[1].ToLower() == "help") { Help(); return; } if (args.Count == 3 && args[1].ToLower() == "enable" && args[2].ToLower() == "logs") { ConsoleModule.isLoggingEnabled = true; return; } if (args.Count < 3) { Log("Usage: nacops (action) (target) (index or argument)\n Try: nacops help", "RunCommand"); return; } string text = args[1].ToLower(); string text2 = args[2].ToLower(); int result = ((args.Count > 3 && int.TryParse(args[3], out result)) ? result : (-1)); if (result == -1 && args.Count > 3 && !(args[3].ToLower() == "start")) { _ = args[3].ToLower() == "stop"; } if (!consoleTargets.TryGetValue(text2, out var value)) { Log("Unknown command target '" + text2 + "'", "RunCommand"); return; } ConsoleModule.CommandSupport commandSupport = text switch { "list" => ConsoleModule.CommandSupport.List, "spawn" => ConsoleModule.CommandSupport.Spawn | ConsoleModule.CommandSupport.SpawnNoIndex, "visualize" => ConsoleModule.CommandSupport.Visualize, "build" => ConsoleModule.CommandSupport.Build, _ => ConsoleModule.CommandSupport.None, }; if ((value.SupportedMethods & commandSupport) == 0) { Log($"Command target '{text2}' does not support requested method '{commandSupport}'", "RunCommand"); return; } switch (commandSupport) { case ConsoleModule.CommandSupport.List: value.List(); break; case ConsoleModule.CommandSupport.Spawn | ConsoleModule.CommandSupport.SpawnNoIndex: value.Spawn(result); break; case ConsoleModule.CommandSupport.Visualize: value.Visualize(result); break; case ConsoleModule.CommandSupport.Build: value.Build(args[3]); break; } } public static void Help() { string text = ""; text += "\nSupported Commands:"; text += "\n\n# ENABLE FULL LOGGING"; text += "\nnacops enable logs"; foreach (ConsoleModule.ConsoleCommandBase value in consoleTargets.Values) { text = text + "\n\n# " + value.Name.ToUpper(); if (value.SupportedMethods.HasFlag(ConsoleModule.CommandSupport.List)) { text = text + "\nnacops list " + value.Name; } if (value.SupportedMethods.HasFlag(ConsoleModule.CommandSupport.Spawn)) { text = text + "\nnacops spawn " + value.Name + " (index)"; } if (value.SupportedMethods.HasFlag(ConsoleModule.CommandSupport.SpawnNoIndex)) { text = text + "\nnacops spawn " + value.Name; } if (value.SupportedMethods.HasFlag(ConsoleModule.CommandSupport.Visualize)) { text = text + "\nnacops visualize " + value.Name + " (index)"; } if (value.SupportedMethods.HasFlag(ConsoleModule.CommandSupport.Build)) { text = text + "\nnacops build " + value.Name + " start"; text = text + "\nnacops build " + value.Name + " stop"; } } Log(text, "Help"); } } [HarmonyPatch(typeof(Console), "SubmitCommand", new Type[] { typeof(List<string>) })] public static class Console_SubmitCommand_ListString_Patch { public static bool Prefix(Console __instance, List<string> args) { if (args.Count == 0) { return true; } if (args[0].ToLower() == "nacops") { DebugModule.RunCommand(args); return true; } return true; } } [HarmonyPatch(typeof(Console), "SubmitCommand", new Type[] { typeof(string) })] public static class Console_SubmitCommand_String_Patch { public static bool Prefix(Console __instance, string args) { return true; } } [HarmonyPatch(typeof(Player), "ConsumeProduct")] public static class Player_ConsumeProduct_Patch { [CompilerGenerated] private sealed class <ApprehenderOfficerClear>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PoliceOfficer offc; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApprehenderOfficerClear>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)offc == (Object)null) { return false; } <>2__current = NACops.Wait30; <>1__state = 1; return true; case 1: <>1__state = -1; DebugModule.Log(" apprehender clear", "ApprehenderOfficerClear"); if (NACops.currentDrugApprehender.Contains(offc)) { NACops.currentDrugApprehender.Remove(offc); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <DrugConsumedCoro>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ProductItemInstance product; public Player player; private PoliceOfficer <noticeOfficer>5__2; private float <smallestDistance>5__3; private bool <direct>5__4; private bool <apprehending>5__5; private HashSet<PoliceOfficer>.Enumerator <>7__wrap5; private PoliceOfficer <offc>5__7; private int <i>5__8; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DrugConsumedCoro>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <noticeOfficer>5__2 = null; <>7__wrap5 = default(HashSet<PoliceOfficer>.Enumerator); <offc>5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; if (!NACops.currentConfig.WeedInvestigator) { return false; } bool flag = false; bool num2 = product is WeedInstance; bool flag2 = product is MethInstance; bool flag3 = product is CocaineInstance; bool flag4 = product is ShroomInstance; flag = num2 || flag2 || flag3 || flag4; DebugModule.Log("Is Supported Instance for Apprehender: " + flag, "DrugConsumedCoro"); if (flag) { DebugModule.Log("Instance casted, check officers count: " + NACops.allActiveOfficers.Count, "DrugConsumedCoro"); <noticeOfficer>5__2 = null; <smallestDistance>5__3 = 49f; <direct>5__4 = false; <>7__wrap5 = NACops.allActiveOfficers.GetEnumerator(); <>1__state = -3; goto IL_02d7; } goto IL_0653; } case 1: <>1__state = -3; if (!BaseUtility.GUIDInUse.Contains(((NPC)<offc>5__7).BakedGUID) && !NACops.currentDrugApprehender.Contains(<offc>5__7) && !NACops.currentSummoned.Contains(<offc>5__7) && !(Vector3.Distance(((Component)<offc>5__7).transform.position, ((Component)player).transform.position) > 50f) && !((NPC)<offc>5__7).Health.IsDead && !((NPC)<offc>5__7).Health.IsKnockedOut) { if (((NPC)<offc>5__7).Awareness.VisionCone.IsPlayerVisible(player) && ((NPC)<offc>5__7).Movement.CanMove() && !((NPC)<offc>5__7).IsInVehicle && !((NPC)<offc>5__7).isInBuilding) { <offc>5__7.BeginFootPursuit(player.PlayerCode); NACops.coros.Add(MelonCoroutines.Start(BaseUtility.GiveFalseCharges(3, player))); <direct>5__4 = true; DebugModule.Log("Apprehend immediate direct", "DrugConsumedCoro"); goto IL_02e7; } float num = Vector3.Distance(((Component)<offc>5__7).transform.position, ((Component)player).transform.position); if (num < <smallestDistance>5__3 && !((NPC)<offc>5__7).IsInVehicle && !((NPC)<offc>5__7).isInBuilding) { <smallestDistance>5__3 = num; <noticeOfficer>5__2 = <offc>5__7; } <offc>5__7 = null; } goto IL_02d7; case 2: <>1__state = -1; if (((NPC)<noticeOfficer>5__2).Awareness.VisionCone.IsPlayerVisible(player)) { DebugModule.Log("Apprehend immediate candidate", "DrugConsumedCoro"); <noticeOfficer>5__2.BeginBodySearch(player.PlayerCode); NACops.coros.Add(MelonCoroutines.Start(BaseUtility.GiveFalseCharges(3, player))); <apprehending>5__5 = true; } if ((Object)(object)<noticeOfficer>5__2 != (Object)null && !<apprehending>5__5) { <i>5__8 = 0; goto IL_0640; } goto IL_064c; case 3: <>1__state = -1; if (!NACops.registered) { return false; } if (!((NPC)<noticeOfficer>5__2).Health.IsDead && !((NPC)<noticeOfficer>5__2).Health.IsKnockedOut) { if (!((NPC)<noticeOfficer>5__2).Awareness.VisionCone.IsPlayerVisible(player)) { <>2__current = NACops.Wait05; <>1__state = 4; return true; } <noticeOfficer>5__2.BeginBodySearch(player.PlayerCode); if (Random.Range(1f, 0f) > 0.8f) { NACops.coros.Add(MelonCoroutines.Start(BaseUtility.GiveFalseCharges(1, player))); } } goto IL_064c; case 4: <>1__state = -1; if (!NACops.registered) { return false; } if (!((NPC)<noticeOfficer>5__2).Health.IsDead && !((NPC)<noticeOfficer>5__2).Health.IsKnockedOut) { ((NPC)<noticeOfficer>5__2).Movement.SetDestination(player.CenterPointTransform.position); <>2__current = NACops.Wait1; <>1__state = 5; return true; } goto IL_064c; case 5: <>1__state = -1; if (!NACops.registered) { return false; } if (!((NPC)<noticeOfficer>5__2).Health.IsDead && !((NPC)<noticeOfficer>5__2).Health.IsKnockedOut) { <i>5__8++; goto IL_0640; } goto IL_064c; case 6: { <>1__state = -1; return false; } IL_064c: <noticeOfficer>5__2 = null; goto IL_0653; IL_0640: if (<i>5__8 <= 6) { DebugModule.Log("Apprehend Search suspect", "DrugConsumedCoro"); if (!NACops.registered) { return false; } if (<i>5__8 <= 3 || !(Random.Range(1f, 0f) > 0.95f)) { ((NPC)<noticeOfficer>5__2).Movement.FacePoint(player.CenterPointTransform.position, 0.3f); <>2__current = NACops.Wait05; <>1__state = 3; return true; } } goto IL_064c; IL_0653: DebugModule.Log("evaluate apprehender end", "DrugConsumedCoro"); evaluating = false; <>2__current = null; <>1__state = 6; return true; IL_02d7: if (<>7__wrap5.MoveNext()) { <offc>5__7 = <>7__wrap5.Current; <>2__current = NACops.Wait01; <>1__state = 1; return true; } goto IL_02e7; IL_02e7: <>m__Finally1(); <>7__wrap5 = default(HashSet<PoliceOfficer>.Enumerator); if (((Object)(object)<noticeOfficer>5__2 == (Object)null) | <direct>5__4) { DebugModule.Log("No apprehender candidate found", "DrugConsumedCoro"); evaluating = false; return false; } NACops.currentDrugApprehender.Add(<noticeOfficer>5__2); DebugModule.Log("Proceed apprehender candidate", "DrugConsumedCoro"); NACops.coros.Add(MelonCoroutines.Start(ApprehenderOfficerClear(<noticeOfficer>5__2))); <apprehending>5__5 = false; ((NPC)<noticeOfficer>5__2).Movement.FacePoint(((Component)player).transform.position, 0.4f); <>2__current = NACops.Wait05; <>1__state = 2; return true; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap5).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static bool evaluating; public static bool Prefix(Player __instance, ProductItemInstance product) { DebugModule.Log("ConsumePrefix", "Prefix"); if (!evaluating && NACops.currentDrugApprehender.Count < 1) { evaluating = true; DebugModule.Log("CorosBegin", "Prefix"); NACops.coros.Add(M