using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem.Collections.Generic; using SOD.Common.BepInEx; using SOD.Common.BepInEx.Configuration; using SOD.Common.Extensions; 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("SOD.ThreatOverhaul")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+80840b9ea819be583ecb1d205ec645ba7e26aa7c")] [assembly: AssemblyProduct("SOD.ThreatOverhaul")] [assembly: AssemblyTitle("SOD.ThreatOverhaul")] [assembly: AssemblyVersion("1.0.0.0")] namespace SOD.ThreatOverhaul { public interface IPluginBindings : IThreatCalculationBindings { [Binding(false, "Should debug mode be enabled to show extra info logging?", "General.EnableDebugMode")] bool EnableDebugMode { get; set; } [Binding(true, "Should threat calculation overhaul be enabled?", "General.EnableThreatCalculationOverhaul")] bool EnableThreatCalculationOverhaul { get; set; } } public interface IThreatCalculationBindings { [Binding(true, "Should neighbors of the target be included in the threat calculation?", "ThreatCalculation.IncludeNeighbors")] bool IncludeNeighbors { get; set; } [Binding(true, "Should friends of the target be included in the threat calculation?", "ThreatCalculation.IncludeFriends")] bool IncludeFriends { get; set; } [Binding(true, "Should work colleagues of the target be included in the threat calculation?", "ThreatCalculation.IncludeColleagues")] bool IncludeColleagues { get; set; } [Binding(true, "Should police officers be included in the threat calculation?", "ThreatCalculation.IncludePoliceOfficers")] bool IncludePoliceOfficers { get; set; } [Binding(true, "Should citizens see the threat action happening before they are allowed to react?", "ThreatCalculation.IncludeSeeingThreat")] bool IncludeSeeingThreat { get; set; } } [BepInPlugin("Venomaus.SOD.ThreatOverhaul", "SOD.ThreatOverhaul", "1.0.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : PluginController { public const string PLUGIN_GUID = "Venomaus.SOD.ThreatOverhaul"; public const string PLUGIN_NAME = "SOD.ThreatOverhaul"; public const string PLUGIN_VERSION = "1.0.3"; public override void Load() { base.Harmony.PatchAll(Assembly.GetExecutingAssembly()); PluginController.Log.LogInfo((object)"Plugin is patched."); } } } namespace SOD.ThreatOverhaul.Patches { internal class NewAIControllerPatches { [HarmonyPatch(typeof(NewAIController), "SetPersue")] internal static class NewAIController_SetPersue { private static bool _wasPublicFauxPas; [HarmonyPrefix] internal static bool Prefix(ref bool publicFauxPas, Actor newTarget) { if (!((PluginController)PluginController.Instance).Config.EnableThreatCalculationOverhaul) { return true; } _wasPublicFauxPas = publicFauxPas; publicFauxPas = false; return true; } [HarmonyPostfix] internal static void Postfix(NewAIController __instance, Actor newTarget, ref bool publicFauxPas, int escalation, bool setHighUrgency, float responseRange) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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) if (!_wasPublicFauxPas) { return; } _wasPublicFauxPas = false; Enumerator enumerator = ((Actor)__instance.human).currentRoom.currentOccupants.GetEnumerator(); while (enumerator.MoveNext()) { Actor current = enumerator.Current; if ((Object)(object)current == (Object)(object)__instance.human || current.isStunned || current.isDead || current.isAsleep || (Object)(object)current.ai == (Object)null || (((PluginController)PluginController.Instance).Config.IncludeSeeingThreat && !GameExtensions.Sees(current, newTarget))) { continue; } Vector3 val = ((Component)current).transform.position - ((Component)__instance.human).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= responseRange * responseRange && IsTargetOfInterest(newTarget, current)) { if (((PluginController)PluginController.Instance).Config.EnableDebugMode) { PluginController.Log.LogInfo((object)("Threat seen by: " + ((Object)current).name + " and engaged persuit!")); } current.ai.SetPersuit(true); current.ai.SetPersueTarget(newTarget); current.AddToSeesIllegal(newTarget, 1f * SessionData.Instance.currentTimeMultiplier); current.ai.persuitChaseLogicUses = 0.5f; current.ai.Investigate(newTarget.currentNode, ((Component)newTarget).transform.position, newTarget, (ReactionState)3, CitizenControls.Instance.persuitMinInvestigationTimeMP, escalation, setHighUrgency, 1f, (Interactable)null); } } publicFauxPas = true; } } [HarmonyPatch(typeof(NewAIController), "InstantPersuitCheck")] internal static class NewAIController_InstantPersuitCheck { [HarmonyPrefix] internal static bool Prefix(NewAIController __instance, Actor target) { if (!((PluginController)PluginController.Instance).Config.EnableThreatCalculationOverhaul) { return true; } bool num = IsTargetOfInterest(target, (Actor)(object)__instance.human); if (num && ((PluginController)PluginController.Instance).Config.EnableDebugMode) { PluginController.Log.LogInfo((object)("Instant check: " + __instance.human.GetCitizenName())); } return num; } } private static bool IsTargetOfInterest(Actor actor, Actor thirdParty) { bool flag = false; if ((Object)(object)actor.currentRoom != (Object)null && actor.currentRoom.belongsTo != null) { flag = EnumerableExtensions.Any(actor.currentRoom.belongsTo, (Func)delegate(Human a) { if (DoesActorMatchModCriteria((Actor)(object)a, thirdParty)) { return true; } return (Object)(object)a.partner != (Object)null && DoesActorMatchModCriteria((Actor)(object)a.partner, thirdParty); }); } if (!flag && (Object)(object)actor.currentGameLocation != (Object)null && (Object)(object)actor.currentGameLocation.thisAsAddress != (Object)null) { Company company = actor.currentGameLocation.thisAsAddress.company; if (company != null) { if ((Object)(object)company.janitor != (Object)null) { flag = DoesActorMatchModCriteria((Actor)(object)company.janitor, thirdParty); } if (!flag && (Object)(object)company.director != (Object)null) { flag = DoesActorMatchModCriteria((Actor)(object)company.director, thirdParty); } if (!flag && (Object)(object)company.receptionist != (Object)null) { flag = DoesActorMatchModCriteria((Actor)(object)company.receptionist, thirdParty); } if (!flag && (Object)(object)company.security != (Object)null) { flag = DoesActorMatchModCriteria((Actor)(object)company.security, thirdParty); } Enumerator enumerator = company.companyRoster.GetEnumerator(); while (enumerator.MoveNext()) { Occupation current = enumerator.Current; if ((Object)(object)actor.currentRoom != (Object)null && actor.currentRoom.currentOccupants != null && actor.currentRoom.currentOccupants.Contains((Actor)(object)current.employee)) { flag = DoesActorMatchModCriteria((Actor)(object)current.employee, thirdParty); if (flag) { break; } } } } } return flag; } private static bool DoesActorMatchModCriteria(Actor source, Actor thirdParty) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected I4, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown Human val = ((Il2CppObjectBase)source).TryCast(); Human val2 = ((Il2CppObjectBase)thirdParty).TryCast(); if (val.humanID == val2.humanID) { return true; } bool flag = default(bool); if (((Actor)val2).isEnforcer && ((PluginController)PluginController.Instance).Config.IncludePoliceOfficers) { if (((PluginController)PluginController.Instance).Config.EnableDebugMode) { ManualLogSource log = PluginController.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Reaction of "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.GetCitizenName()); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" | Reason: Is Enforcer"); } log.LogInfo(val3); } return true; } Acquaintance val4 = default(Acquaintance); if (val2.FindAcquaintanceExists(val, ref val4)) { Enumerator enumerator = val4.connections.GetEnumerator(); while (enumerator.MoveNext()) { ConnectionType current = enumerator.Current; switch ((int)current) { case 4: case 5: case 6: case 8: case 10: case 20: if (!((PluginController)PluginController.Instance).Config.IncludeColleagues) { break; } if (((PluginController)PluginController.Instance).Config.EnableDebugMode) { ManualLogSource log3 = PluginController.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Reaction of "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.GetCitizenName()); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" | Reason: Is Colleague"); } log3.LogInfo(val3); } return true; case 0: case 2: case 3: case 16: if (!((PluginController)PluginController.Instance).Config.IncludeFriends) { break; } if (((PluginController)PluginController.Instance).Config.EnableDebugMode) { ManualLogSource log4 = PluginController.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Reaction of "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.GetCitizenName()); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" | Reason: Is Friend"); } log4.LogInfo(val3); } return true; case 1: if (!((PluginController)PluginController.Instance).Config.IncludeNeighbors) { break; } if (((PluginController)PluginController.Instance).Config.EnableDebugMode) { ManualLogSource log2 = PluginController.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Reaction of "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.GetCitizenName()); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" | Reason: Is Neighbor"); } log2.LogInfo(val3); } return true; } } } return false; } } }