using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using SOD.Common; using SOD.Common.Helpers; using SOD.Common.Helpers.DialogObjects; using SOD.Common.Helpers.GameplayObjects; using SOD.Common.Helpers.SyncDiskObjects; using TMPro; using TheSyndicate.Contracts; using TheSyndicate.Cripple; using TheSyndicate.CruncherApp; using TheSyndicate.DebugTools; using TheSyndicate.Evidence; using TheSyndicate.Firearms; using TheSyndicate.Heat; using TheSyndicate.Mask; using TheSyndicate.Money; using TheSyndicate.News; using TheSyndicate.Patches; using TheSyndicate.Poison; using TheSyndicate.Progression; using TheSyndicate.State; using TheSyndicate.Supplies; using TheSyndicate.Tools; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("TheSyndicate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c5b974631e2c7a6af0fc74c3998122ed3d16d298")] [assembly: AssemblyProduct("TheSyndicate")] [assembly: AssemblyTitle("TheSyndicate")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TheSyndicate { internal static class ConsoleTweaks { private const int STD_INPUT_HANDLE = -10; private const uint ENABLE_QUICK_EDIT_MODE = 64u; private const uint ENABLE_EXTENDED_FLAGS = 128u; [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); internal static void DisableQuickEdit() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown try { IntPtr stdHandle = GetStdHandle(-10); if (!(stdHandle == IntPtr.Zero) && !(stdHandle == new IntPtr(-1)) && GetConsoleMode(stdHandle, out var lpMode)) { uint num = (lpMode & 0xFFFFFFBFu) | 0x80; if (num != lpMode && SetConsoleMode(stdHandle, num)) { Plugin.Logger.LogInfo((object)"[Perf] Disabled console QuickEdit mode — the click-to-pause game freeze is gone. (Copy logs from BepInEx/LogOutput.log; set General/DisableConsoleQuickEdit=false to restore mouse-select.)"); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Perf] DisableQuickEdit failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } [BepInPlugin("Kropath.TheSyndicate", "The Syndicate", "0.9.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { internal static ManualLogSource Logger; internal static Harmony HarmonyInstance; internal static void LogVerbose(string msg) { ConfigEntry verboseLogging = SyndicateConfig.VerboseLogging; if (verboseLogging != null && verboseLogging.Value) { Logger.LogInfo((object)msg); } } public override void Load() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown Logger = ((BasePlugin)this).Log; ManualLogSource logger = Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("The Syndicate"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("0.9.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loading..."); } logger.LogInfo(val); SyndicateConfig.Init(((BasePlugin)this).Config); ConfigEntry disableConsoleQuickEdit = SyndicateConfig.DisableConsoleQuickEdit; if (disableConsoleQuickEdit == null || disableConsoleQuickEdit.Value) { ConsoleTweaks.DisableQuickEdit(); } Rewards.Register(); SyndicateState.Hook(); InvestigationTimer.Hook(); Lib.Gameplay.OnVictimReported += delegate(object? sender, VictimReportedArgs args) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown try { CrimeSceneManager.OnBodyReported(((VictimKilledArgs)args).Victim, args.Reporter); } catch (Exception ex) { ManualLogSource logger3 = Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Syndicate] OnVictimReported handler failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger3.LogWarning(val2); } }; ConfigEntry debugEnabled = SyndicateConfig.DebugEnabled; if (debugEnabled != null && debugEnabled.Value) { ((BasePlugin)this).AddComponent(); } ((BasePlugin)this).AddComponent(); ((BasePlugin)this).AddComponent(); ((BasePlugin)this).AddComponent(); ((BasePlugin)this).AddComponent(); HeatMeter.Source = () => SyndicateState.Data?.ResidualHeat ?? 0f; ((BasePlugin)this).AddComponent(); ((BasePlugin)this).AddComponent(); ((BasePlugin)this).AddComponent(); ((BasePlugin)this).AddComponent(); ((BasePlugin)this).AddComponent(); TipLine.Init(); PauseLine.Init(); FirearmsPose.Init(); FirearmsAssetTuner.Init(); EchelonHomeGuard.Init(); ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); HarmonyInstance = new Harmony("Kropath.TheSyndicate"); HarmonyInstance.PatchAll(typeof(Plugin).Assembly); ManualLogSource logger2 = Logger; val = new BepInExInfoLogInterpolatedStringHandler(26, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("The Syndicate"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded. "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(HarmonyInstance.GetPatchedMethods().Count()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" methods patched."); } logger2.LogInfo(val); } } internal static class PluginInfo { public const string GUID = "Kropath.TheSyndicate"; public const string NAME = "The Syndicate"; public const string VERSION = "0.9.0"; } internal static class ProtectedCitizens { internal const string LandlordPresetName = "SelfEmployedLandlord"; private static readonly Dictionary _lastToastByVictim = new Dictionary(); internal static bool IsProtected(Human h) { if ((Object)(object)h == (Object)null) { return false; } try { ConfigEntry protectFiniteNPCs = SyndicateConfig.ProtectFiniteNPCs; return (protectFiniteNPCs == null || protectFiniteNPCs.Value) && (((Actor)h).isEnforcer || IsLandlord(h)); } catch { return true; } } internal static bool IsContractExcluded(Human h) { if ((Object)(object)h == (Object)null) { return false; } if (!IsProtected(h)) { return IsLastCompanyWorker(h); } return true; } internal static bool IsLandlord(Human h) { try { object obj; if (h == null) { obj = null; } else { Occupation job = h.job; obj = ((job != null) ? job.preset : null); } OccupationPreset val = (OccupationPreset)obj; return (SoCustomComparison)(object)val != (SoCustomComparison)null && ((Object)val).name == "SelfEmployedLandlord"; } catch { return false; } } internal static bool IsLastCompanyWorker(Human h) { ConfigEntry protectLastCompanyWorker = SyndicateConfig.ProtectLastCompanyWorker; if (protectLastCompanyWorker != null && !protectLastCompanyWorker.Value) { return false; } try { if ((Object)(object)h == (Object)null) { return false; } if (((Actor)h).isEnforcer || IsLandlord(h)) { return false; } Occupation job = h.job; object obj; if (job == null) { obj = null; } else { Company employer = job.employer; obj = ((employer != null) ? employer.companyRoster : null); } List val = (List)obj; if (val == null) { return false; } bool result = false; Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Occupation current = enumerator.Current; Human val2 = ((current != null) ? current.employee : null); if (!((Object)(object)val2 == (Object)null)) { if (val2.humanID == h.humanID) { result = true; } else if (!((Actor)val2).isDead) { return false; } } } return result; } catch { return true; } } internal static void DegradeToKO(Citizen target) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)target != (Object)null && (Object)(object)((Actor)target).ai != (Object)null && !((Actor)target).ai.ko) { ((Actor)target).ai.SetKO(true, ((Component)target).transform.position, Vector3.up, false, 0f, true, 1f); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Protect] DegradeToKO SetKO failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } try { int key = (((Object)(object)target != (Object)null) ? ((Human)target).humanID : (-1)); float time = Time.time; if (_lastToastByVictim.TryGetValue(key, out var value) && time - value < 3f) { return; } _lastToastByVictim[key] = time; } catch { } try { Lib.GameMessage.Broadcast(RefusalLine((Human)(object)target), (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } internal static string RefusalLine(Human h) { try { if ((Object)(object)h != (Object)null && ((Actor)h).isEnforcer) { return "Enforcers stay breathing — the Syndicate needs the law predictable. Down, not dead."; } if (IsLandlord(h)) { return "Kill the landlord and the whole block goes to hell. Down, not dead."; } } catch { } return "This one's off-limits — the Syndicate wants them alive. Down, not dead."; } } internal static class SyndicateConfig { public static ConfigEntry WitnessReportMinHours; public static ConfigEntry WitnessReportMaxHours; public static ConfigEntry WelfareMinHours; public static ConfigEntry WelfareMaxHours; public static ConfigEntry SceneColdHours; public static ConfigEntry WitnessInterviewHours; public static ConfigEntry WarrantResolveHours; public static ConfigEntry WarrantDurationHours; public static ConfigEntry FingerprintIdHeatThreshold; public static ConfigEntry FingerprintIdCountThreshold; public static ConfigEntry FingerprintMinHeat; public static ConfigEntry FingerprintMaxHeat; public static ConfigEntry SuppressNativePlayerPrints; public static ConfigEntry ResidualHeatEnabled; public static ConfigEntry ResidualHeatPerMurderMax; public static ConfigEntry HeistOfferThreshold; public static ConfigEntry ResidualFinePerMurder; public static ConfigEntry ResidualWarrantAt100; public static ConfigEntry HeistEnabled; public static ConfigEntry HeistBackroomPercent; public static ConfigEntry HeistFolderPreset; public static ConfigEntry NewsEnabled; public static ConfigEntry NewsFreshHours; public static ConfigEntry NewsRoundupWindowDays; public static ConfigEntry NewsRoundupMinKills; public static ConfigEntry NewsSecondaryEnabled; public static ConfigEntry MaskNotorietyEnabled; public static ConfigEntry MaskNotorietyDecayPerDay; public static ConfigEntry MaskIncidentBase; public static ConfigEntry MaskIncidentMax; public static ConfigEntry MaskWitnessWeight; public static ConfigEntry MaskPublicPlaceMult; public static ConfigEntry MaskDaytimeMult; public static ConfigEntry MaskNerveDrainMult; public static ConfigEntry MaskRedisguiseCost; public static ConfigEntry MaskRedisguiseDrop; public static ConfigEntry MaskRedisguiseClearsHistory; public static ConfigEntry MaskMergeMinColdShare; public static ConfigEntry MaskMergeFineBasePercent; public static ConfigEntry MaskMergeFineNotorietyPercent; public static ConfigEntry MaskBustedDestroysMask; public static ConfigEntry MaskEnforcerSoftStopEnabled; public static ConfigEntry MaskEnforcerSoftStopThreshold; public static ConfigEntry MaskEnforcerSoftStopRange; public static ConfigEntry MaskEnforcerSoftStopCooldownSeconds; public static ConfigEntry RepairEchelonFloors; public static ConfigEntry CrippleEnabled; public static ConfigEntry CrippleSpeedMultiplier; public static ConfigEntry CrippleDurationSeconds; public static ConfigEntry CrippleBloodTrailEnabled; public static ConfigEntry CamerasIdentify; public static ConfigEntry CameraNearSceneHeat; public static ConfigEntry CameraNearSceneFreshWindowHours; public static ConfigEntry CameraSweepEnabled; public static ConfigEntry CamerasRespectDarkness; public static ConfigEntry HudClusterEnabled; public static ConfigEntry HudSceneTableEnabled; public static ConfigEntry HuntMode; public static ConfigEntry PursuitResponseRange; public static ConfigEntry PursuitMaxDistanceMeters; public static ConfigEntry PursuitRequireLineOfSight; public static ConfigEntry RequirePlayerInsideScene; public static ConfigEntry BodyDiscoveryRequireLineOfSight; public static ConfigEntry WelfareRaidEnabled; public static ConfigEntry WelfareRaidDelayHours; public static ConfigEntry WelfareRaidForceCrimeScene; public static ConfigEntry MurderFineAmount; public static ConfigEntry IllegalRefreshSeconds; public static ConfigEntry StakeoutEnabled; public static ConfigEntry HomeRaidDelayHours; public static ConfigEntry StakeoutForceCrimeScene; public static ConfigEntry StakeoutGuardHours; public static ConfigEntry RepPenaltyOnIdentifiedContract; public static ConfigEntry RepPenaltyOnIdentifiedRandom; public static ConfigEntry HitmanLevelPenaltyOnIdentified; public static ConfigEntry RepMessageDelaySeconds; public static ConfigEntry RepPenaltyOnContractCancel; public static ConfigEntry CaseBoardEnabled; public static ConfigEntry AutoCollectHours; public static ConfigEntry TipLineEnabled; public static ConfigEntry TipLineNumber; public static ConfigEntry PauseLineEnabled; public static ConfigEntry PauseLineNumber; public static ConfigEntry AutoAssignMaxLevel; public static ConfigEntry MaxConcurrentContractsL3; public static ConfigEntry OfferBoardSize; public static ConfigEntry RefreshBoardCooldownHours; public static ConfigEntry OfferLifetimeHours; public static ConfigEntry ContractCooldownHours; public static ConfigEntry FirstContractDelayHours; public static ConfigEntry DeadlineHours; public static ConfigEntry CloseToastEnabled; public static ConfigEntry OnboardingEnabled; public static ConfigEntry FirstJobAfterActivationHours; public static ConfigEntry CheckInReminder1Minutes; public static ConfigEntry CheckInReminder2Minutes; public static ConfigEntry MoleEmailEnabled; public static ConfigEntry ContractBasePayout; public static ConfigEntry DiffMultT2; public static ConfigEntry DiffMultT3; public static ConfigEntry InfoMultPartial; public static ConfigEntry InfoMultCold; public static ConfigEntry InfoFullPctT1; public static ConfigEntry InfoPartialPctT1; public static ConfigEntry InfoFullPctT2; public static ConfigEntry InfoPartialPctT2; public static ConfigEntry InfoFullPctT3; public static ConfigEntry InfoPartialPctT3; public static ConfigEntry InvestigationBias; public static ConfigEntry ObjChanceZero; public static ConfigEntry ObjChanceOne; public static ConfigEntry BonusClean; public static ConfigEntry BonusDeadline; public static ConfigEntry BonusPhoto; public static ConfigEntry BonusSuicide; public static ConfigEntry EnablePhotoObjective; public static ConfigEntry EnableSuicideObjective; public static ConfigEntry EnableDisposalObjective; public static ConfigEntry DisposalContractPercent; public static ConfigEntry DisposalPenalty; public static ConfigEntry DisposalMinLevel; public static ConfigEntry DisposalWeaponList; public static ConfigEntry EnableFallForge; public static ConfigEntry FallVariantPercent; public static ConfigEntry FallKillsEnabled; public static ConfigEntry LethalFallHeight; public static ConfigEntry HeaveKey; public static ConfigEntry HeaveSpeed; public static ConfigEntry DragLiftAssist; public static ConfigEntry FallSceneAtLanding; public static ConfigEntry FallAntiSnagEnabled; public static ConfigEntry FallAntiSnagForce; public static ConfigEntry HomeVacateEnabled; public static ConfigEntry HomeVacateDelayHours; public static ConfigEntry KODurationMultiplier; public static ConfigEntry BluntKOMultiplier; public static ConfigEntry BladeKOMultiplier; public static ConfigEntry Level1Rep; public static ConfigEntry Level2Rep; public static ConfigEntry Level3Rep; public static ConfigEntry Level1Reward; public static ConfigEntry Level2Reward; public static ConfigEntry Level3Reward; public static ConfigEntry SocialCreditPerToken; public static ConfigEntry SocialCreditPurchaseMoneyCost; public static ConfigEntry FineMinimumBalance; public static ConfigEntry FineEarlyPayoffPercent; public static ConfigEntry RaidWeaponSeizureEnabled; public static ConfigEntry RaidWeaponSurchargePercent; public static ConfigEntry CarryWeaponSeizureEnabled; public static ConfigEntry CarryWeaponSurchargePercent; public static ConfigEntry CruncherRaidPenaltyEnabled; public static ConfigEntry CruncherRaidSurchargePercent; public static ConfigEntry CruncherRaidRepLoss; public static ConfigEntry SafehouseBreachEnabled; public static ConfigEntry SuppliesEnabled; public static ConfigEntry SuppliesDiscountPercent; public static ConfigEntry SuppliesDeliveryHours; public static ConfigEntry GroceriesEnabled; public static ConfigEntry GroceriesMarkupPercent; public static ConfigEntry GearPriceMultiplier; public static ConfigEntry AmmoPriceMultiplier; public static ConfigEntry GunPriceMultiplier; public static ConfigEntry FirearmsEnabled; public static ConfigEntry FirearmsHeadshotLethal; public static ConfigEntry FirearmsHeadshotRadius; public static ConfigEntry FirearmsHeadshotDebug; public static ConfigEntry FirearmsOneShotWeapons; public static ConfigEntry FirearmsAccuracy; public static ConfigEntry FirearmsMinCooldownSeconds; public static ConfigEntry FirearmsConsumeAmmo; public static ConfigEntry FirearmsSpawnCasings; public static ConfigEntry FirearmsFireKey; public static ConfigEntry FirearmsMeleeKey; public static ConfigEntry FirearmsRecoil; public static ConfigEntry FirearmsPoseLab; public static ConfigEntry FirearmsReloadKey; public static ConfigEntry FirearmsReloadSeconds; public static ConfigEntry FirearmsMagazineSizes; public static ConfigEntry FirearmsAmmoBoxSizes; public static ConfigEntry FirearmsAmmoHud; public static ConfigEntry FirearmsAutoFireWeapons; public static ConfigEntry FirearmsAutoFireInterval; public static ConfigEntry FirearmsAutoRecoilScale; public static ConfigEntry FirearmsShotgunPellets; public static ConfigEntry FirearmsShotgunSpread; public static ConfigEntry FirearmsShotgunLethalPellets; public static ConfigEntry FirearmsShotgunAmmoKey; public static ConfigEntry FirearmsDrawnDread; public static ConfigEntry FirearmsDrawnNerve; public static ConfigEntry FirearmsDrawnRange; public static ConfigEntry FirearmsGunshotsAlarm; public static ConfigEntry FirearmsAlarmExemptGuns; public static ConfigEntry FirearmsGunshotSpook; public static ConfigEntry FirearmsRoomTurnOnHit; public static ConfigEntry FirearmsRoomTurnRange; public static ConfigEntry FirearmsInteractYieldDistance; public static ConfigEntry MaskToggleKey; public static ConfigEntry MaskScareEnabled; public static ConfigEntry MaskScareNerve; public static ConfigEntry MaskScareRange; public static ConfigEntry MaskScareEnforcers; public static ConfigEntry MaskedDescriptionHeat; public static ConfigEntry MaskUnmaskInViewIdentifies; public static ConfigEntry PoisonEnabled; public static ConfigEntry PoisonPromptOverride; public static ConfigEntry SyringeDoses; public static ConfigEntry VialDoses; public static ConfigEntry FingerprintRemoverCharges; public static ConfigEntry FingerprintRemoverPreset; public static ConfigEntry FingerprintRemoverRange; public static ConfigEntry FingerprintNoPrintPresets; public static ConfigEntry ChloroformEnabled; public static ConfigEntry ChloroformPreset; public static ConfigEntry ChloroformRange; public static ConfigEntry ChloroformBehindDot; public static ConfigEntry ChloroformDoses; public static ConfigEntry SedatePromptOverride; public static ConfigEntry EnableNoViolenceObjective; public static ConfigEntry NoViolenceChancePercent; public static ConfigEntry BonusNoViolence; public static ConfigEntry ForgeViolenceHeat; public static ConfigEntry PoisonRange; public static ConfigEntry PoisonCooldownSeconds; public static ConfigEntry SyringeKillDelayGameMinutes; public static ConfigEntry SyringeStaggerDrunk; public static ConfigEntry ForgeDelayMinutes; public static ConfigEntry EnablePoisonObjective; public static ConfigEntry BonusPoison; public static ConfigEntry ProtectFiniteNPCs; public static ConfigEntry ProtectLastCompanyWorker; public static ConfigEntry DisableConsoleQuickEdit; public static ConfigEntry SightCheckIntervalSeconds; public static ConfigEntry VerboseLogging; public static ConfigEntry MessageGapSeconds; public static ConfigEntry DebugEnabled; public static void Init(ConfigFile cfg) { WitnessReportMinHours = cfg.Bind("Manhunt", "WitnessReportMinHours", 2, "Minimum in-game hours a witness takes to reach the authorities and report. Kill/KO them before this to cancel it."); WitnessReportMaxHours = cfg.Bind("Manhunt", "WitnessReportMaxHours", 2, "Maximum in-game hours a witness takes to report."); WelfareMinHours = cfg.Bind("Manhunt", "WelfareMinHours", 24, "Minimum in-game hours before an unseen body is found by a welfare check."); WelfareMaxHours = cfg.Bind("Manhunt", "WelfareMaxHours", 48, "Maximum in-game hours before a welfare check finds an unseen body."); SceneColdHours = cfg.Bind("Manhunt", "SceneColdHours", 8, "In-game hours a discovered-but-unsolved scene stays open. If no witness reports in time, forensics decide, then it goes cold."); WitnessInterviewHours = cfg.Bind("Manhunt", "WitnessInterviewHours", 2, "Once a body is officially reported, pending witnesses who can name the player are interviewed within this many in-game hours (kill/KO them first to prevent it)."); WarrantResolveHours = cfg.Bind("Manhunt", "WarrantResolveHours", 2, "Grace hours after a positive ID before the warrant/hunt actually begins — a heads-up window, NOT an escape: the warrant issues regardless of where you are."); WarrantDurationHours = cfg.Bind("Manhunt", "WarrantDurationHours", 48, "How long a warrant stays active once issued."); FingerprintIdHeatThreshold = cfg.Bind("Evidence", "FingerprintIdHeatThreshold", 25, "Total fingerprint heat at a scene that alone makes a positive forensic ID."); FingerprintIdCountThreshold = cfg.Bind("Evidence", "FingerprintIdCountThreshold", 4, "Number of distinct fingerprinted objects at a scene that alone makes a positive forensic ID."); FingerprintMinHeat = cfg.Bind("Evidence", "FingerprintMinHeat", 3, "Minimum random heat weight assigned to each fingerprint left."); FingerprintMaxHeat = cfg.Bind("Evidence", "FingerprintMaxHeat", 12, "Maximum random heat weight assigned to each fingerprint left."); SuppressNativePlayerPrints = cfg.Bind("Evidence", "SuppressNativePlayerPrints", true, "Hide the game's always-on player fingerprint from the vanilla scanner on items you own/carry (weapons, casings, delivered supplies). This static print ignores gloves; suppressing it means only the mod's own gloves-gated print system marks you. Leaves NPC prints (incl. the fixer who mailed a weapon) intact. Disable to restore vanilla behaviour."); ResidualHeatEnabled = cfg.Bind("Heat", "ResidualHeatEnabled", true, "F2 cumulative residual-evidence meter: when a murder's case goes COLD but you still left sub-threshold evidence, the top-centre HEAT bar climbs. At ~80% the Syndicate offers a clearing heist; at 100% the law catches up. Turn off to freeze the meter at 0."); ResidualHeatPerMurderMax = cfg.Bind("Heat", "ResidualHeatPerMurderMax", 0.2f, "The MOST a single cold-but-messy murder can add to the residual-evidence meter (0.20 = 20%). The actual add is this times how close the scene came to identifying you (its fingerprint heat/count vs the ID thresholds)."); HeistOfferThreshold = cfg.Bind("Heat", "HeistOfferThreshold", 0.8f, "At this meter level (0.80 = 80%) the Syndicate v-mails you a tip and opens the 'Loose Ends' heist to clear it. Clamped 0.10-0.95."); ResidualFinePerMurder = cfg.Bind("Heat", "ResidualFinePerMurder", 1000, "At 100% the law catches up: this fine (credits) is levied for EACH murder that fed the meter. Half a full-ID murder fine by default (residual evidence is weaker than a positive ID)."); ResidualWarrantAt100 = cfg.Bind("Heat", "ResidualWarrantAt100", true, "At 100%, also issue a single warrant (enforcers hunt you) alongside the fines. Off = fines only."); HeistEnabled = cfg.Bind("Heist", "Enabled", true, "Enable the 'Loose Ends' evidence heist offered at ~80% meter. Off = no offer/heist (the meter still climbs to the 100% punishment, which becomes the only outcome)."); HeistBackroomPercent = cfg.Bind("Heist", "BackroomPercent", 80, "Chance (%) the evidence folder spawns in the enforcer division office's password-protected secure BACKROOM (the highest-security room in the office). Otherwise it lands on a desk deeper in the office (never reception). Clamped 0-100. The folder always spawns in a division office now — never a home."); HeistFolderPreset = cfg.Bind("Heist", "FolderPreset", "SealedEnvelope", "Item preset spawned as the stealable evidence folder. Default 'SealedEnvelope' = the in-game 'Secret Envelope'. Blank = auto (prefer a carryable documents item, else a briefcase). Set another PascalCase preset name to override — use the 'Find secret-envelope-like presets' debug button to discover names."); NewsEnabled = cfg.Bind("News", "Enabled", true, "Enable The Syndicate's custom front-page stories in the in-game newspaper (murder/manhunt/heist beats named with the real victim and location) and the matching city news-ticker headline. Off = the vanilla paper only."); NewsFreshHours = cfg.Bind("News", "FreshHours", 48, "How long (in-game hours) a Syndicate news beat stays eligible to run on the front page. After this it drops off and the paper reverts to vanilla filler (or the next fresher beat)."); NewsRoundupWindowDays = cfg.Bind("News", "RoundupWindowDays", 3, "Window (in-game days) the 'crime wave' round-up story counts recent killings over."); NewsRoundupMinKills = cfg.Bind("News", "RoundupMinKills", 3, "Minimum distinct victims within the round-up window before the 'crime wave' story runs instead of a single-victim story."); NewsSecondaryEnabled = cfg.Bind("News", "SecondaryStory", true, "Allow a second Syndicate beat to occupy the newspaper's article-2 slot when two stories are live. Off = only the top story is injected and any displaced vanilla lead keeps slot 2."); MaskNotorietyEnabled = cfg.Bind("MaskNotoriety", "Enabled", true, "Master switch for the masked-persona notoriety system (meter, HUD bar, gradient effects, merge-on-slip, busted reveal). Off = masked crimes behave as before F7."); MaskNotorietyDecayPerDay = cfg.Bind("MaskNotoriety", "DecayPerDay", 0.15f, "Notoriety lost per in-game day of lying low (not being seen committing a masked crime). 0.15 ≈ a maxed persona fades in ~7 days."); MaskIncidentBase = cfg.Bind("MaskNotoriety", "IncidentBase", 0.1f, "Base notoriety added per masked crime that gets seen (before brazenness scaling)."); MaskIncidentMax = cfg.Bind("MaskNotoriety", "IncidentMax", 0.3f, "Cap on the notoriety added by a single masked incident after brazenness scaling."); MaskWitnessWeight = cfg.Bind("MaskNotoriety", "WitnessWeight", 0.15f, "+fraction per witness beyond the first (capped at 4 extra), multiplying the incident bump."); MaskPublicPlaceMult = cfg.Bind("MaskNotoriety", "PublicPlaceMult", 1.5f, "Multiplier when the masked crime is in a public place (street / lobby / common area)."); MaskDaytimeMult = cfg.Bind("MaskNotoriety", "DaytimeMult", 1.25f, "Multiplier when the masked crime happens in daytime (~07:00–21:00)."); MaskNerveDrainMult = cfg.Bind("MaskNotoriety", "NerveDrainMult", 4f, "Extra nerve-drain multiplier at full notoriety for civilians who SEE the masked player (they panic/flee sooner). Scales from 0 (base ambient dread only) up to this at N=1."); MaskRedisguiseCost = cfg.Bind("MaskNotoriety", "RedisguiseCost", 2500, "Cost of a 'Persona Wipe' (new disguise) from the Supplies app, which drops notoriety."); MaskRedisguiseDrop = cfg.Bind("MaskNotoriety", "RedisguiseDrop", 1f, "Notoriety removed per Persona Wipe (1.0 = full reset)."); MaskRedisguiseClearsHistory = cfg.Bind("MaskNotoriety", "RedisguiseClearsHistory", false, "If true, a Persona Wipe also erases the masked-incident case files (a later slip can't merge old crimes). Default false = the street cools but the case files remain."); MaskMergeMinColdShare = cfg.Bind("MaskNotoriety", "MergeMinColdShare", 0.25f, "Share of the COLD masked spree merged onto you on a slip at zero notoriety (scales to 100% at full notoriety), newest-first."); MaskMergeFineBasePercent = cfg.Bind("MaskNotoriety", "MergeFineBasePercent", 50, "Per-merged-cold-incident fine as a % of the standard murder fine, at zero notoriety."); MaskMergeFineNotorietyPercent = cfg.Bind("MaskNotoriety", "MergeFineNotorietyPercent", 50, "Additional per-incident fine %, scaled by notoriety (so at N=1 the fine = Base+this % of the murder fine)."); MaskBustedDestroysMask = cfg.Bind("MaskNotoriety", "BustedDestroysMask", true, "If true, getting busted while masked confiscates (uninstalls) the mask disk — you must acquire a new one."); MaskEnforcerSoftStopEnabled = cfg.Bind("MaskNotoriety", "EnforcerSoftStopEnabled", false, "OFF by default. When on, at high notoriety enforcers who SEE the masked player give a soft 'stop and look' (heightened suspicion, NOT a chase). Fires off raw line-of-sight — tune before enabling."); MaskEnforcerSoftStopThreshold = cfg.Bind("MaskNotoriety", "EnforcerSoftStopThreshold", 0.5f, "Minimum notoriety before enforcers start eyeing the mask (soft-stop tier)."); MaskEnforcerSoftStopRange = cfg.Bind("MaskNotoriety", "EnforcerSoftStopRange", 12f, "Metres within which a seeing enforcer reacts to the notorious mask (kept tight vs the 50m warrant pursuit)."); MaskEnforcerSoftStopCooldownSeconds = cfg.Bind("MaskNotoriety", "EnforcerSoftStopCooldownSeconds", 90f, "Per-enforcer cooldown between soft-stop looks."); RepairEchelonFloors = cfg.Bind("Echelons", "RepairEchelonFloors", true, "Repair high-security 'echelon' floors on city load. A new game LOADS a pre-generated city whose floors deserialize with isEchelons stuck false (a vanilla save/load bug — NewFloor.Load trusts a stale serialized flag instead of recomputing it), so echelon floors never trespass-flag you and cameras/enforcers ignore you there even without the echelon-access perk. This recomputes the flag per floor from the building preset exactly as city-generation does, restoring trespassing + camera/enforcer detection. Idempotent; a no-op on correctly-serialized cities; self-heals existing saves. Disable to restore vanilla (buggy) behaviour."); CrippleEnabled = cfg.Bind("Cripple", "Enabled", true, "Non-lethal player melee/gunshot hits 'cripple' an NPC — they move slower (limp) for a while. Refresh-only (repeat hits reset the timer, never stack). Session-only: a mid-effect save/load forgets it (it's a short combat debuff)."); CrippleSpeedMultiplier = cfg.Bind("Cripple", "SpeedMultiplier", 0.3f, "Crippled NPCs move at this fraction of normal speed (0.3 = 70% slower). Clamped 0.05-1."); CrippleDurationSeconds = cfg.Bind("Cripple", "DurationSeconds", 90f, "How long (REAL seconds) a cripple lasts before the NPC recovers full speed."); CrippleBloodTrailEnabled = cfg.Bind("Cripple", "BloodTrailEnabled", true, "#D: a crippled NPC leaves a light blood drip as they limp (pure flair — no health loss, no aggro; the drops use the game's own blood spatter and fade on the normal decal timer). Off = no trail."); CamerasIdentify = cfg.Bind("Cameras", "Identify", true, "Security cameras that see you commit a murder, OR see you INSIDE the crime-scene apartment, IDENTIFY you — a guaranteed warrant, beaten only by wearing the mask. A camera that only catches you in the common AREA of the scene's floor (hall/landing) does NOT identify you — it just raises heat (see NearSceneHeat), since it never saw the murder or placed you at the body. Cameras act as eyewitnesses that can't be knocked out. Cameras inside your OWN apartment are exempt."); CameraNearSceneHeat = cfg.Bind("Cameras", "NearSceneHeat", 15, "Heat added when a common-area camera (hall/landing on the crime-scene floor) catches you UNMASKED near — but not inside — a crime scene. It does NOT identify you (no warrant); it only raises suspicion. The camera can't report a murder it hasn't found, so — like a witness — it RECORDS the sighting at the time (you get a cue) and the heat only lands once the body is discovered and the footage is reviewed (about WitnessReportMinHours-MaxHours later). Once per scene. A camera inside the scene apartment, or one that saw the kill, still identifies you outright."); CameraNearSceneFreshWindowHours = cfg.Bind("Cameras", "NearSceneFreshWindowHours", 2, "How many in-game HOURS after a kill a common-area camera sighting still raises suspicion (see NearSceneHeat). Past this window, a camera that catches you in the hall/landing near the scene no longer adds heat — a casual sighting has gone cold. Only affects the SUSPICION path; a camera that saw the murder or caught you INSIDE the scene still identifies you outright, regardless of time. 0 = no window (a sighting counts for as long as the case is open — the previous behaviour)."); CameraSweepEnabled = cfg.Bind("Cameras", "SweepEnabled", true, "When a camera spots a WANTED or MASKED player, dispatch a brief enforcer sweep to WHERE THEY WERE SPOTTED — separate from the crime-scene response and the home raid. ONE sweep at a time: a new one is sent only after the previous finishes, so a hunted player is chased with natural delay instead of spamming the city's ~12 enforcers."); CamerasRespectDarkness = cfg.Bind("Cameras", "RespectDarkness", true, "Cameras use the game's OWN light/stealth model: your personal light level (plus crouch-stealth; running or a lit FLASHLIGHT gives you away) sets the maximum distance a camera can detect you, exactly like vanilla camera sighting — standing in the dark defeats a camera unless you're nearly under it (point-blank ~0.75m always spots you). Applies to EVERY Syndicate camera check: kill-witness ID, at-scene ID, near-scene suspicion heat, the wanted-player camera hunt, and the unmask face-connect. Human witnesses are unaffected. It can only ever SHRINK detection in darkness (a provable no-op in bright light). Disable to restore the previous behaviour (cameras ignore darkness)."); HudClusterEnabled = cfg.Bind("Hud", "ClusterEnabled", true, "Show the Syndicate HUD cluster along the top of the screen: your Syndicate level and open crime scenes (top-left), a MASK ON/OFF indicator (top-right, when the mask disk is installed), and the heat/evidence meter (top-centre). Turn off to hide the whole cluster."); HudSceneTableEnabled = cfg.Bind("Hud", "SceneTableEnabled", true, "Show a small table under the Syndicate-level badge listing your open crime scenes (victim + status: undiscovered / under investigation / going cold). Auto-hides when you have no open scenes. Requires the HUD cluster to be on."); HuntMode = cfg.Bind("Enforcers", "HuntMode", TheSyndicate.Heat.HuntMode.EnforcerPursuit, "How enforcers become hostile while you're wanted. EnforcerPursuit (recommended): only enforcers who actually SEE you chase you — no civilian panic. GlobalIllegal: vanilla 'wanted' — the whole city reacts (may cause a hitch when the hunt starts)."); PursuitResponseRange = cfg.Bind("Enforcers", "PursuitResponseRange", 5f, "SetPersue 'response range' when an enforcer acquires you — how far additional enforcers get recruited. Keep low to avoid pathfinding spikes."); PursuitMaxDistanceMeters = cfg.Bind("Enforcers", "PursuitMaxDistanceMeters", 50f, "EnforcerPursuit mode: only consider enforcers this close (or in your building) for the sight check each tick."); PursuitRequireLineOfSight = cfg.Bind("Enforcers", "PursuitRequireLineOfSight", true, "Require a physical line-of-sight ray (no wall in between) before an enforcer or witness counts as seeing you. Disable to restore the vanilla awareness-only check."); RequirePlayerInsideScene = cfg.Bind("Manhunt", "RequirePlayerInsideScene", true, "Only count 'caught red-handed' / scene witnesses when the PLAYER is physically inside the crime scene's apartment (any room) — not the lobby/stairs/landing/another floor."); BodyDiscoveryRequireLineOfSight = cfg.Bind("Manhunt", "BodyDiscoveryRequireLineOfSight", true, "Require a physical line-of-sight ray before an NPC in a DIFFERENT room can spot a dead/KO'd body (vanilla sees through walls within ~6.5m). Same-room spotting and body smell are unaffected — a hidden body is still found by anyone who walks in or eventually smells it. Disable to restore vanilla through-wall spotting."); WelfareRaidEnabled = cfg.Bind("Manhunt", "WelfareRaidEnabled", true, "When the welfare window on an undiscovered body lapses, dispatch an enforcer welfare check to the victim's home (a concerned relative / missed-work report). The cops finding the body IS the discovery. Disabled: the scene silently flips to discovered as before."); WelfareRaidDelayHours = cfg.Bind("Manhunt", "WelfareRaidDelayHours", 0.25f, "In-GAME hours between the welfare call coming in and enforcers setting out (CallEnforcers' delay is game-hours). 0.25h = 15 game-minutes."); WelfareRaidForceCrimeScene = cfg.Bind("Manhunt", "WelfareRaidForceCrimeScene", false, "If true the welfare response is dispatched pre-flagged as a crime scene (tape + guard). Leave false: the game flags it automatically the moment responders find a dead occupant, and a false alarm (body moved) then stays low-key."); MurderFineAmount = cfg.Bind("Enforcers", "MurderFineAmount", 2000, "Credits added to the Syndicate fine ledger per Identified murder. Collected on capture (leaving a minimum), remainder persists forever; settleable early at a discount."); IllegalRefreshSeconds = cfg.Bind("Enforcers", "IllegalRefreshSeconds", 30f, "Seconds the player's 'illegal' hunt flag lasts per refresh while warranted (re-applied at half this cadence). Lower = it lapses faster if the mod ever stops ticking."); StakeoutEnabled = cfg.Bind("Enforcers", "StakeoutEnabled", true, "On a warrant, send enforcers to the suspect's home. If the suspect is there, enforcer-pursuit engages; if not, the native response guards/patrols it."); HomeRaidDelayHours = cfg.Bind("Enforcers", "HomeRaidDelayHours", 0.05f, "In-GAME hours before enforcers set out for the suspect's home after a warrant (CallEnforcers' delay is game-hours, not seconds). 0.05h ~ 3 game-minutes; set 0 for instant."); StakeoutGuardHours = cfg.Bind("Enforcers", "StakeoutGuardHours", 24f, "Game-hours per guard-duty shift at the suspect's home (mirrors the game's own 24h guard goal). The guard is automatically re-posted while the warrant lasts."); StakeoutForceCrimeScene = cfg.Bind("Enforcers", "StakeoutForceCrimeScene", false, "If true the home raid is dispatched as a crime scene (tapes + a lingering guard, like a murder scene); if false it's a plain targeted response. Probe both to see which posts a guard."); RepPenaltyOnIdentifiedContract = cfg.Bind("Enforcers", "RepPenaltyOnIdentifiedContract", 25, "Underworld rep the Syndicate docks when you're Identified for killing one of THEIR contract targets (once per murder). Botching a sanctioned job embarrasses them. 0 disables."); RepPenaltyOnIdentifiedRandom = cfg.Bind("Enforcers", "RepPenaltyOnIdentifiedRandom", 10, "Underworld rep docked when you're Identified for a NON-contract (freelance/random) kill — less than a botched contract, but still sloppy. 0 disables."); HitmanLevelPenaltyOnIdentified = cfg.Bind("Enforcers", "HitmanLevelPenaltyOnIdentified", 0, "Reserved: hitman-level knock on being Identified (tier already derives from rep). 0 = off."); RepMessageDelaySeconds = cfg.Bind("Enforcers", "RepMessageDelaySeconds", 20f, "Seconds to delay the 'Syndicate standing has taken a hit' toast so it doesn't flood the screen during the caught/wanted flurry."); FineMinimumBalance = cfg.Bind("Fines", "FineMinimumBalance", 5, "Credits always left in your pocket when murder fines are collected at hospital (vanilla leaves 5)."); FineEarlyPayoffPercent = cfg.Bind("Fines", "FineEarlyPayoffPercent", 60, "Settle your outstanding murder fines EARLY (before capture) for this percent of the total. Capture always collects 100%."); RaidWeaponSeizureEnabled = cfg.Bind("Fines", "RaidWeaponSeizureEnabled", true, "During the warrant home-raid, if a murder weapon you used is at your apartment, enforcers seize it (it's destroyed) and surcharge that murder's fine — even if you're not home."); RaidWeaponSurchargePercent = cfg.Bind("Fines", "RaidWeaponSurchargePercent", 50, "Home-raid weapon-seizure surcharge, per seized weapon per victim, as a percent of MurderFineAmount (50 = 1000cr at the 2000 default). 0 = seize with no fine bump."); CarryWeaponSeizureEnabled = cfg.Bind("Fines", "CarryWeaponSeizureEnabled", true, "If you're busted (downed while wanted) while carrying a murder weapon you used, it's confiscated (destroyed) and that murder's fine is surcharged."); CarryWeaponSurchargePercent = cfg.Bind("Fines", "CarryWeaponSurchargePercent", 50, "Caught-carrying weapon surcharge, per confiscated weapon per victim, as a percent of MurderFineAmount (50 = 1000cr at the 2000 default). 0 = confiscate with no fine bump."); CruncherRaidPenaltyEnabled = cfg.Bind("Fines", "CruncherRaidPenaltyEnabled", true, "During the warrant home-raid, if a computer at your home is powered on AND logged in as you, enforcers pull your files: the murder fine is surcharged and the Syndicate docks your standing. Power off or log out before you run."); CruncherRaidSurchargePercent = cfg.Bind("Fines", "CruncherRaidSurchargePercent", 25, "Cruncher-exposure surcharge as a percent of MurderFineAmount (25 = 500cr at the 2000 default). 0 = no fine bump."); CruncherRaidRepLoss = cfg.Bind("Fines", "CruncherRaidRepLoss", 5, "Underworld rep docked when the raid finds your cruncher powered on and logged in. 0 disables."); SafehouseBreachEnabled = cfg.Bind("Enforcers", "SafehouseBreachEnabled", true, "During a warrant, when hunters see you flee into your own (locked) home, dispatch ONE enforcer breach+sweep so they don't just give up at your door. If they don't find you they leave; the landing guard stays posted. Fleeing home again triggers another breach."); RepPenaltyOnContractCancel = cfg.Bind("Contracts", "RepPenaltyOnContractCancel", 5, "Underworld rep the Syndicate docks when you cancel/abandon an active contract. Backing out has a price, but a small one. 0 disables."); CaseBoardEnabled = cfg.Bind("Contracts", "CaseBoardEnabled", true, "Give each accepted hit contract a custom case on the detective pinboard (target + objective checklist). Purely presentation — turning it off changes nothing about payouts or objectives; the contract still works entirely through the Cruncher and v-mail."); AutoCollectHours = cfg.Bind("Contracts", "AutoCollectHours", 24, "In-game hours after a contract's payment becomes collectable (its crime scene resolves) before the fixer auto-wires it if you never collect at your terminal — a safety net so payment can never get stranded. Clamped to at least 1."); TipLineEnabled = cfg.Bind("TipLine", "Enabled", true, "Enable the Syndicate anonymous tip line — an in-world phone number you can dial to 'call in' a hidden contract body, so the investigation (and your forensics-gated payment) starts sooner instead of waiting for the welfare check. It's accelerate-only: leaving prints/witnesses still gets you caught, just sooner. When off, no tip line is registered and the case-board hint / v-mail line are omitted."); TipLineNumber = cfg.Bind("TipLine", "Number", 9008477, "The tip line's phone number (7 digits, shown as XXX-XXXX). Default 9008477 = '900-TIPS'. Keep it outside BOTH the game's real-number band (1000000-6999000) AND its dynamic fake-callback band (8000000-8999000, which murder-ransom and side-job 'call this number' objectives draw from), and away from the reserved service numbers (1540000/5410000/9110000) — only change it if a save shows a collision."); PauseLineEnabled = cfg.Bind("PauseLine", "Enabled", true, "Enable the Dispatcher line — a phone number (in your phonebook from the start) you dial to go off the books: no new auto-assigned contracts, no board refills, no accepts, until you dial again. Active contracts are unaffected. If disabled while paused, contracts auto-resume on next load."); PauseLineNumber = cfg.Bind("PauseLine", "Number", 9007378, "The Dispatcher's number (7 digits, shown as XXX-XXXX). Default 9007378 = '900-REST'. Keep it outside the game's real-number band (1000000-6999000), its dynamic fake-callback band (8000000-8999000), away from the reserved service numbers (1540000/5410000/9110000), and different from the tip line — only change it if a save shows a collision."); AutoAssignMaxLevel = cfg.Bind("Contracts", "AutoAssignMaxLevel", 2, "Highest Syndicate level at which the fixer AUTO-ASSIGNS contracts (one at a time, via v-mail). From the next level up you pick your own jobs on the home Cruncher's job board."); MaxConcurrentContractsL3 = cfg.Bind("Contracts", "MaxConcurrentContractsL3", 3, "How many contracts you may hold active at once once the job board unlocks (Level 3). Below that it is always one at a time. Accept jobs from the board up to this cap; a value of 1 restores the old single-contract behaviour at every level."); OfferBoardSize = cfg.Bind("Contracts", "OfferBoardSize", 8, "How many contract offers the L3 Cruncher job board holds (1-8). The app pages the list (store/status/refresh rows stay pinned, roughly 3 offers per page), so larger boards just add pages."); RefreshBoardCooldownHours = cfg.Bind("Contracts", "RefreshBoardCooldownHours", 6, "In-game hours between manual board REFRESHes (the L3 Cruncher's REFRESH row rerolls the whole board for free). The cooldown stops reroll-fishing for a specific objective. 0 = no cooldown."); OfferLifetimeHours = cfg.Bind("Contracts", "OfferLifetimeHours", 48, "In-game hours an un-accepted listing stays on the L3 Cruncher job board before the market moves on and it is replaced (evaluated when the board renders). Each listing varies by a few hours so the board turns over gradually. Very low values churn the board every open."); ContractCooldownHours = cfg.Bind("Contracts", "ContractCooldownHours", 12, "In-game hours after a contract closes (completed/failed/cancelled) before the next auto-assigned job arrives."); FirstContractDelayHours = cfg.Bind("Contracts", "FirstContractDelayHours", 1, "In-game hours after becoming eligible (activating with the Dispatcher, or reaching a contractable level with onboarding off) before the first auto-assigned contract v-mail lands. NOTE: onboarding uses [Onboarding] FirstJobAfterActivationHours for the post-check-in first job instead."); DeadlineHours = cfg.Bind("Contracts", "DeadlineHours", 48, "In-game hours the optional deadline objective allows from the moment the contract is issued (values below 24 are clamped — the client always gives you at least a day to investigate and plan)."); CloseToastEnabled = cfg.Bind("Contracts", "CloseToastEnabled", true, "Feature 4: after a contract closes, a short toast tells you when the next job lands (and, pre-L3, that you can call the Dispatcher to pull one now)."); OnboardingEnabled = cfg.Bind("Onboarding", "Enabled", true, "The v1.0 onboarding flow: an intro v-mail on a new game, then contracts stay GATED until you call the Dispatcher to check in (with 30/60-min reminders), a gentle first 'proving' hit, and one-shot tutorial toasts. Turn OFF to start already activated with no intro/tutorial (contracts flow immediately once you reach Level 1)."); FirstJobAfterActivationHours = cfg.Bind("Onboarding", "FirstJobAfterActivationHours", 2, "In-game hours after you call the Dispatcher to check in before the FIRST contract lands — time to learn the streets. 0 = immediate."); CheckInReminder1Minutes = cfg.Bind("Onboarding", "CheckInReminder1Minutes", 30, "In-game minutes after the intro v-mail before the first 'call the Dispatcher' reminder toast. 0 disables it."); CheckInReminder2Minutes = cfg.Bind("Onboarding", "CheckInReminder2Minutes", 60, "In-game minutes after the intro v-mail before the SECOND and final check-in reminder. After this, reminders stop — calling in is your choice. 0 disables it."); MoleEmailEnabled = cfg.Bind("Heat", "MoleEmailEnabled", true, "Feature 5: when a case goes cold but you left forensic traces, a v-mail from the Syndicate's source inside the Enforcers itemizes exactly what fed the residual heat (fingerprints by room, a camera that clocked you, a beaten body)."); ContractBasePayout = cfg.Bind("ContractEconomy", "ContractBasePayout", 900, "BASE of the payout formula: payout = BASE x difficulty x info x (1 + sum of met objective bonuses)."); DiffMultT2 = cfg.Bind("ContractEconomy", "DiffMultT2", 1.7f, "Difficulty multiplier for Tier 2 contracts (Tier 1 is fixed at 1.0)."); DiffMultT3 = cfg.Bind("ContractEconomy", "DiffMultT3", 2.8f, "Difficulty multiplier for Tier 3 contracts."); InfoMultPartial = cfg.Bind("ContractEconomy", "InfoMultPartial", 1.5f, "Payout multiplier when the offer only carries a PARTIAL lead (you investigate the rest; Full is fixed at 1.0)."); InfoMultCold = cfg.Bind("ContractEconomy", "InfoMultCold", 2.2f, "Payout multiplier for a COLD lead (a thin scrap — initial, description, district)."); InfoFullPctT1 = cfg.Bind("ContractEconomy", "InfoFullPctT1", 60, "Tier-1 info distribution: percent of offers with a FULL dossier. Partial below; Cold = 100 - Full - Partial."); InfoPartialPctT1 = cfg.Bind("ContractEconomy", "InfoPartialPctT1", 40, "Tier-1 info distribution: percent with a PARTIAL lead."); InfoFullPctT2 = cfg.Bind("ContractEconomy", "InfoFullPctT2", 40, "Tier-2 info distribution: percent FULL."); InfoPartialPctT2 = cfg.Bind("ContractEconomy", "InfoPartialPctT2", 45, "Tier-2 info distribution: percent PARTIAL (Cold = remainder, 15 by default)."); InfoFullPctT3 = cfg.Bind("ContractEconomy", "InfoFullPctT3", 15, "Tier-3 info distribution: percent FULL."); InfoPartialPctT3 = cfg.Bind("ContractEconomy", "InfoPartialPctT3", 50, "Tier-3 info distribution: percent PARTIAL (Cold = remainder, 35 by default)."); InvestigationBias = cfg.Bind("ContractEconomy", "InvestigationBias", 0, "Single global shifter (-50..50): positive moves offer chance from Full toward Partial/Cold (more detective work), negative toward Full (more point-and-click)."); ObjChanceZero = cfg.Bind("ContractEconomy", "ObjChanceZero", 45, "Percent of contracts rolled with ZERO optional objectives."); ObjChanceOne = cfg.Bind("ContractEconomy", "ObjChanceOne", 40, "Percent with exactly ONE optional objective (two = the remainder, 15 by default)."); BonusClean = cfg.Bind("ContractEconomy", "BonusClean", 0.25f, "Payout fraction added for the clean/no-ID objective — paid in ESCROW when the victim's case closes without identifying you."); BonusDeadline = cfg.Bind("ContractEconomy", "BonusDeadline", 0.2f, "Payout fraction added for completing within the deadline."); BonusPhoto = cfg.Bind("ContractEconomy", "BonusPhoto", 0.3f, "Payout fraction added for the photo-of-body objective — earned by photographing the corpse any time after the kill (before you collect)."); BonusSuicide = cfg.Bind("ContractEconomy", "BonusSuicide", 0.5f, "Payout fraction for the forge-suicide objective — paid in ESCROW when the victim's forged-overdose case closes WITHOUT identifying you (a blown forgery pays nothing and brings heat). Needs the vial (#48), which is mailed on accept."); BonusPoison = cfg.Bind("ContractEconomy", "BonusPoison", 0.35f, "Payout fraction for the poison-kill objective — earned by killing the target with the Syndicate syringe (#48), which is mailed to you on accept. Any other kill method misses it."); EnablePhotoObjective = cfg.Bind("ContractEconomy", "EnablePhotoObjective", true, "Allow the photo-of-body bonus objective to roll (landed in slice 3). Photograph the corpse with the camera any time after the kill and before you collect to earn the bonus; missing it just drops that bonus."); EnablePoisonObjective = cfg.Bind("ContractEconomy", "EnablePoisonObjective", true, "Allow the poison-kill objective to roll (#48). The target must be killed with the mailed syringe. Mutually exclusive with the forge-suicide objective on a given contract."); EnableSuicideObjective = cfg.Bind("ContractEconomy", "EnableSuicideObjective", true, "Allow the forge-suicide objective to roll (#48). Stage a clean overdose with the mailed vial; the bonus escrows and pays only if the case closes without your name on it. Mutually exclusive with the poison-kill objective on a given contract."); EnableDisposalObjective = cfg.Bind("ContractEconomy", "EnableDisposalObjective", true, "Allow the weapon-disposal-at-sea TERM to attach to a contract (#73). The Syndicate mails you a specific poison/melee weapon; you must kill the target with THAT weapon and then throw it in the sea. Keep the weapon and the base fee takes a cut (DisposalPenalty). Not a bonus — a penalty-bearing term."); DisposalContractPercent = cfg.Bind("ContractEconomy", "DisposalContractPercent", 25, "Percent of eligible contracts (poison/melee-killable, not already a poison-kill/forge-suicide job) that carry the sea-disposal term. 0 disables it without touching EnableDisposalObjective."); DisposalPenalty = cfg.Bind("ContractEconomy", "DisposalPenalty", 0.45f, "Fraction of the BASE fee DEDUCTED when you don't dump the issued weapon at sea (you keep the weapon instead). 0.45 = a ~45% base cut. Clamped so the payout never goes negative."); DisposalMinLevel = cfg.Bind("ContractEconomy", "DisposalMinLevel", 0, "Lowest Syndicate level at which the sea-disposal term attaches to a poison/forge job (0 = from the very start, so a Level-0 proving hit that mails you a syringe also asks you to dump it)."); DisposalWeaponList = cfg.Bind("ContractEconomy", "DisposalWeaponList", "Syringe,KitchenKnifeLarge,CombatKnife,Truncheon,BasBouleBat,VintageSword,Katana", "PascalCase item presets the Syndicate may issue for a sea-disposal job — POISON or MELEE only, never firearms. Comma-separated. One is picked at random per contract, mailed on accept."); EnableFallForge = cfg.Bind("ContractEconomy", "EnableFallForge", true, "Allow the forge-suicide objective to roll its 'forge a fall' variant (drag a KO'd target off a high point — stairwell opening, rooftop) instead of the overdose variant (#75). While off, every forge-suicide job is the overdose variant."); FallVariantPercent = cfg.Bind("ContractEconomy", "FallVariantPercent", 40, "When EnableFallForge is on, percent of forge-suicide jobs that use the 'forge a fall' variant (the rest are 'forge an overdose')."); FallKillsEnabled = cfg.Bind("Fall", "FallKillsEnabled", true, "Enable fall-damage kills (#75): drag a KO'd (still-living) citizen off a high point — a stairwell opening, a rooftop — and the fall kills them (the base game has no NPC fall damage). A clean case reads as an accidental fall. Off = dropped bodies just land, as in vanilla."); LethalFallHeight = cfg.Bind("Fall", "LethalFallHeight", 6f, "How far (in metres) a dragged KO'd body must fall below its release point to die from the impact. ~6m is roughly two floors, so a KO'd body dropped from a second-floor window dies. Lower = easier fall kills."); HeaveKey = cfg.Bind("Fall", "HeaveKey", (KeyCode)103, "While DRAGGING a KO'd body, press this to HEAVE it in the direction you're looking (the vanilla drag can't lift a body up and out a window well). Drag the body to the opening on the ground, aim out, and heave. None = disabled."); HeaveSpeed = cfg.Bind("Fall", "HeaveSpeed", 6f, "Launch speed (metres/second) of a heaved body. Higher = it flies further/faster out the window. Tune to taste."); DragLiftAssist = cfg.Bind("Fall", "DragLiftAssist", 0.8f, "0..1 lift assist while DRAGGING a KO'd body — cancels this fraction of gravity on the ragdoll so it feels lighter to lift up and out a window (the native drag can't be made mass-lighter; this counters gravity instead). 0 = vanilla weight, 1 = weightless while held (never > gravity, so it won't float away). Only applies while you're dragging; released/heaved bodies fall normally."); FallSceneAtLanding = cfg.Bind("Fall", "FallSceneAtLanding", true, "After a fall kill (#75/#83), re-anchor the crime scene to where the corpse comes to REST, so a fall down a deep shaft or off a rooftop reads at the landing instead of the mid-fall kill point. (The kill itself ALWAYS fires the instant a lethal fall is confirmed — a dead body is immune to the game's ragdoll-recovery teleport that otherwise makes a still-living thrown body vanish to a random spot.) Off = leave the scene at the kill point."); FallAntiSnagEnabled = cfg.Bind("Fall", "FallAntiSnagEnabled", true, "#J: a body heaved out a window sometimes snags on the building's outer wall mid-fall and hangs there instead of dropping to the street. With this on, a body that stalls in mid-air while falling (confirmed by a downward probe finding no ground beneath it) gets a short downward shove to knock it loose so it keeps falling. Collision is NEVER disabled (the body always lands normally — no risk of it dropping through the world), so the worst case is a harmless no-op. Off = vanilla fall physics."); FallAntiSnagForce = cfg.Bind("Fall", "FallAntiSnagForce", 6f, "#J: downward shove speed (m/s) applied to a mid-air-snagged falling body to dislodge it. Higher = a firmer knock. Clamped to a small floor."); HomeVacateEnabled = cfg.Bind("Cleanup", "HomeVacateEnabled", true, "#83 crime-scene coherence: when a target is killed AWAY from home and their case resolves, the game only cleans the death location — their apartment is left frozen as if they still live there. With this on, the Syndicate quietly vacates the victim's home a while later (HomeVacateDelayHours) exactly as the base game does for an at-home death: their furniture is removed and the address is cleared, but only once you're not there to see it and no living resident remains. Off = leave the home untouched (vanilla behaviour for away kills)."); HomeVacateDelayHours = cfg.Bind("Cleanup", "HomeVacateDelayHours", 24, "In-game hours after an away-from-home kill's case resolves before the victim's empty home is vacated (mirrors the base-game crime-scene cleanup delay). Only fires while you're elsewhere."); KODurationMultiplier = cfg.Bind("Combat", "KODurationMultiplier", 3f, "Multiplies how long a knocked-out NPC stays down, so you have time to drag + throw them (the base game's KO is short). Vanilla base is ~1 in-game hour, so 3 = ~3 in-game hours. Only affects ROLLED knockouts (a normal non-lethal takedown); the Syndicate's own timed KOs — poison holds, witness pins — are left exactly as set, and the PLAYER's own KO is never lengthened. 1 = vanilla. Higher = longer."); BluntKOMultiplier = cfg.Bind("Combat", "BluntKOMultiplier", 1.6f, "#H: scales the per-hit damage of BLUNT weapons (truncheon, bat, etc.) when YOU swing them, so a knockout takes FEWER hits — blunt force stuns. Only affects the player's own attacks; NPC-carried blunt weapons are unchanged. 1 = vanilla. Higher = fewer hits to KO."); BladeKOMultiplier = cfg.Bind("Combat", "BladeKOMultiplier", 0.6f, "#H: scales the per-hit damage of BLADED weapons (knife, katana, sword, etc.) when YOU swing them, so a NON-LETHAL knockout takes MORE hits — blades cut, they don't stun (a lethal cut still kills as before, this only changes the KO ramp). Only affects the player's own attacks. 1 = vanilla. Lower = more hits to KO."); Level1Rep = cfg.Bind("Progression", "Level1Rep", 20, "Underworld rep needed to reach Syndicate Level 1 (first earned milestone; you start at Level 0)."); Level2Rep = cfg.Bind("Progression", "Level2Rep", 50, "Underworld rep needed to reach Syndicate Level 2. Also the contract-difficulty Tier-2 boundary."); Level3Rep = cfg.Bind("Progression", "Level3Rep", 100, "Underworld rep needed to reach Syndicate Level 3 (top). Also the contract-difficulty Tier-3 boundary."); Level1Reward = cfg.Bind("Progression", "Level1Reward", 500, "Credits paid out the first time you reach Level 1."); Level2Reward = cfg.Bind("Progression", "Level2Reward", 1500, "Credits paid out the first time you reach Level 2. (Later also delivers the gloves sync disk — pending.)"); Level3Reward = cfg.Bind("Progression", "Level3Reward", 4000, "Credits paid out the first time you reach Level 3. (Later also unlocks the Cruncher app — pending.)"); SocialCreditPerToken = cfg.Bind("SocialCredit", "SocialCreditPerToken", 350, "Native social credit gained per standing purchase (1 hit token + money). Native level thresholds: L2=350, L3=750, L4=1250, L5=2000, L6/echelon=3200, L8/Normal-cap=6000. Default 350 = a hit meaningfully advances your standing."); SocialCreditPurchaseMoneyCost = cfg.Bind("SocialCredit", "SocialCreditPurchaseMoneyCost", 500, "Credits charged alongside the hit token for each standing purchase (bribe/laundering flavor). Modest by design — the hit token is the real cost."); SuppliesEnabled = cfg.Bind("Supplies", "Enabled", true, "Enable the Syndicate Supply app on your home Cruncher — buy gear (weapons, tools, meds, the Second Skin disk) at a discount and have it dropped at your door in a courier case. When off, no icon, no deliveries."); SuppliesDiscountPercent = cfg.Bind("Supplies", "DiscountPercent", 20, "Syndicate discount off an item's street value (its preset max value), as a percent. 20 = you pay 80% of the vanilla price. Clamped 0-90."); SuppliesDeliveryHours = cfg.Bind("Supplies", "DeliveryHours", 1, "In-game hours from checkout to the courier's knock at your door. Clamped to at least 0 (0 = essentially immediate on the next tick). Shared by the gear and groceries apps."); GroceriesEnabled = cfg.Bind("Supplies", "GroceriesEnabled", true, "Enable the bonus Syndicate Groceries app on your home Cruncher — buy food/drink delivered in a courier case, same as gear. When off, no groceries icon."); GroceriesMarkupPercent = cfg.Bind("Supplies", "GroceriesMarkupPercent", 10, "Delivery markup added to a grocery item's shop price, as a percent (simulates store delivery fees). Default 10 = you pay 110% of the item's value. Clamped 0-500."); GearPriceMultiplier = cfg.Bind("Supplies", "GearPriceMultiplier", 3f, "GLOBAL price multiplier on the GEAR bucket — everything that isn't a firearm or ammo (blades, blunt, poison, tools, consumables, the custom sync disks). Applied to the base game item value at load, so EVERY vendor charges more, not just the Syndicate shop (which then still takes DiscountPercent off). See GunPriceMultiplier / AmmoPriceMultiplier for those buckets. 1.0 = vanilla. Groceries (incl. medical) are unaffected. Clamped 0.1-100."); AmmoPriceMultiplier = cfg.Bind("Supplies", "AmmoPriceMultiplier", 3f, "GLOBAL price multiplier on AMMUNITION (pistol/rifle/shotgun rounds). Same global mechanism as GearPriceMultiplier, scoped to ammo. 1.0 = vanilla. Clamped 0.1-100."); GunPriceMultiplier = cfg.Bind("Supplies", "GunPriceMultiplier", 7f, "GLOBAL price multiplier on FIREARMS (sidearms + long guns). Same global mechanism as GearPriceMultiplier, scoped to guns — guns are the premium tier. 1.0 = vanilla. Clamped 0.1-100."); FirearmsEnabled = cfg.Bind("Firearms", "Enabled", true, "Enable player weapon-firing: aim a held gun and shoot (left-click, or the fallback FireKey). Off = guns behave like vanilla (a melee club at most)."); FirearmsHeadshotLethal = cfg.Bind("Firearms", "HeadshotLethal", true, "A headshot with ANY gun kills outright (the precise-shot / silenced-pistol payoff). Off = headshots do normal damage like body shots."); FirearmsHeadshotRadius = cfg.Bind("Firearms", "HeadshotRadius", 0.35f, "How close (metres) a bullet's impact must land to the head anchor to count as a headshot. Raise if headshots aren't registering, lower if body shots are wrongly counting as headshots."); FirearmsHeadshotDebug = cfg.Bind("Firearms", "HeadshotDebug", false, "Log a diagnostic line for each PELLET that hits a citizen (collider name, distance to the head anchor, headshot result) so headshot detection can be calibrated. Fires per-pellet per-shot, so leave OFF in normal play (heavy console logging can aggravate the Windows-console freeze) — turn on only when tuning headshots."); FirearmsOneShotWeapons = cfg.Bind("Firearms", "OneShotWeapons", "Shotgun,SniperRifle", "Comma-separated PascalCase gun preset names whose BODY shot kills outright. Others rely on the two-hit rule (a shot KOs; a second shot on the KO'd target executes) — same as melee. Blank = no gun one-shots on a body hit."); FirearmsAccuracy = cfg.Bind("Firearms", "Accuracy", 1f, "0-1 aim precision fed to the game's Shoot(). 1.0 = the bullet goes exactly where the crosshair points (and makes lethality detection exact). Below 1.0 adds spread to the DAMAGE ray only; lethality still follows the crosshair."); FirearmsMinCooldownSeconds = cfg.Bind("Firearms", "MinFireCooldownSeconds", 0.4f, "Floor (real seconds) under the gun's native per-weapon fire cadence, so nothing fires faster than this. Raise to slow all guns down."); FirearmsConsumeAmmo = cfg.Bind("Firearms", "ConsumeAmmo", true, "Require and consume one matching ammo item per shot (the gun's own ammunition list decides the match). Off = unlimited free firing (debug/sandbox)."); FirearmsSpawnCasings = cfg.Bind("Firearms", "SpawnCasings", true, "Leave a spent shell casing at the scene per shot (revolvers/no-eject guns leave none). If you're NOT wearing gloves, the casing carries YOUR fingerprint — feeding the forensics/ID system. Off = no casing, no print trail."); FirearmsFireKey = cfg.Bind("Firearms", "FireKey", (KeyCode)0, "Optional ALTERNATE fire key. Left-click already fires a held gun (no melee swing); set a key here only if you also want a second bind. None = left-click only."); FirearmsMeleeKey = cfg.Bind("Firearms", "MeleeKey", (KeyCode)0, "Optional key to pistol-whip (melee swing) with a held firearm — left-click now fires instead of swinging, so the melee is moved here. None = no gun-melee."); FirearmsRecoil = cfg.Bind("Firearms", "Recoil", 15f, "Camera recoil kick applied per shot (a JoltCamera amplitude). 0 = no recoil. The game uses ~6 for a mild jolt and 45-60 for a violent one, so 15 is a firm-but-controllable kick. Raise for heavier recoil."); FirearmsPoseLab = cfg.Bind("Firearms", "PoseLab", false, "DEBUG ONLY: enable the first-person Pose Lab hotkeys for surveying/adjusting how a held item is posed — works on any firearm AND the syringe (see the log for the keymap when one is equipped). Leave OFF in normal play."); FirearmsReloadKey = cfg.Bind("Firearms", "ReloadKey", (KeyCode)114, "Key to reload the held gun (tops the magazine up from ammo boxes in your inventory; takes ReloadSeconds). None = no reload key: a gun becomes UNUSABLE once its starting magazine and any reserve are spent, so keep a key bound (or set ConsumeAmmo=false)."); FirearmsReloadSeconds = cfg.Bind("Firearms", "ReloadSeconds", 2.5f, "Seconds a reload takes. Switching or holstering the gun mid-reload cancels it with no ammo consumed. Clamped to a 0.2s floor."); FirearmsMagazineSizes = cfg.Bind("Firearms", "MagazineSizes", "SemiAutomaticPistol:12,SemiAutomaticPistolSilenced:12,Revolver:6,Shotgun:6,BattleRifle:30,SniperRifle:5", "Per-gun magazine capacity (PascalCase preset name:rounds, comma-separated). Rounds loaded per gun are tracked in the save; an unlisted gun defaults to 8."); FirearmsAmmoBoxSizes = cfg.Bind("Firearms", "AmmoBoxSizes", "21AmmoSmall:12,21AmmoLarge:50,309Ammo:20,BuckshotAmmo:6,HuntingAmmo:6", "Rounds contained in each ammo BOX item (preset name:rounds). A reload consumes whole boxes and banks any excess as loose rounds in that gun-group's reserve. Unlisted box defaults to 12."); FirearmsAmmoHud = cfg.Bind("Firearms", "AmmoHud", true, "Show a small corner readout of magazine/reserve while a gun is drawn (e.g. '7 / 12 · 38 rounds'). Off = no on-screen ammo counter (reload/empty toasts still fire)."); FirearmsAutoFireWeapons = cfg.Bind("Firearms", "AutoFireWeapons", "BattleRifle", "Comma-separated PascalCase gun preset names that fire full-auto while you HOLD left-click. All others are semi (one shot per click). Default = the Faucon (BattleRifle) only."); FirearmsAutoFireInterval = cfg.Bind("Firearms", "AutoFireIntervalSeconds", 0.12f, "Seconds between shots for an auto weapon while the trigger is held (~0.12 = 500 rpm). Overrides the per-weapon cadence for auto guns only. Clamped to a 0.05s floor."); FirearmsAutoRecoilScale = cfg.Bind("Firearms", "AutoRecoilScale", 0.4f, "Multiplier on the per-shot recoil kick for auto weapons (full Recoil per shot at 8 shots/sec would be unplayable). 1.0 = same kick as a semi shot."); FirearmsShotgunPellets = cfg.Bind("Firearms", "ShotgunPellets", 6, "Pellets fired per shotgun shell (uses the weapon's own 'shots' value if higher). Each pellet is an independent damage ray; the first flies straight to the crosshair, the rest spread."); FirearmsShotgunSpread = cfg.Bind("Firearms", "ShotgunSpread", 0.06f, "Shotgun pellet spread in the game's aim-jitter units (~0.06 ≈ a 4-5 degree cone). 0 = no spread (all pellets on the crosshair). Higher = wider pattern, thinner at range."); FirearmsShotgunLethalPellets = cfg.Bind("Firearms", "ShotgunLethalPellets", 3, "How many pellets must strike one citizen for a lethal (one-shot) shotgun hit. Point-blank the whole pattern lands (>= this) and kills; at range the pattern thins and only wounds."); FirearmsShotgunAmmoKey = cfg.Bind("Firearms", "ShotgunAmmoSwitchKey", (KeyCode)98, "Key to switch the shotgun's loaded shell between BUCKSHOT (spreads) and DEER SLUG (a single ball, no spread — a heavy one-shot). The switch is immediate and shows on the ammo HUD; any shells of the other type still chambered are ejected, so reload to fill the new type. None = the shotgun just uses whichever shell you have (buckshot preferred)."); FirearmsDrawnDread = cfg.Bind("Firearms", "DrawnGunDread", true, "Citizens NEAR you while you hold a drawn gun lose nerve (fear) — an ambient proximity effect (not tied to precise aim). Off = a drawn gun is not itself intimidating. Enforcers on duty and armed NPCs resist natively."); FirearmsDrawnNerve = cfg.Bind("Firearms", "DrawnGunNerve", -0.05f, "Nerve drained per ~0.5s from each nearby citizen while your gun is drawn (negative = fear; citizen nerve maxes ~0.5, so -0.05 rattles them within a couple of seconds). Nerve regenerates when you leave, so it's a soft pressure. More negative = faster panic; 0 = off."); FirearmsDrawnRange = cfg.Bind("Firearms", "DrawnGunRange", 8f, "Range (metres) within your current room where citizens feel the drawn-gun dread."); FirearmsGunshotsAlarm = cfg.Bind("Firearms", "GunshotsAlarm", true, "Gunshots alarm citizens who HEAR them — nerve drop + they investigate/flee and remember a gunshot. Off = firing makes noise but no one reacts to hearing it. (The silenced pistol is exempt by default.)"); FirearmsAlarmExemptGuns = cfg.Bind("Firearms", "AlarmExemptGuns", "SemiAutomaticPistolSilenced", "Comma-separated PascalCase gun preset names whose gunshots do NOT alarm hearers (silenced weapons). Their fire sound is left vanilla. Blank = every gun alarms."); FirearmsGunshotSpook = cfg.Bind("Firearms", "GunshotSpook", 0.2f, "Minimum nerve drop applied to a citizen who hears a gunshot (raises the gun sound's spook value if lower). Higher = louder panic from hearing shots."); FirearmsRoomTurnOnHit = cfg.Bind("Firearms", "RoomTurnOnHit", true, "A non-lethal gunshot HIT rouses the victim AND everyone in their room to pursue you (the native Shoot doesn't alert the surroundings, so this is on us). Off = only the wounded victim reacts."); FirearmsRoomTurnRange = cfg.Bind("Firearms", "RoomTurnRange", 10f, "Range (metres) within the victim's room whose occupants turn on you after a non-lethal hit. Only used when RoomTurnOnHit is on."); FirearmsInteractYieldDistance = cfg.Bind("Firearms", "InteractYieldDistance", 2f, "How close (metres) an interactable under the crosshair must be for a trigger-pull to open/use it INSTEAD of firing. The game registers doors/items you're looking at from across a room; this gate means only a door/item within reach eats the shot, so you can fire at a distant door. Raise if the gun still refuses to fire near doors; lower toward the game's ~1.8m interact reach for stricter behaviour."); MaskToggleKey = cfg.Bind("Mask", "ToggleKey", (KeyCode)110, "Key to pull the 'False Face' mask on/off (only works once the mask sync-disk is installed). While worn, witnesses to your kills can only describe a masked figure — a Suspicious scene, not a warrant in your name — but a covered face unnerves civilians near you. None = no toggle key (use the debug button)."); MaskScareEnabled = cfg.Bind("Mask", "ScareCivilians", true, "While the mask is worn, nearby civilians lose nerve (fear) — a proximity effect so masking has a cost, mirroring the drawn-gun dread. Off = the mask is socially invisible."); MaskScareNerve = cfg.Bind("Mask", "ScareNerve", -0.02f, "Nerve drained per ~0.5s from each nearby civilian while the mask is worn (negative = fear; citizen nerve maxes ~0.5, so -0.02 rattles them over ~12s of proximity rather than a few seconds). Nerve regenerates when you leave. More negative = faster panic; 0 = off."); MaskScareRange = cfg.Bind("Mask", "ScareRange", 8f, "Range (metres) within your current room where civilians feel the masked-figure dread."); MaskScareEnforcers = cfg.Bind("Mask", "ScareEnforcers", false, "Whether the worn-mask scare also unnerves ENFORCERS (like a masked suspect should). Default false — mirrors the drawn-gun dread, which exempts enforcers, and avoids provoking unpredictable enforcer AI. On = a masked figure spooks everyone."); MaskedDescriptionHeat = cfg.Bind("Mask", "MaskedDescriptionHeat", 12, "Heat added (once per scene) when a masked witness reports a 'masked figure' — noticeably more than a bare body-discovery (+8) but far below a positive ID (+40). Tunes how much a described-but-unnamed sighting stings."); MaskUnmaskInViewIdentifies = cfg.Bind("Mask", "UnmaskInViewIdentifies", true, "F5: taking the mask OFF while a witness or camera of an ACTIVE case is watching converts their masked-figure account into a positive ID (a witness who saw the masked act can now name you; a camera IDs you outright). With no open case, unmasking is free. Disable to make the mask purely about the moment of the crime."); PoisonEnabled = cfg.Bind("Poison", "Enabled", true, "Enable the poison items: the LOADED SYRINGE (a silent instant kill on any citizen you aim at within reach — conscious or KO'd) and the POISON VIAL (force-feed a KO'd citizen to stage a delayed overdose). Off = both behave like vanilla held items."); SyringeDoses = cfg.Bind("Poison", "SyringeDoses", 3, "How many kills one syringe holds before it's spent (shown like ammo). The item is reusable — a use spends one dose; at 0 it's inert. Clamped to at least 1."); VialDoses = cfg.Bind("Poison", "VialDoses", 1, "Forced overdoses per vial. The vial is SINGLE-USE by design: using it consumes the vial and leaves a spent overdose bottle at the scene as the murder weapon, so this is effectively 1 (no on-screen counter is shown for the vial). Clamped to at least 1."); PoisonRange = cfg.Bind("Poison", "UseRangeMeters", 2f, "Reach (metres) for aiming the syringe/vial at a citizen — roughly arm's length. Clamped to a 0.5m floor."); PoisonPromptOverride = cfg.Bind("Poison", "PromptOverride", true, "#E: when a syringe/vial is aimed at a valid target within reach, swap the on-screen interaction prompt to 'Inject' (syringe) / 'Force-feed' (vial) instead of the vanilla 'Take One'/'Use'. Off = leave the vanilla prompt text."); PoisonCooldownSeconds = cfg.Bind("Poison", "UseCooldownSeconds", 1.2f, "Minimum real seconds between poison uses (stops a mashed click from spending several doses). Floored at 0.05s internally — a lower value would let the two same-frame trigger paths both spend a dose on one click."); SyringeKillDelayGameMinutes = cfg.Bind("Poison", "SyringeKillDelayGameMinutes", 5f, "IN-GAME minutes a CONSCIOUS syringe target stays alive after the jab — a drunk wobble at the jab, then a vomit tell shortly before they collapse dead. Long enough to walk clear, so the needle is a viable PUBLIC execution. They are alive and mobile the whole time (can wander and be seen). Measured on the in-game clock, so it pauses with the game and scales with time-speed. 0 = instant kill. A KO'd target dies instantly regardless."); SyringeStaggerDrunk = cfg.Bind("Poison", "SyringeStaggerDrunk", 0.6f, "How hard a conscious syringe target staggers — the 'drunk' amount applied at the jab (0-1). Higher = a stronger wobble but a higher chance they trip and fall on their own before the collapse. 0 = no stagger."); ForgeDelayMinutes = cfg.Bind("Poison", "ForgeDelayMinutes", 10, "In-GAME minutes between force-feeding a KO'd target with the vial and their overdose death. The target stays down until then. Clamped to at least 1."); FingerprintRemoverCharges = cfg.Bind("Fingerprints", "RemoverCharges", 50, "#F: charges in one FINGERPRINT REMOVER (cleaning spray). A charge is spent ONLY when a wipe actually lifts one of your prints — looking at a clean object costs nothing. Clamped to at least 1."); FingerprintRemoverPreset = cfg.Bind("Fingerprints", "RemoverPreset", "CleaningSpray", "#F: the vanilla item preset the FINGERPRINT REMOVER reuses. Change this only if the Supplies probe shows the cleaning-spray preset resolves under a different PascalCase name."); FingerprintRemoverRange = cfg.Bind("Fingerprints", "WipeRangeMeters", 2f, "#F: how close (metres) you must be to actually WIPE prints off an object with the Fingerprint Remover — roughly arm's length, matching the game's interact reach. The 'YOUR PRINTS ARE ON THIS' cue still shows from across the room; only the wipe itself needs you up close. Floored at 0.5m."); FingerprintNoPrintPresets = cfg.Bind("Fingerprints", "NoPrintPresets", "DoorUnderneathPeek", "Comma-separated interactable PRESET names that never leave your fingerprint — for 'peek / observe' interactions that aren't a real touch (looking UNDER a door = 'DoorUnderneathPeek'). Case-insensitive. Add more names (comma-separated) if you find another observe-style interaction that shouldn't incriminate you."); ChloroformEnabled = cfg.Bind("Sedative", "Enabled", true, "#G: enable the SEDATIVE (Dorma-Dix) stealth takedown — hold it, get BEHIND an unaware target while UNSEEN, and USE to put them out cold WITHOUT a mark on them. A sedated target keeps the 'no signs of violence' forgery bonus and adds no investigation heat; a target you BEAT unconscious instead loses both. Off = the item is inert."); ChloroformPreset = cfg.Bind("Sedative", "Preset", "Sleeping Pills", "#G: the vanilla item preset the SEDATIVE reuses (probe-confirmed 'Sleeping Pills' = Dorma-Dix). Editable without a rebuild if you prefer another item (e.g. ChemicalBottle2)."); ChloroformRange = cfg.Bind("Sedative", "UseRangeMeters", 2f, "#G: reach (metres) to apply the sedative to a citizen — arm's length. Floored at 0.5m."); ChloroformBehindDot = cfg.Bind("Sedative", "BehindDot", -0.25f, "#G: how far BEHIND the target you must be. The dot of the target's facing with the direction to you must be at or below this: -1 = directly behind only, 0 = anywhere in the rear half, positive = even from the side. Lower = stricter."); ChloroformDoses = cfg.Bind("Sedative", "Doses", 3, "#G: how many stealth takedowns one SEDATIVE pack holds before it's spent. A dose is used only on a successful KO. Clamped to at least 1."); SedatePromptOverride = cfg.Bind("Sedative", "PromptOverride", true, "#11: while holding the sedative, when a clean from-behind takedown is actually available (target in reach, behind, unseen, doses left) the interaction prompt reads 'Sedate' instead of the vanilla 'Use'/'Take One'. Off = keep the vanilla prompt."); EnableNoViolenceObjective = cfg.Bind("Contracts", "EnableNoViolenceObjective", true, "#G: allow forge jobs (overdose / fall) to carry an OPTIONAL 'no signs of violence' bonus — paid only if you put the target down cleanly (sedative), not by beating them."); NoViolenceChancePercent = cfg.Bind("Contracts", "NoViolenceChancePercent", 35, "#G: percent chance a forge job (overdose / fall) carries the 'no signs of violence' bonus. 0 = never."); BonusNoViolence = cfg.Bind("ContractEconomy", "BonusNoViolence", 0.3f, "#G: payout fraction added when a forge target is killed with NO signs of violence (a clean sedative KO)."); ForgeViolenceHeat = cfg.Bind("Cameras", "ForgeViolenceHeat", 10, "#G: investigation HEAT added when a FORGED death (overdose / fall) is staged over a BEATEN body — the trauma reads as suspicious to a coroner, so the case is likelier to be investigated rather than ruled an accident. Applies to any forge with violence, whether or not the job carried the no-violence bonus. 0 = no extra heat."); ProtectFiniteNPCs = cfg.Bind("Protection", "ProtectFiniteNPCs", true, "SAFETY: enforcers and landlords are a FINITE, non-replenishing pool — every one killed is gone for the rest of the save (fewer cops; a landlord-less district). On (recommended): they never appear as contract targets, and any lethal action on them only knocks them out. Off: they can be killed (and landlords contracted) again — permanent save damage is on you."); ProtectLastCompanyWorker = cfg.Bind("Protection", "ProtectLastCompanyWorker", true, "The Syndicate won't ORDER a hit that empties a business: a citizen who is the LAST living employee of their company is never offered as a contract target (nobody replaces the dead, so it'd leave the shop permanently unstaffed). They are NOT murder-immune — you can still kill them freelance if you choose; this only keeps them off the contract board. Off: last workers can be contracted too."); DisableConsoleQuickEdit = cfg.Bind("General", "DisableConsoleQuickEdit", true, "Fixes the intermittent 'game freezes until I click the BepInEx console and hit Enter' stutter by turning off the Windows console's QuickEdit mode at startup (a stray click/selection on the console otherwise SUSPENDS the whole game). ON by default. Side effect: you can't mouse-select text in the console — to grab logs for a bug report, use BepInEx/LogOutput.log (it has everything). Set FALSE only if you specifically need console mouse-select and can live with the freeze."); SightCheckIntervalSeconds = cfg.Bind("General", "SightCheckIntervalSeconds", 1.5f, "Seconds between crime-scene perception/report checks. Lower = more responsive, marginally more CPU."); VerboseLogging = cfg.Bind("General", "VerboseLogging", false, "Emit the mod's detailed diagnostic logging (stakeout-guard/raid mechanics, probes). Off keeps the console to gameplay-narration lines only. Turn on when reporting a bug."); MessageGapSeconds = cfg.Bind("General", "MessageGapSeconds", 4f, "Minimum seconds between consecutive on-screen Syndicate toast messages, so a burst (e.g. a home raid seizing your weapon AND catching your cruncher logged in) reads as a paced sequence instead of overlapping. Lower = snappier but riskier overlap."); DebugEnabled = cfg.Bind("Debug", "Enabled", false, "Developer/debug mode. Leave OFF for normal play. OFF (the default): the F6 debug HUD and all its buttons are disabled, the F8 print-inspector and the frame input-freeze diagnostic are off, and citizen NAMES and home ADDRESSES are kept out of the BepInEx log — each is written as its numeric id instead (e.g. 'victim #4471'), so the console can't be used as an investigation cheat-sheet while staying traceable for a bug report. ON: restores the F6 debug HUD and prints full un-redacted names/addresses to the log. Either way, on-screen text (toasts, v-mail, the newspaper, the case board) always shows real names — this only affects the debug tooling and what goes to the log file."); Plugin.Logger.LogInfo((object)"Syndicate config bound (BepInEx/config/Kropath.TheSyndicate.cfg)."); } } internal static class Redact { internal static bool Reveal => SyndicateConfig.DebugEnabled?.Value ?? false; internal static string Name(string name, int id) { if (!Reveal) { return "#" + id; } return Show(name); } internal static string Name(string name, long id) { if (!Reveal) { return "#" + id; } return Show(name); } internal static string Loc(string locName, long key) { if (!Reveal) { return "loc#" + key; } return Show(locName); } internal static string Place(string locName) { if (!Reveal) { return "a location"; } return Show(locName); } internal static string Person(string name) { if (!Reveal) { return "the target"; } return Show(name); } internal static string Actor(Human h) { if (Reveal) { try { return ((Object)(object)h != (Object)null) ? Show(h.GetCitizenName()) : "?"; } catch { return "?"; } } try { return ((Object)(object)h != (Object)null) ? ("#" + h.humanID) : "#?"; } catch { return "#?"; } } private static string Show(string s) { if (!string.IsNullOrEmpty(s)) { return s; } return "?"; } } } namespace TheSyndicate.Tools { internal static class FingerprintRemoverController { internal const string DisplayName = "Fingerprint Remover"; private static float _nextUse; private static long _lastWipeKey; internal static string Preset => SyndicateConfig.FingerprintRemoverPreset?.Value ?? "CleaningSpray"; internal static void RegisterName() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown try { Lib.DdsStrings.AddOrUpdate("evidence.names", (Preset ?? "CleaningSpray").ToLowerInvariant(), "Fingerprint Remover"); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Cleaner] name registration failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static bool IsHolding(out Interactable held) { held = null; try { Interactable equippedInteractableCached = KillSwitchPatch.GetEquippedInteractableCached(); if (equippedInteractableCached != null && (SoCustomComparison)(object)equippedInteractableCached.preset != (SoCustomComparison)null && ((Object)equippedInteractableCached.preset).name == Preset) { held = equippedInteractableCached; return true; } } catch { } return false; } internal static bool IsHolding() { Interactable held; return IsHolding(out held); } internal static bool WasJustWiped(long key) { if (key != 0L && key == _lastWipeKey) { return Time.time < _nextUse; } return false; } internal static void Use() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) try { if (!IsHolding()) { return; } InteractionController instance = InteractionController.Instance; if ((Object)(object)instance == (Object)null) { return; } float num = Mathf.Max(0.5f, SyndicateConfig.FingerprintRemoverRange?.Value ?? 2f); RaycastHit playerCurrentRaycastHit = instance.playerCurrentRaycastHit; if (!(((RaycastHit)(ref playerCurrentRaycastHit)).distance > num)) { Interactable val = (((Object)(object)instance.currentLookingAtInteractable != (Object)null) ? instance.currentLookingAtInteractable.interactable : null); if (val != null) { TryWipe(val); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Cleaner] spray use failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } } internal static bool TryWipe(Interactable target) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown try { if (!IsHolding(out var held) || target == null) { return false; } long num = PrintKeys.For(target); if (num != 0L && num == _lastWipeKey && Time.time < _nextUse) { return true; } int playerId = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).humanID : (-1)); bool flag = false; try { flag = PlayerInteractionPrintPatch.DfHasPlayerPrint(target, playerId) || (num != 0L && PlayerEvidence.HasPrint(num)); } catch { } if (!flag) { return false; } _nextUse = Time.time + 0.4f; _lastWipeKey = num; if (PrintRemoverCharges.Get(held) <= 0) { Lib.GameMessage.Broadcast("The can's empty.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); return true; } PrintCleaner.WipePrints(target); PrintRemoverCharges.Spend(held); Lib.GameMessage.Broadcast("Prints wiped.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); return true; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Cleaner] spray wipe failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); return true; } } } internal static class InputFreezeDiag { private static bool _stuck; private static float _stuckSince; private static float _lastLog; internal static void Tick() { //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown try { SessionData instance = SessionData.Instance; if ((Object)(object)instance == (Object)null || !instance.play) { Recover("left play"); return; } Player instance2 = Player.Instance; if ((Object)(object)instance2 == (Object)null || ((Actor)instance2).isDead) { Recover("no player"); return; } if (instance2.computerInteractable != null) { Recover("at computer"); return; } PopupMessageController instance3 = PopupMessageController.Instance; if ((Object)(object)instance3 != (Object)null && (instance3.active || instance3.appearProgress > 0f)) { Recover("popup open"); return; } InputController instance4 = InputController.Instance; InteractionController instance5 = InteractionController.Instance; bool flag = (Object)(object)instance4 == (Object)null || instance4.enableInput; float num = (((Object)(object)instance5 != (Object)null) ? instance5.inputCooldown : 0f); bool flag2 = (Object)(object)instance4 != (Object)null && instance4.mouseInputMode; if (flag && !(num > 0f)) { Recover("gate open"); return; } if (!_stuck) { _stuck = true; _stuckSince = Time.unscaledTime; _lastLog = -999f; } float num2 = Time.unscaledTime - _stuckSince; if (num2 >= 0.5f && Time.unscaledTime - _lastLog >= 1f) { _lastLog = Time.unscaledTime; string text = ((!flag) ? "InputController.enableInput=FALSE" : $"InteractionController.inputCooldown={num:F2} (native reset is ~0.1s — stuck)"); ManualLogSource logger = Plugin.Logger; bool flag3 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(204, 5, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[InputDiag] BUG2: non-movement input GATED "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2, "F1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s in live gameplay — CAUSE: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(enableInput="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", inputCooldown="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", mouseInputMode="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Right-click should recover. Whatever you did in the ~2s before this is the trigger."); } logger.LogWarning(val); } } catch { } } private static void Recover(string reason) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (!_stuck) { return; } float num = Time.unscaledTime - _stuckSince; _stuck = false; if (num >= 0.5f) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(45, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[InputDiag] BUG2: input recovered after "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num, "F1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogWarning(val); } } } internal static class MessageQueue { private sealed class Item { public int Group; public int Seq; public float EligibleAt; public string Msg; } private static readonly List _q = new List(); private static float _lastShownAt = -999f; private static int _nextGroup = 1; private static float Gap => SyndicateConfig.MessageGapSeconds?.Value ?? 4f; public static void Enqueue(string msg, float delaySeconds = 0f) { if (string.IsNullOrEmpty(msg)) { return; } try { _q.Add(new Item { Group = _nextGroup++, Seq = 0, EligibleAt = Time.time + Math.Max(0f, delaySeconds), Msg = msg }); } catch { try { Lib.GameMessage.Broadcast(msg, (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } } public static void EnqueueGroup(IEnumerable lines, float notBeforeSeconds = 0f) { if (lines == null) { return; } try { int num = _nextGroup++; float eligibleAt = Time.time + Math.Max(0f, notBeforeSeconds); int num2 = 0; foreach (string line in lines) { if (!string.IsNullOrEmpty(line)) { _q.Add(new Item { Group = num, Seq = num2++, EligibleAt = eligibleAt, Msg = line }); } } } catch { } } public static void EnqueueGroup(params string[] lines) { EnqueueGroup(lines, 0f); } public static void Tick() { if (_q.Count == 0) { return; } try { float time = Time.time; if (time - _lastShownAt < Gap) { return; } int num = -1; for (int i = 0; i < _q.Count; i++) { if (!(_q[i].EligibleAt > time) && (num < 0 || _q[i].Group < num)) { num = _q[i].Group; } } if (num < 0) { return; } int num2 = -1; for (int j = 0; j < _q.Count; j++) { if (_q[j].Group == num && !(_q[j].EligibleAt > time) && (num2 < 0 || _q[j].Seq < _q[num2].Seq)) { num2 = j; } } if (num2 < 0) { return; } string msg = _q[num2].Msg; _q.RemoveAt(num2); _lastShownAt = time; try { Lib.GameMessage.Broadcast(msg, (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } catch { } } } internal static class PrintCleaner { public static void CleanLookedAt() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown try { InteractionController instance = InteractionController.Instance; InteractableController val = (((Object)(object)instance != (Object)null) ? instance.currentLookingAtInteractable : null); Interactable val2 = (((Object)(object)val != (Object)null) ? val.interactable : null); if (val2 == null) { Plugin.Logger.LogInfo((object)"[Cleaner] Not looking at any interactable object."); } else { WipePrints(val2); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Cleaner] CleanLookedAt failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } logger.LogError(val3); } } public static void WipePrints(Interactable it) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown if (it == null) { return; } string text = "?"; try { if ((SoCustomComparison)(object)it.preset != (SoCustomComparison)null) { text = ((Object)it.preset).name; } } catch { } int num = ((it.df != null) ? it.df.Count : 0); int num2 = 0; bool flag = default(bool); try { int num3 = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).humanID : (-1)); if (it.df != null && num3 >= 0) { for (int num4 = it.df.Count - 1; num4 >= 0; num4--) { DynamicFingerprint val = it.df[num4]; if (val != null && val.id == num3) { it.RemoveDynamicPrint(val); num2++; } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Cleaner] wipe error on '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } PlayerEvidence.RemovePrint(PrintKeys.For(it)); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(54, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Cleaner] Wiped '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': removed "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" of your print(s) (df "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("->"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(it.df?.Count ?? 0); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")."); } logger2.LogInfo(val3); } } public class PrintCueOverlay : MonoBehaviour { private const int ListMax = 10; private readonly List _listCache = new List(); private int _listTotal; private float _listCacheAt = -999f; private int _listRoomId = int.MinValue; public PrintCueOverlay(IntPtr ptr) : base(ptr) { } private void OnGUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) try { if ((int)Event.current.type != 7) { return; } FirstPersonItemController instance = FirstPersonItemController.Instance; bool flag = (Object)(object)instance != (Object)null && (Object)(object)instance.activeScanner != (Object)null; bool flag2 = CrimeSceneManager.PlayerInsideAnyScene(); Interactable held; bool flag3 = FingerprintRemoverController.IsHolding(out held); if (!flag && !flag2 && !flag3) { return; } NewRoom val = (((Object)(object)Player.Instance != (Object)null) ? ((Actor)Player.Instance).currentRoom : null); if ((Object)(object)val != (Object)null && RoomForensics.IsPublicPrintSpace(val) && (flag || flag3)) { SynUI.Label(new Rect(((float)Screen.width - 520f) / 2f, (float)Screen.height * 0.12f, 520f, 26f), "TOO MANY PRINTS HERE — YOURS WON'T MATTER", SynUI.Good, 14, (FontStyle)1, (TextAnchor)4); } else if ((Object)(object)val != (Object)null && flag) { RefreshTaintedList(val); if (_listTotal > 0) { DrawTaintedList(); } } else if ((Object)(object)val != (Object)null && flag2) { RefreshTaintedList(val); int listTotal = _listTotal; if (listTotal > 0) { SynUI.Label(new Rect(((float)Screen.width - 460f) / 2f, (float)Screen.height * 0.12f, 460f, 26f), $"PLAYER PRINTS IN THIS ROOM: {listTotal}", SynUI.Caution, 14, (FontStyle)1, (TextAnchor)4); } } InteractionController instance2 = InteractionController.Instance; InteractableController val2 = (((Object)(object)instance2 != (Object)null) ? instance2.currentLookingAtInteractable : null); Interactable val3 = (((Object)(object)val2 != (Object)null) ? val2.interactable : null); if (val3 != null) { long num = PrintKeys.For(val3); bool flag4 = num != 0L && PlayerEvidence.HasPrint(num); bool flag5 = false; try { int playerId = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).humanID : (-1)); flag5 = PlayerInteractionPrintPatch.DfHasPlayerPrint(val3, playerId); } catch { } if (flag4 || flag5) { Rect r = default(Rect); ((Rect)(ref r))..ctor(((float)Screen.width - 440f) / 2f, (float)Screen.height * 0.58f, 440f, 30f); SynUI.Panel(r, SynUI.WithA(SynUI.C(SynUI.Pal.PanelBg), 0.55f), SynUI.WithA(SynUI.Caution, 0.4f)); string text = (flag3 ? $"YOUR PRINTS ARE ON THIS — [USE] TO WIPE ({PrintRemoverCharges.Get(held)} left)" : "YOUR PRINTS ARE ON THIS"); SynUI.Label(r, text, SynUI.Caution, 15, (FontStyle)1, (TextAnchor)4); SynUI.Icon(new Rect(((Rect)(ref r)).x + 8f, ((Rect)(ref r)).y + 7f, 16f, 16f), (Icon)6, SynUI.Caution); } } } catch { } } private void RefreshTaintedList(NewRoom room) { if (room.roomID == _listRoomId && Time.unscaledTime - _listCacheAt < 0.5f) { return; } _listCache.Clear(); _listTotal = 0; int num = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).humanID : (-1)); if (num >= 0) { HashSet seen = new HashSet(); HashSet worldObjects = room.worldObjects; if (worldObjects != null) { Enumerator enumerator = worldObjects.GetEnumerator(); while (enumerator.MoveNext()) { Interactable current = enumerator.Current; Consider(current, num, seen); } } List furniture = room.furniture; if (furniture != null) { Enumerator enumerator2 = furniture.GetEnumerator(); while (enumerator2.MoveNext()) { FurnitureClusterLocation current2 = enumerator2.Current; if (current2 == null) { continue; } List clusterList = current2.clusterList; if (clusterList != null) { Enumerator enumerator3 = clusterList.GetEnumerator(); while (enumerator3.MoveNext()) { FurnitureLocation current3 = enumerator3.Current; ConsiderFurniture(current3, num, seen); } } } } List individualFurniture = room.individualFurniture; if (individualFurniture != null) { Enumerator enumerator3 = individualFurniture.GetEnumerator(); while (enumerator3.MoveNext()) { FurnitureLocation current4 = enumerator3.Current; ConsiderFurniture(current4, num, seen); } } List lightswitchInteractables = room.lightswitchInteractables; if (lightswitchInteractables != null) { Enumerator enumerator4 = lightswitchInteractables.GetEnumerator(); while (enumerator4.MoveNext()) { Interactable current5 = enumerator4.Current; Consider(current5, num, seen); } } List entrances = room.entrances; if (entrances != null) { Enumerator enumerator5 = entrances.GetEnumerator(); while (enumerator5.MoveNext()) { NodeAccess current6 = enumerator5.Current; if (current6 != null) { NewDoor val = null; try { val = current6.door; } catch { } if (!((Object)(object)val == (Object)null)) { Consider(val.doorInteractable, num, seen); Consider(val.handleInteractable, num, seen); } } } } } _listCacheAt = Time.unscaledTime; _listRoomId = room.roomID; } private void ConsiderFurniture(FurnitureLocation fl, int pid, HashSet seen) { if (fl == null) { return; } List integratedInteractables = fl.integratedInteractables; if (integratedInteractables != null) { Enumerator enumerator = integratedInteractables.GetEnumerator(); while (enumerator.MoveNext()) { Interactable current = enumerator.Current; Consider(current, pid, seen); } } List spawnedInteractables = fl.spawnedInteractables; if (spawnedInteractables != null) { Enumerator enumerator = spawnedInteractables.GetEnumerator(); while (enumerator.MoveNext()) { Interactable current2 = enumerator.Current; Consider(current2, pid, seen); } } } private void Consider(Interactable obj, int pid, HashSet seen) { if (obj == null) { return; } long num = 0L; try { num = PrintKeys.For(obj); } catch { } if (num != 0L && !seen.Add(num)) { return; } bool flag = false; try { flag = PlayerInteractionPrintPatch.DfHasPlayerPrint(obj, pid) || (num != 0L && PlayerEvidence.HasPrint(num)); } catch { } if (flag) { _listTotal++; if (_listCache.Count < 10) { _listCache.Add(Prettify(PlayerInteractionPrintPatch.ObjectLabel(obj))); } } } private void DrawTaintedList() { //IL_005f: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) int count = _listCache.Count; if (count != 0) { bool flag = _listTotal > count; float num = 22f + (float)count * 17f + (flag ? 15f : 0f) + 8f; Rect r = default(Rect); ((Rect)(ref r))..ctor(24f, ((float)Screen.height - num) / 2f, 360f, num); SynUI.Panel(r, SynUI.WithA(SynUI.C(SynUI.Pal.PanelBg), 0.55f), SynUI.WithA(SynUI.Caution, 0.4f)); float num2 = ((Rect)(ref r)).x + 12f; float num3 = 336f; SynUI.Label(new Rect(num2, ((Rect)(ref r)).y + 4f, num3, 16f), $"YOUR PRINTS — {_listTotal} OBJECT{((_listTotal == 1) ? "" : "S")} IN THIS ROOM", SynUI.Caution, 12, (FontStyle)1, (TextAnchor)3); float num4 = ((Rect)(ref r)).y + 22f; for (int i = 0; i < count; i++) { SynUI.Label(new Rect(num2 + 6f, num4, num3 - 6f, 17f), "· " + _listCache[i], SynUI.TextPrimary, 12, (FontStyle)0, (TextAnchor)3); num4 += 17f; } if (flag) { SynUI.Label(new Rect(num2 + 6f, num4, num3 - 6f, 14f), $"+{_listTotal - count} more", SynUI.TextDim, 11, (FontStyle)2, (TextAnchor)3); } } } private static string Prettify(string s) { return PlayerInteractionPrintPatch.Prettify(s); } } internal static class PrintInspector { public static void InspectLookedAt() { //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { InteractionController instance = InteractionController.Instance; InteractableController val = (((Object)(object)instance != (Object)null) ? instance.currentLookingAtInteractable : null); Interactable val2 = (((Object)(object)val != (Object)null) ? val.interactable : null); if (val2 == null) { Plugin.Logger.LogInfo((object)"[Inspect] Not looking at any interactable object."); return; } string text = "?"; try { if ((SoCustomComparison)(object)val2.preset != (SoCustomComparison)null) { text = ((Object)val2.preset).name; } } catch { } int num = ((val2.df != null) ? val2.df.Count : 0); int num2 = ((val2.print != null) ? val2.print.Count : 0); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(46, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Inspect] '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' (id "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("): dynamic df="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", static print="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num2); } logger.LogInfo(val3); if (val2.df != null) { Enumerator enumerator = val2.df.GetEnumerator(); while (enumerator.MoveNext()) { DynamicFingerprint current = enumerator.Current; if (current != null) { ManualLogSource logger2 = Plugin.Logger; val3 = new BepInExInfoLogInterpolatedStringHandler(40, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Inspect] df: id="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(current.id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" life="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(current.life); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" created="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(current.created, "F1"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" seed="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Trunc(current.seed)); } logger2.LogInfo(val3); } } } if (val2.print == null) { return; } Enumerator enumerator2 = val2.print.GetEnumerator(); while (enumerator2.MoveNext()) { SavedPrint current2 = enumerator2.Current; if (current2 != null) { ManualLogSource logger3 = Plugin.Logger; val3 = new BepInExInfoLogInterpolatedStringHandler(45, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Inspect] static: interactableID="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(current2.interactableID); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" worldPos="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(current2.worldPos); } logger3.LogInfo(val3); } } } catch (Exception ex) { ManualLogSource logger4 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Inspect] failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex); } logger4.LogError(val4); } } private static string Trunc(string s) { if (string.IsNullOrEmpty(s)) { return "(none)"; } if (s.Length <= 24) { return s; } return s.Substring(0, 24) + "…"; } } internal static class PrintRemoverCharges { internal static int Capacity => Math.Max(1, SyndicateConfig.FingerprintRemoverCharges?.Value ?? 50); internal static int Get(Interactable item) { try { if (item == null) { return 0; } if (SyndicateState.Data.FingerprintRemoverCharges.TryGetValue(item.id, out var value)) { return Math.Max(0, value); } return Capacity; } catch { return 0; } } internal static void Spend(Interactable item) { try { if (item != null) { SyndicateState.Data.FingerprintRemoverCharges[item.id] = Math.Max(0, Get(item) - 1); } } catch { } } } public class SceneWatch : MonoBehaviour { private float _next; public SceneWatch(IntPtr ptr) : base(ptr) { } private void Update() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (Time.deltaTime > 0.5f) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Perf] frame hitch "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Time.deltaTime, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s"); } logger.LogWarning(val); } ConfigEntry debugEnabled = SyndicateConfig.DebugEnabled; if (debugEnabled != null && debugEnabled.Value) { InputFreezeDiag.Tick(); } try { FallForge.Tick(); } catch { } try { PauseLine.PumpPendingEndCall(); } catch { } if (Time.time < _next) { return; } float num = ((SyndicateConfig.SightCheckIntervalSeconds != null) ? SyndicateConfig.SightCheckIntervalSeconds.Value : 1.5f); if (num < 0.2f) { num = 0.2f; } _next = Time.time + num; try { CrimeSceneManager.MonitorScenes(); } catch { } try { HomeVacateQueue.Tick(); } catch { } try { ManhuntController.Tick(); } catch { } try { ProgressionManager.Evaluate(); } catch { } try { OnboardingController.Tick(); } catch { } try { ContractDispatcher.Tick(); } catch { } try { ContractManager.SettlementTick(); } catch { } try { ContractManager.VoidProtectedContracts(); } catch { } try { SupplyDelivery.Tick(); } catch { } try { PoisonScheduler.Tick(); } catch { } try { CrippleController.Tick(); } catch { } try { CrimeSceneManager.CameraHuntTick(); } catch { } try { HeatMeterState.Tick(); } catch { } try { MaskNotoriety.Tick(); } catch { } try { PoisonMailer.Tick(); } catch { } try { ManhuntController.FlushDeferredToasts(); } catch { } try { NewsEngine.Tick(); } catch { } } } public static class HeatMeter { public static Func Source; public static float Fraction01 { get { try { return Mathf.Clamp01((Source != null) ? Source() : 0f); } catch { return 0f; } } } } public class SyndicateHud : MonoBehaviour { private float _nextCompute; private int _level = -1; private string _levelText = "RECRUIT"; private List _scenes; private int _sceneTotal; private const int SceneRowsMax = 4; private float _maskBadgeBottom = 58f; public SyndicateHud(IntPtr ptr) : base(ptr) { } private void OnGUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 try { if ((int)Event.current.type != 7) { return; } ConfigEntry hudClusterEnabled = SyndicateConfig.HudClusterEnabled; if ((hudClusterEnabled != null && !hudClusterEnabled.Value) || !InPlay()) { return; } SyndicateData data = SyndicateState.Data; if (data == null || SyndicateState.IsWorldLoading) { return; } if (Time.unscaledTime >= _nextCompute || _level < 0) { _nextCompute = Time.unscaledTime + 1f; _level = SyndicateState.Level; _levelText = ((_level <= 0) ? "RECRUIT" : $"LEVEL {_level}"); _scenes = CrimeSceneManager.SnapshotForHud(4, out _sceneTotal); } DrawLevelBadge(); ConfigEntry hudSceneTableEnabled = SyndicateConfig.HudSceneTableEnabled; if ((hudSceneTableEnabled == null || hudSceneTableEnabled.Value) && _sceneTotal > 0) { DrawSceneTable(); } if (data.MaskDiskInstalled) { DrawMaskBadge(SyndicateState.MaskActive); ConfigEntry maskNotorietyEnabled = SyndicateConfig.MaskNotorietyEnabled; if (maskNotorietyEnabled == null || maskNotorietyEnabled.Value) { DrawPersonaBar(); } } DrawHeatBar(); } catch { } } private void DrawLevelBadge() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) Rect r = default(Rect); ((Rect)(ref r))..ctor(16f, 12f, 200f, 56f); SynUI.NeonPanel(r); float num = ((Rect)(ref r)).x + 12f; float num2 = 176f; SynUI.Label(new Rect(num, ((Rect)(ref r)).y + 7f, num2, 13f), "THE SYNDICATE", SynUI.Pink, 11, (FontStyle)1, (TextAnchor)3); SynUI.NeonDivider(num, ((Rect)(ref r)).y + 24f, num2); Rect val = default(Rect); ((Rect)(ref val))..ctor(num, ((Rect)(ref r)).y + 30f, num2, 22f); SynUI.Label(val, _levelText, SynUI.TextPrimary, 16, (FontStyle)1, (TextAnchor)3); DrawStarMeter(val); } private void DrawStarMeter(Rect row2) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) float num = 48f; float num2 = ((Rect)(ref row2)).xMax - num; float num3 = ((Rect)(ref row2)).y + (((Rect)(ref row2)).height - 14f) / 2f; Rect r = default(Rect); for (int i = 0; i < 3; i++) { ((Rect)(ref r))..ctor(num2 + (float)i * 17f, num3, 14f, 14f); bool flag = i < _level; Color tint = (flag ? SynUI.Accent : SynUI.WithA(SynUI.TextDim, 0.3f)); if (!SynUI.Icon(r, (Icon)13, tint)) { if (flag) { SynUI.Fill(r, SynUI.Accent); } else { SynUI.Border(r, SynUI.WithA(SynUI.TextDim, 0.35f)); } } } } private void DrawSceneTable() { //IL_0069: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) if (_scenes == null) { return; } int count = _scenes.Count; float num = 28f; float num2 = 224f; bool flag = _sceneTotal > count; float num3 = 24f + (float)count * 15f + (flag ? 14f : 0f) + 6f; Rect r = default(Rect); ((Rect)(ref r))..ctor(16f, 72f, 248f, num3); SynUI.NeonPanel(r); SynUI.Label(new Rect(num, ((Rect)(ref r)).y + 4f, num2, 16f), "CRIME SCENES", SynUI.Pink, 10, (FontStyle)1, (TextAnchor)3); SynUI.Label(new Rect(num, ((Rect)(ref r)).y + 4f, num2, 16f), _sceneTotal.ToString(), SynUI.TextDim, 10, (FontStyle)1, (TextAnchor)5); SynUI.NeonDivider(num, ((Rect)(ref r)).y + 20f, num2); float num4 = ((Rect)(ref r)).y + 24f; for (int i = 0; i < count; i++) { CrimeSceneManager.SceneRow r2 = _scenes[i]; Color val = StatusColor(r2.Status); SynUI.Fill(new Rect(num, num4 + 7.5f - 3f, 6f, 6f), val); SynUI.Label(new Rect(num + 12f, num4, num2 * 0.46f - 12f, 15f), Truncate(r2.Name, 13), SynUI.TextPrimary, 11, (FontStyle)1, (TextAnchor)3); if (r2.Status == CrimeSceneManager.SceneStatus.Undiscovered) { SynUI.Label(new Rect(num + num2 * 0.46f, num4, num2 * 0.54f, 15f), "UNDISCOVERED", val, 9, (FontStyle)1, (TextAnchor)5); } else { SynUI.Label(new Rect(num + num2 * 0.7f, num4, num2 * 0.3f, 15f), StatusLabel(r2), val, 9, (FontStyle)1, (TextAnchor)5); if (r2.PayoutPending) { SynUI.Label(new Rect(num + num2 * 0.46f, num4, num2 * 0.24f - 2f, 15f), "PAY", SynUI.Good, 9, (FontStyle)1, (TextAnchor)5); } } num4 += 15f; } if (flag) { SynUI.Label(new Rect(num, num4, num2, 13f), $"+{_sceneTotal - count} more", SynUI.TextDim, 9, (FontStyle)2, (TextAnchor)3); } } private static Color StatusColor(CrimeSceneManager.SceneStatus s) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return (Color)(s switch { CrimeSceneManager.SceneStatus.Undiscovered => SynUI.C(SynUI.Pal.Info), CrimeSceneManager.SceneStatus.GoingCold => SynUI.Good, _ => SynUI.Caution, }); } private static string StatusLabel(CrimeSceneManager.SceneRow r) { if (r.Status == CrimeSceneManager.SceneStatus.Undiscovered) { return "UNDISCOVERED"; } string text = ((r.HoursLeft >= 0) ? (r.HoursLeft + "h") : "?"); return ((r.Status == CrimeSceneManager.SceneStatus.GoingCold) ? "COLD " : "INV ") + text; } private static string Truncate(string s, int max) { if (string.IsNullOrEmpty(s)) { return "?"; } if (s.Length > max) { return s.Substring(0, max - 1) + "…"; } return s; } private void DrawMaskBadge(bool on) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) float num = (on ? 2f : 1f); float num2 = 56f * num; float num3 = 46f * num; Rect r = default(Rect); ((Rect)(ref r))..ctor((float)Screen.width - 16f - num2, 12f, num2, num3); SynUI.NeonPanel(r); SynUI.MaskGlyph(new Rect(((Rect)(ref r)).x + 10f * num, ((Rect)(ref r)).y + 8f * num, 36f * num, 20f * num), on); SynUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 31f * num, num2, 12f * num), "MASK", on ? SynUI.Accent : SynUI.TextDim, on ? 16 : 8, (FontStyle)1, (TextAnchor)4); _maskBadgeBottom = ((Rect)(ref r)).yMax; } private void DrawPersonaBar() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00f6: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) float value = MaskNotoriety.Value; Rect r = default(Rect); ((Rect)(ref r))..ctor((float)Screen.width - 16f - 120f, _maskBadgeBottom + 4f, 120f, 28f); SynUI.NeonPanel(r); SynUI.Label(new Rect(((Rect)(ref r)).x + 8f, ((Rect)(ref r)).y + 2f, 64f, 12f), "PERSONA", SynUI.Pink, 8, (FontStyle)1, (TextAnchor)3); string text = $"{Mathf.RoundToInt(value * 100f)}%"; SynUI.Label(new Rect(((Rect)(ref r)).xMax - 46f, ((Rect)(ref r)).y + 2f, 42f, 12f), text, (value > 0f) ? SynUI.TextPrimary : SynUI.TextDim, 8, (FontStyle)1, (TextAnchor)5); Rect track = new Rect(((Rect)(ref r)).x + 8f, ((Rect)(ref r)).y + 16f, ((Rect)(ref r)).width - 16f, 8f); Color fill = Color.Lerp(SynUI.C(SynUI.Pal.Info), SynUI.C(SynUI.Pal.Pink), value); SynUI.Bar(track, value, fill); } private void DrawHeatBar() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) SynUI.TopStack(out var heatRect, out var _); SynUI.NeonPanel(heatRect, null, 0.85f, 0.62f); SynUI.Icon(new Rect(((Rect)(ref heatRect)).x + 8f, ((Rect)(ref heatRect)).y + 5f, 16f, 16f), (Icon)11, SynUI.Pink); SynUI.Label(new Rect(((Rect)(ref heatRect)).x + 28f, ((Rect)(ref heatRect)).y, 40f, ((Rect)(ref heatRect)).height), "HEAT", SynUI.Pink, 10, (FontStyle)1, (TextAnchor)3); float fraction = HeatMeter.Fraction01; Rect track = default(Rect); ((Rect)(ref track))..ctor(((Rect)(ref heatRect)).x + 70f, ((Rect)(ref heatRect)).y + 8f, 452f, 10f); Color fill = Color.Lerp(SynUI.C(SynUI.Pal.HeatLow), SynUI.C(SynUI.Pal.HeatHigh), fraction); SynUI.Bar(track, fraction, fill); for (int i = 1; i <= 3; i++) { SynUI.Fill(new Rect(((Rect)(ref track)).x + ((Rect)(ref track)).width * ((float)i * 0.25f), ((Rect)(ref track)).y + 2f, 1f, ((Rect)(ref track)).height - 4f), SynUI.WithA(SynUI.TextDim, 0.25f)); } string text = $"{Mathf.RoundToInt(fraction * 100f)}%"; SynUI.Label(new Rect(((Rect)(ref heatRect)).xMax - 58f + 4f, ((Rect)(ref heatRect)).y, 44f, ((Rect)(ref heatRect)).height), text, (fraction > 0f) ? SynUI.TextPrimary : SynUI.TextDim, 10, (FontStyle)1, (TextAnchor)5); } private static bool InPlay() { try { if ((Object)(object)SessionData.Instance == (Object)null || !SessionData.Instance.play) { return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || ((Actor)instance).isDead) { return false; } if (instance.computerInteractable != null) { return false; } return true; } catch { return false; } } } public static class SynUI { public enum Pal { Accent, Pink, Warn, Caution, Good, Info, TextPrimary, TextDim, PanelBg, PanelBorder, HeatLow, HeatHigh } private struct Slot { public Func Pick; public Color Fallback; public bool WantChroma; } private static readonly Slot[] Table = new Slot[12] { new Slot { Pick = null, Fallback = Hex(15073279u), WantChroma = false }, new Slot { Pick = null, Fallback = Hex(4281177599u), WantChroma = false }, new Slot { Pick = (InterfaceControls ic) => ic.messageRed, Fallback = Hex(4282537983u), WantChroma = true }, new Slot { Pick = (InterfaceControls ic) => ic.messageYellow, Fallback = Hex(4290653951u), WantChroma = true }, new Slot { Pick = (InterfaceControls ic) => ic.messageGreen, Fallback = Hex(905940991u), WantChroma = true }, new Slot { Pick = (InterfaceControls ic) => ic.messageBlue, Fallback = Hex(1338245119u), WantChroma = true }, new Slot { Pick = (InterfaceControls ic) => ic.neutralColour, Fallback = Hex(3908370431u), WantChroma = false }, new Slot { Pick = (InterfaceControls ic) => ic.nonSelectionColour, Fallback = Hex(2410069247u), WantChroma = false }, new Slot { Pick = null, Fallback = Hex(168959175u), WantChroma = false }, new Slot { Pick = null, Fallback = Hex(15073113u), WantChroma = false }, new Slot { Pick = (InterfaceControls ic) => ic.trespassingEscalationZero, Fallback = Hex(4290653951u), WantChroma = true }, new Slot { Pick = (InterfaceControls ic) => ic.trespassingEscalationOne, Fallback = Hex(4282537983u), WantChroma = true } }; private static readonly Color[] _cache = (Color[])(object)new Color[12]; private static readonly string[] _hex = new string[12]; private static float _cacheAt = -999f; private static Texture2D _white; private static GUIStyle _lbl; public const float CenterW = 580f; public const float HeatH = 26f; public const float StackGap = 4f; private static Texture2D _hatch; private static readonly Dictionary _iconCache = new Dictionary(); public static Color Accent => C(Pal.Accent); public static Color Pink => C(Pal.Pink); public static Color Warn => C(Pal.Warn); public static Color Caution => C(Pal.Caution); public static Color Good => C(Pal.Good); public static Color TextPrimary => C(Pal.TextPrimary); public static Color TextDim => C(Pal.TextDim); public static Texture2D White { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_white == (Object)null) { _white = new Texture2D(1, 1, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; _white.SetPixel(0, 0, Color.white); _white.Apply(false, true); } return _white; } } private static GUIStyle Lbl { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (_lbl == null) { _lbl = new GUIStyle(GUI.skin.label) { richText = true, wordWrap = false }; } return _lbl; } } private static Texture2D Hatch { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_hatch == (Object)null) { _hatch = new Texture2D(8, 8, (TextureFormat)4, false) { hideFlags = (HideFlags)61, wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)0 }; Color val = default(Color); ((Color)(ref val))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { _hatch.SetPixel(j, i, ((j + i) % 4 == 0) ? Color.white : val); } } _hatch.Apply(false, true); } return _hatch; } } public static Color C(Pal p) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) Refresh(); return _cache[(int)p]; } public static string HexRGB(Pal p) { Refresh(); return _hex[(int)p]; } private static void Refresh() { //IL_007d: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime - _cacheAt < 1f) { return; } _cacheAt = Time.unscaledTime; InterfaceControls val = null; try { val = InterfaceControls.Instance; } catch { } for (int i = 0; i < Table.Length; i++) { Slot slot = Table[i]; Color val2 = slot.Fallback; if ((Object)(object)val != (Object)null && slot.Pick != null) { try { Color val3 = slot.Pick(val); if (Usable(val3, slot.WantChroma)) { val2 = val3; } } catch { } } _cache[i] = val2; _hex[i] = ColorUtility.ToHtmlStringRGB(val2); } _cache[9] = WithA(_cache[1], 0.5f); _hex[9] = _hex[1]; } private static bool Usable(Color c, bool wantChroma) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (c.a < 0.1f) { return false; } float num = Mathf.Max(c.r, Mathf.Max(c.g, c.b)); float num2 = Mathf.Min(c.r, Mathf.Min(c.g, c.b)); if (num < 0.12f) { return false; } if (wantChroma && num - num2 < 0.08f) { return false; } return true; } private static Color Hex(uint rgba) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) return new Color((float)((rgba >> 24) & 0xFF) / 255f, (float)((rgba >> 16) & 0xFF) / 255f, (float)((rgba >> 8) & 0xFF) / 255f, (float)(rgba & 0xFF) / 255f); } public static Color WithA(Color c, float a) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return new Color(c.r, c.g, c.b, a); } public static void Fill(Rect r, Color c) { //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_000b: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = c; GUI.DrawTexture(r, (Texture)(object)White); GUI.color = color; } public static void Border(Rect r, Color c) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 1f), c); Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - 1f, ((Rect)(ref r)).width, 1f), c); Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), c); Fill(new Rect(((Rect)(ref r)).xMax - 1f, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), c); } public static void Panel(Rect r, Color? bg = null, Color? border = null, float edge = 0f, Color? edgeColor = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Fill(r, (Color)(((??)bg) ?? C(Pal.PanelBg))); Border(r, (Color)(((??)border) ?? C(Pal.PanelBorder))); if (edge > 0f) { Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, edge, ((Rect)(ref r)).height), (Color)(((??)edgeColor) ?? C(Pal.Accent))); } } public static void Label(Rect r, string text, Color color, int size = 13, FontStyle fs = (FontStyle)1, TextAnchor anchor = (TextAnchor)3, bool shadow = true) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) GUIStyle lbl = Lbl; lbl.fontSize = size; lbl.fontStyle = fs; lbl.alignment = anchor; Color color2 = GUI.color; GUI.color = Color.white; if (shadow) { float num = ((size >= 18) ? 2f : 1f); lbl.normal.textColor = new Color(0f, 0f, 0f, 0.9f); GUI.Label(new Rect(((Rect)(ref r)).x + num, ((Rect)(ref r)).y + num, ((Rect)(ref r)).width, ((Rect)(ref r)).height), text, lbl); } lbl.normal.textColor = color; GUI.Label(r, text, lbl); GUI.color = color2; } public static void Bar(Rect track, float frac01, Color fill, string label = null, string value = null) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(frac01); Fill(track, C(Pal.PanelBg)); Fill(track, WithA(fill, 0.1f)); if (num > 0f) { Fill(new Rect(((Rect)(ref track)).x, ((Rect)(ref track)).y, ((Rect)(ref track)).width * num, ((Rect)(ref track)).height), fill); } Border(track, WithA(fill, 0.35f)); if (!string.IsNullOrEmpty(label)) { Label(new Rect(((Rect)(ref track)).x + 4f, ((Rect)(ref track)).y, ((Rect)(ref track)).width - 8f, ((Rect)(ref track)).height), label, C(Pal.TextDim), 9, (FontStyle)1, (TextAnchor)3); } if (!string.IsNullOrEmpty(value)) { Label(new Rect(((Rect)(ref track)).x + 4f, ((Rect)(ref track)).y, ((Rect)(ref track)).width - 8f, ((Rect)(ref track)).height), value, C(Pal.TextPrimary), 9, (FontStyle)1, (TextAnchor)5); } } public static void Chip(Rect r, string text, Color accent, bool on) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (on) { Fill(r, WithA(accent, 0.2f)); Border(r, accent); Label(r, text, accent, 11, (FontStyle)1, (TextAnchor)4); } else { Fill(r, WithA(C(Pal.PanelBg), 0.85f)); Border(r, WithA(C(Pal.TextDim), 0.35f)); Label(r, text, C(Pal.TextDim), 11, (FontStyle)1, (TextAnchor)4); } } public static void TopStack(out Rect heatRect, out float warrantPanelY) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) float num = ((float)Screen.width - 580f) / 2f; float num2 = Mathf.Max(8f, (float)Screen.height * 0.04f - 36f); heatRect = new Rect(num, num2, 580f, 26f); warrantPanelY = num2 + 26f + 4f; } public static void NeonPanel(Rect r, Color? frame = null, float frameA = 0.85f, float bgA = 0.72f, bool hatch = true, bool glow = true) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Color c = (Color)(((??)frame) ?? C(Pal.Pink)); Fill(r, WithA(C(Pal.PanelBg), bgA)); if (hatch) { Color color = GUI.color; try { GUI.color = WithA(C(Pal.Pink), 0.05f); GUI.DrawTextureWithTexCoords(r, (Texture)(object)Hatch, new Rect(0f, 0f, ((Rect)(ref r)).width / 8f, ((Rect)(ref r)).height / 8f)); } catch { } finally { GUI.color = color; } } if (glow) { Border(new Rect(((Rect)(ref r)).x - 1f, ((Rect)(ref r)).y - 1f, ((Rect)(ref r)).width + 2f, ((Rect)(ref r)).height + 2f), WithA(c, 0.18f)); } Fill(new Rect(((Rect)(ref r)).x + 3f, ((Rect)(ref r)).y, ((Rect)(ref r)).width - 6f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).x + 3f, ((Rect)(ref r)).yMax - 1f, ((Rect)(ref r)).width - 6f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 3f, 1f, ((Rect)(ref r)).height - 6f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).xMax - 1f, ((Rect)(ref r)).y + 3f, 1f, ((Rect)(ref r)).height - 6f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).x + 1f, ((Rect)(ref r)).y + 2f, 1f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).y + 1f, 1f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).xMax - 2f, ((Rect)(ref r)).y + 2f, 1f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).xMax - 3f, ((Rect)(ref r)).y + 1f, 1f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).x + 1f, ((Rect)(ref r)).yMax - 3f, 1f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).yMax - 2f, 1f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).xMax - 2f, ((Rect)(ref r)).yMax - 3f, 1f, 1f), WithA(c, frameA)); Fill(new Rect(((Rect)(ref r)).xMax - 3f, ((Rect)(ref r)).yMax - 2f, 1f, 1f), WithA(c, frameA)); Border(new Rect(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).y + 2f, ((Rect)(ref r)).width - 4f, ((Rect)(ref r)).height - 4f), WithA(c, 0.12f)); } public static void NeonDivider(float x, float y, float w) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) Fill(new Rect(x, y, w, 1f), WithA(C(Pal.Pink), 0.7f)); Fill(new Rect(x, y + 1f, w, 1f), WithA(C(Pal.Pink), 0.15f)); } public static void MaskGlyph(Rect box, bool on) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) float w = ((Rect)(ref box)).width; float h = ((Rect)(ref box)).height; Rect r = RR(0.17f, 0.33f, 0.38f, 0.55f); Rect r2 = RR(0.62f, 0.33f, 0.83f, 0.55f); Color e; if (on) { Color c = C(Pal.Accent); Rect r3 = new Rect(((Rect)(ref box)).x - 3f, ((Rect)(ref box)).y - 3f, w + 6f, h + 6f); Fill(r3, WithA(c, 0.1f)); Border(r3, WithA(c, 0.25f)); Fill(RR(0.28f, 0.05f, 0.72f, 0.2f), c); Fill(RR(0.12f, 0.2f, 0.88f, 0.35f), c); Fill(RR(0f, 0.35f, 1f, 0.6f), c); Fill(RR(0.06f, 0.6f, 0.42f, 0.8f), c); Fill(RR(0.58f, 0.6f, 0.94f, 0.8f), c); Color c2 = default(Color); ((Color)(ref c2))..ctor(0.039f, 0.071f, 0.11f, 1f); Fill(r, c2); Fill(r2, c2); } else { e = WithA(C(Pal.Pink), 0.55f); HSeg(0.28f, 0.72f, 0.05f); HSeg(0.12f, 0.28f, 0.2f); HSeg(0.72f, 0.88f, 0.2f); HSeg(0f, 0.12f, 0.35f); HSeg(0.88f, 1f, 0.35f); HSeg(0f, 0.06f, 0.6f); HSeg(0.42f, 0.58f, 0.6f); HSeg(0.94f, 1f, 0.6f); HSeg(0.06f, 0.42f, 0.8f); HSeg(0.58f, 0.94f, 0.8f); VSeg(0.05f, 0.2f, 0.28f); VSeg(0.05f, 0.2f, 0.72f); VSeg(0.2f, 0.35f, 0.12f); VSeg(0.2f, 0.35f, 0.88f); VSeg(0.35f, 0.6f, 0f); VSeg(0.35f, 0.6f, 1f); VSeg(0.6f, 0.8f, 0.06f); VSeg(0.6f, 0.8f, 0.42f); VSeg(0.6f, 0.8f, 0.58f); VSeg(0.6f, 0.8f, 0.94f); Border(r, WithA(C(Pal.Pink), 0.45f)); Border(r2, WithA(C(Pal.Pink), 0.45f)); } void HSeg(float u0, float u1, float v) { //IL_003d: 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) Fill(new Rect(((Rect)(ref box)).x + u0 * w, ((Rect)(ref box)).y + v * h - 1f, (u1 - u0) * w, 2f), e); } Rect RR(float u0, float v0, float u1, float v1) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) return new Rect(((Rect)(ref box)).x + u0 * w, ((Rect)(ref box)).y + v0 * h, (u1 - u0) * w, (v1 - v0) * h); } void VSeg(float v0, float v1, float u) { //IL_003d: 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) Fill(new Rect(((Rect)(ref box)).x + u * w - 1f, ((Rect)(ref box)).y + v0 * h, 2f, (v1 - v0) * h), e); } } public static Sprite IconSprite(Icon type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown //IL_0049: 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) int key = (int)type; if (_iconCache.TryGetValue(key, out var value)) { return value; } Sprite val = null; try { InterfaceControls instance = InterfaceControls.Instance; List val2 = (((Object)(object)instance != (Object)null) ? instance.iconReference : null); if (val2 != null) { for (int i = 0; i < val2.Count; i++) { IconConfig val3 = val2[i]; if (val3 != null && val3.iconType == type) { val = val3.sprite; break; } } } } catch { } if ((Object)(object)val != (Object)null) { _iconCache[key] = val; } return val; } public static bool Icon(Rect r, Icon type, Color tint) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Sprite val = IconSprite(type); if ((Object)(object)val == (Object)null) { return false; } Color color = GUI.color; try { Texture2D texture = val.texture; if ((Object)(object)texture == (Object)null) { return false; } Rect textureRect = val.textureRect; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height); GUI.color = tint; GUI.DrawTextureWithTexCoords(r, (Texture)(object)texture, val2); return true; } catch { return false; } finally { GUI.color = color; } } } public class WarrantHud : MonoBehaviour { private float _nextCompute; private string _cachedWarrant = ""; private string _cachedFine = ""; public WarrantHud(IntPtr ptr) : base(ptr) { } private void OnGUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) try { if ((int)Event.current.type != 7) { return; } SyndicateData data = SyndicateState.Data; if (data == null || SyndicateState.IsWorldLoading) { return; } bool activeWarrant = data.ActiveWarrant; int outstanding = FineLedger.Outstanding; if (!activeWarrant && outstanding <= 0) { return; } if (Time.time >= _nextCompute) { _nextCompute = Time.time + 1f; _cachedWarrant = (activeWarrant ? Compose(data) : ""); _cachedFine = ((outstanding <= 0) ? "" : FineLedger.HudLine()?.ToUpperInvariant()); } bool flag = !string.IsNullOrEmpty(_cachedWarrant); bool flag2 = !string.IsNullOrEmpty(_cachedFine); if (flag || flag2) { float num = 580f; float num2 = ((float)Screen.width - num) / 2f; float num3 = (flag ? 24f : 0f) + (flag2 ? 22f : 0f); SynUI.TopStack(out var _, out var warrantPanelY); Rect r = default(Rect); ((Rect)(ref r))..ctor(num2, warrantPanelY, num, num3 + 12f); SynUI.NeonPanel(r, null, 0.85f, 0.62f); SynUI.Fill(new Rect(((Rect)(ref r)).x + 3f, ((Rect)(ref r)).y, ((Rect)(ref r)).width - 6f, 2f), SynUI.Warn); Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.34f, 0.34f); Color color = Color.Lerp(SynUI.Caution, Color.white, 0.2f); float num4 = warrantPanelY + 6f; if (flag) { SynUI.Label(new Rect(num2, num4, num, 24f), _cachedWarrant, val, 17, (FontStyle)1, (TextAnchor)4); float num5 = num4 + 2f; SynUI.Icon(new Rect(num2 + 14f, num5, 20f, 20f), (Icon)22, val); SynUI.Icon(new Rect(num2 + num - 14f - 20f, num5, 20f, 20f), (Icon)22, val); num4 += 24f; } if (flag2) { SynUI.Label(new Rect(num2, num4, num, 22f), _cachedFine, color, 14, (FontStyle)1, (TextAnchor)4); } } } catch { } } private static string Compose(SyndicateData d) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) try { if (string.IsNullOrEmpty(d.WarrantExpires)) { return "WANTED — ENFORCERS ARE HUNTING YOU"; } double totalHours = (TimeData.Deserialize(d.WarrantExpires) - Lib.Time.CurrentDateTime).TotalHours; if (totalHours <= 0.0) { return "WANTED — THE WARRANT IS ABOUT TO LIFT…"; } int num = (int)totalHours; int value = (int)((totalHours - (double)num) * 60.0); string text = $"{num}H {value:00}M"; return "WANTED FOR MURDER — WARRANT EXPIRES IN " + text; } catch { return "WANTED — ENFORCERS ARE HUNTING YOU"; } } } } namespace TheSyndicate.Supplies { internal static class GearPricing { private static readonly Dictionary _orig = new Dictionary(); public static float GearMultiplier => Mathf.Clamp(SyndicateConfig.GearPriceMultiplier?.Value ?? 3f, 0.1f, 100f); public static float AmmoMultiplier => Mathf.Clamp(SyndicateConfig.AmmoPriceMultiplier?.Value ?? 3f, 0.1f, 100f); public static float GunMultiplier => Mathf.Clamp(SyndicateConfig.GunPriceMultiplier?.Value ?? 7f, 0.1f, 100f); public static float MultiplierFor(SupplyEntry e) { if (e == null) { return GearMultiplier; } if (e.Kind == SupplyKind.Ammo) { return AmmoMultiplier; } if (e.Category == "SIDEARMS" || e.Category == "LONG GUNS") { return GunMultiplier; } return GearMultiplier; } public static void Apply() { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { Toolbox instance = Toolbox.Instance; if ((Object)(object)instance == (Object)null) { return; } int num = 0; SupplyEntry[] entries = SupplyCatalog.Entries; foreach (SupplyEntry supplyEntry in entries) { if (supplyEntry == null || supplyEntry.Group != SupplyGroup.Gear || supplyEntry.PresetName == "SecondSkinDisk") { continue; } InteractablePreset val = null; try { val = instance.GetInteractablePreset(supplyEntry.PresetName); } catch { } if (!((SoCustomComparison)(object)val == (SoCustomComparison)null)) { float num2 = MultiplierFor(supplyEntry); if (!_orig.TryGetValue(supplyEntry.PresetName, out var value)) { value = val.value; _orig[supplyEntry.PresetName] = value; } val.value = new Vector2(value.x * num2, value.y * num2); num++; } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(140, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GearPricing] scaled "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" gear preset value(s) globally by bucket (guns x"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(GunMultiplier, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", ammo x"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(AmmoMultiplier, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", gear x"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(GearMultiplier, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; Syndicate shop still discounts from the higher base)."); } logger.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[GearPricing] apply failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } } internal enum SupplyKind { Standard, SelfRouting, SyncDisk, Ammo, Service } internal enum SupplyGroup { Gear, Grocery } internal sealed class SupplyEntry { public readonly string PresetName; public readonly string DisplayName; public readonly string Category; public readonly int BaseValue; public readonly int MinLevel; public readonly SupplyKind Kind; public readonly string Blurb; public readonly string AmmoFor; public readonly SupplyGroup Group; public SupplyEntry(string preset, string display, string category, int baseValue, int minLevel, SupplyKind kind, string blurb, string ammoFor = "", SupplyGroup group = SupplyGroup.Gear) { PresetName = preset; DisplayName = display; Category = category; BaseValue = baseValue; MinLevel = minLevel; Kind = kind; Blurb = blurb; AmmoFor = ammoFor; Group = group; } } internal static class SupplyCatalog { public const string SecondSkinKey = "SecondSkinDisk"; public const string MaskDiskKey = "MaskDisk"; public const string RedisguiseKey = "PersonaWipe"; public static readonly SupplyEntry[] Entries = new SupplyEntry[56] { new SupplyEntry("SemiAutomaticPistol", "LAZARUS 5", "SIDEARMS", 100, 2, SupplyKind.Standard, "A plain semi-auto. Reliable, unremarkable, forgettable — exactly the point."), new SupplyEntry("Revolver", "LUCKY 7", "SIDEARMS", 100, 2, SupplyKind.Standard, "Six shots, no jams, no brass left behind if you're careful."), new SupplyEntry("SemiAutomaticPistolSilenced", "LAZARUS 5 SILENCED", "SIDEARMS", 100, 3, SupplyKind.Standard, "The professional's sidearm. Quiet enough that the neighbours keep sleeping."), new SupplyEntry("Shotgun", "SHACKLEY SHOTGUN", "LONG GUNS", 100, 3, SupplyKind.Standard, "Loud, ugly, final. For when subtlety already left the building."), new SupplyEntry("BattleRifle", "FAUCON RIFLE", "LONG GUNS", 100, 3, SupplyKind.Standard, "Fully automatic. More gun than most jobs need — hold to fire."), new SupplyEntry("SniperRifle", "HAMILTON RIFLE", "LONG GUNS", 100, 3, SupplyKind.Standard, "Reach out and touch someone from three rooftops away."), new SupplyEntry("21AmmoSmall", "PISTOL AMMO (SMALL)", "AMMUNITION", 100, 2, SupplyKind.Ammo, "A small box of pistol/revolver rounds.", "Lazarus 5, Lazarus 5 Silenced & Lucky 7"), new SupplyEntry("21AmmoLarge", "PISTOL AMMO (LARGE)", "AMMUNITION", 100, 2, SupplyKind.Ammo, "A full box of pistol/revolver rounds — more shots per box.", "Lazarus 5, Lazarus 5 Silenced & Lucky 7"), new SupplyEntry("309Ammo", "RIFLE AMMO", "AMMUNITION", 100, 3, SupplyKind.Ammo, "Full-power rifle rounds.", "Faucon Rifle & Hamilton Rifle"), new SupplyEntry("BuckshotAmmo", "BUCKSHOT", "AMMUNITION", 100, 3, SupplyKind.Ammo, "Shotgun shells — a spread of pellets. Loud, ugly, final.", "Shackley Shotgun"), new SupplyEntry("HuntingAmmo", "DEER SLUG", "AMMUNITION", 100, 3, SupplyKind.Ammo, "Shotgun slugs — one heavy projectile instead of a spread.", "Shackley Shotgun"), new SupplyEntry("KitchenKnifeLarge", "CHEF'S KNIFE", "BLADES", 20, 1, SupplyKind.Standard, "Ordinary until it isn't. Untraceable in any kitchen in the city."), new SupplyEntry("CombatKnife", "COMBAT KNIFE", "BLADES", 100, 2, SupplyKind.Standard, "Balanced, blackened, purpose-built. No pretending this one's for cooking."), new SupplyEntry("VintageSword", "VINTAGE SWORD", "BLADES", 300, 3, SupplyKind.Standard, "A collector's piece with a working edge. Theatrical, if that's your style."), new SupplyEntry("Katana", "KATANA", "BLADES", 400, 3, SupplyKind.Standard, "Folded steel. Overkill that photographs beautifully."), new SupplyEntry("BasBouleBat", "BAT", "BLUNT", 80, 1, SupplyKind.Standard, "Sporting goods. What you do after hours is your business."), new SupplyEntry("Truncheon", "TRUNCHEON", "BLUNT", 120, 2, SupplyKind.Standard, "Weighted, wrist-strapped, quiet work. The enforcers carry them for a reason."), new SupplyEntry("Syringe", "LOADED SYRINGE", "POISON", 12, 1, SupplyKind.Standard, "A full syringe. No loud goodbyes."), new SupplyEntry("PoisonBottle", "POISON VIAL", "POISON", 15, 1, SupplyKind.Standard, "A small bottle with a big effect. Handle it like it matters."), new SupplyEntry("Sleeping Pills", "SEDATIVE", "POISON", 40, 0, SupplyKind.Standard, "A fast dose of Dorma-Dix. Get behind a mark unseen and put them under — no struggle, no marks. The clean way to stage an accident."), new SupplyEntry("Handcuffs", "HANDCUFFS", "TOOLS", 25, 1, SupplyKind.Standard, "For when a target's worth more restrained than cold."), new SupplyEntry("DoorWedge", "DOOR WEDGE", "TOOLS", 100, 1, SupplyKind.Standard, "Buys you seconds when seconds are everything — jam a door behind you."), new SupplyEntry("Camera", "CAMERA", "TOOLS", 85, 1, SupplyKind.Standard, "Proof of work. Some clients pay extra for a photograph."), new SupplyEntry("CleaningSpray", "FINGERPRINT REMOVER", "TOOLS", 60, 0, SupplyKind.Standard, "Solvent in a can. Point it at anything you've handled and it lifts your prints clean off — hold it, look at the object, use it. 50 wipes."), new SupplyEntry("Codebreaker", "CODEBREAKER", "TOOLS", 75, 1, SupplyKind.Standard, "Talks keypads open. Slow, but it never leaves a scratch."), new SupplyEntry("Tracker", "BLOODHOUND TRACKER", "TOOLS", 120, 1, SupplyKind.Standard, "Plant it and let them lead you home."), new SupplyEntry("FlashBomb", "FLASH GRENADE", "TOOLS", 65, 2, SupplyKind.Standard, "White light, blind room, clean exit."), new SupplyEntry("Incapacitator", "INCAPACITATOR GRENADE", "TOOLS", 65, 2, SupplyKind.Standard, "Drops whoever's in the blast down for a while. Non-lethal — mostly."), new SupplyEntry("PrintScanner", "PRINT SCANNER", "TOOLS", 100, 0, SupplyKind.SelfRouting, "Reads what a scene remembers — and what you left behind. Slots into your print reader."), new SupplyEntry("BallisticArmour", "BALLISTIC VEST", "TOOLS", 400, 2, SupplyKind.Standard, "Because some jobs shoot back."), new SupplyEntry("LockpickKit", "LOCKPICK KIT", "CONSUMABLE", 50, 0, SupplyKind.SelfRouting, "A fresh set — adds thirty picks to your kit. Every locked door is a suggestion."), new SupplyEntry("SecondSkinDisk", "SECOND SKIN DISK", "CUSTOM", 2000, 2, SupplyKind.SyncDisk, "The tailor's own work — a sync disk that leaves no prints while worn. A spare, in case you lose the first."), new SupplyEntry("MaskDisk", "FALSE FACE DISK", "CUSTOM", 3000, 1, SupplyKind.SyncDisk, "A projected identity veil — witnesses see a masked figure they can't name (but a covered face draws eyes). A spare, in case you lose the first."), new SupplyEntry("PersonaWipe", "PERSONA WIPE", "CUSTOM", 2500, 3, SupplyKind.Service, "The tailor retires your masked persona — new geometry, cold trail. The street forgets the figure. The case files don't. (Lowers mask notoriety.)"), new SupplyEntry("Bourbon", "BOURBON", "DRINKS", 25, 0, SupplyKind.Standard, "A bottle of the good stuff. For after the job — or during.", "", SupplyGroup.Grocery), new SupplyEntry("Vodka", "VODKA", "DRINKS", 20, 0, SupplyKind.Standard, "Clear, clean, deniable.", "", SupplyGroup.Grocery), new SupplyEntry("Wine", "WINE", "DRINKS", 15, 0, SupplyKind.Standard, "A civilised evening in.", "", SupplyGroup.Grocery), new SupplyEntry("Cider", "CIDER", "DRINKS", 9, 0, SupplyKind.Standard, "Cheap and cheerful.", "", SupplyGroup.Grocery), new SupplyEntry("StarchKola", "STARCH KOLA", "DRINKS", 2, 0, SupplyKind.Standard, "The city's favourite fizz.", "", SupplyGroup.Grocery), new SupplyEntry("SynthMilk", "SYNTH MILK", "DRINKS", 5, 0, SupplyKind.Standard, "Does a body good. Allegedly.", "", SupplyGroup.Grocery), new SupplyEntry("TakeawayCoffee", "COFFEE", "DRINKS", 5, 0, SupplyKind.Standard, "The only thing keeping the stakeout going.", "", SupplyGroup.Grocery), new SupplyEntry("ChocolateBar", "CHOCOLATE BAR", "PANTRY", 4, 0, SupplyKind.Standard, "Small comfort, decent margins.", "", SupplyGroup.Grocery), new SupplyEntry("Apple", "APPLE", "PANTRY", 3, 0, SupplyKind.Standard, "Keeps the doctor away. Keeps you honest.", "", SupplyGroup.Grocery), new SupplyEntry("TinnedFood", "TINNED FOOD", "PANTRY", 100, 0, SupplyKind.Standard, "Stocks the safehouse. Lasts forever.", "", SupplyGroup.Grocery), new SupplyEntry("Cigarettes", "CIGARETTES", "VICES", 9, 0, SupplyKind.Standard, "A pack to steady the hands.", "", SupplyGroup.Grocery), new SupplyEntry("Cigar", "CIGAR", "VICES", 10, 0, SupplyKind.Standard, "For closing a contract in style.", "", SupplyGroup.Grocery), new SupplyEntry("Tobacco", "TOBACCO", "VICES", 15, 0, SupplyKind.Standard, "Roll your own.", "", SupplyGroup.Grocery), new SupplyEntry("HeatPack", "HEAT PACK", "MEDICAL", 12, 0, SupplyKind.Standard, "Takes the edge off the cold and the shakes.", "", SupplyGroup.Grocery), new SupplyEntry("Bandage", "BANDAGE", "MEDICAL", 30, 0, SupplyKind.Standard, "Stops the bleeding. Yours, usually.", "", SupplyGroup.Grocery), new SupplyEntry("Painkillers", "PAINKILLERS", "MEDICAL", 30, 0, SupplyKind.Standard, "Keeps you upright long enough to finish and get home.", "", SupplyGroup.Grocery), new SupplyEntry("Splint", "SPLINT", "MEDICAL", 30, 0, SupplyKind.Standard, "For the landing that didn't go to plan.", "", SupplyGroup.Grocery), new SupplyEntry("CharcoalTablets", "CHARCOAL TABLETS", "MEDICAL", 15, 0, SupplyKind.Standard, "Activated charcoal. Swallow a dose and it soaks a poison up before it takes hold — worth carrying when your line of work involves the stuff.", "", SupplyGroup.Grocery), new SupplyEntry("CoughMedicine", "COUGH MEDICINE", "MEDICAL", 30, 0, SupplyKind.Standard, "Quiets a cough. A quiet stakeout is a live stakeout.", "", SupplyGroup.Grocery), new SupplyEntry("BetaBlockers", "BETA BLOCKERS", "MEDICAL", 30, 0, SupplyKind.Standard, "Slows a racing heart. Keeps the hand steady when it counts.", "", SupplyGroup.Grocery), new SupplyEntry("Antidepressants", "ANTIDEPRESSANTS", "MEDICAL", 30, 0, SupplyKind.Standard, "The city takes its toll. A little chemical help never hurt anyone.", "", SupplyGroup.Grocery), new SupplyEntry("BreathMints", "BREATH MINTS", "VICES", 3, 0, SupplyKind.Standard, "A tin of Minute Mints. Steady breath, and nobody smells the bourbon.", "", SupplyGroup.Grocery) }; public static int DiscountPercent => Math.Clamp(SyndicateConfig.SuppliesDiscountPercent?.Value ?? 20, 0, 90); public static int GroceryMarkupPercent => Math.Clamp(SyndicateConfig.GroceriesMarkupPercent?.Value ?? 10, 0, 500); public static int Price(SupplyEntry e) { if (e == null) { return 0; } if (e.Kind == SupplyKind.Service) { return Math.Max(1, SyndicateConfig.MaskRedisguiseCost?.Value ?? 2500); } if (e.Group == SupplyGroup.Grocery) { int groceryMarkupPercent = GroceryMarkupPercent; int num = ((groceryMarkupPercent > 0) ? Math.Max(1, (int)Math.Ceiling((double)(e.BaseValue * groceryMarkupPercent) / 100.0)) : 0); return Math.Max(1, e.BaseValue + num); } double num2 = (float)e.BaseValue * GearPricing.MultiplierFor(e); return Math.Max(1, (int)Math.Round(num2 * (1.0 - (double)DiscountPercent / 100.0))); } public static bool Unlocked(SupplyEntry e) { if (e != null) { return SyndicateState.Level >= e.MinLevel; } return false; } public static int[] IndicesForGroup(SupplyGroup g) { List list = new List(); for (int i = 0; i < Entries.Length; i++) { if (Entries[i].Group == g) { list.Add(i); } } if (g == SupplyGroup.Grocery) { return list.OrderBy((int num) => GroceryCategoryRank(Entries[num].Category)).ToArray(); } return list.OrderBy((int num) => Entries[num].MinLevel).ToArray(); } private static int GroceryCategoryRank(string category) { return category switch { "MEDICAL" => 0, "VICES" => 1, "PANTRY" => 2, "DRINKS" => 3, _ => 4, }; } public static SupplyEntry Find(string presetName) { if (string.IsNullOrEmpty(presetName)) { return null; } SupplyEntry[] entries = Entries; foreach (SupplyEntry supplyEntry in entries) { if (supplyEntry.PresetName == presetName) { return supplyEntry; } } return null; } } internal static class SupplyDelivery { private enum SpawnMode { AtDoor, FeetDrop, Retry } private const int FeetDropDeadlineHours = 24; private const int KnockCount = 3; private const float MergeRadius = 2f; private static readonly Vector3 DoorOffset = new Vector3(0.35f, 0f, 0.35f); private static SyndicateData Data => SyndicateState.Data; private static bool Enabled => SyndicateConfig.SuppliesEnabled?.Value ?? true; private static int DeliveryHours => Math.Max(0, SyndicateConfig.SuppliesDeliveryHours?.Value ?? 1); public static bool TryCheckout(Dictionary cart, out string failReason) { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown failReason = null; if (!Enabled) { failReason = "Supplies are offline."; return false; } if (cart == null || cart.Count == 0) { failReason = "Cart's empty. Browse the shelves."; return false; } List list = new List(); int num = 0; bool flag = false; foreach (KeyValuePair item in cart) { int key = item.Key; int value = item.Value; if (key < 0 || key >= SupplyCatalog.Entries.Length || value <= 0) { continue; } SupplyEntry supplyEntry = SupplyCatalog.Entries[key]; if (!SupplyCatalog.Unlocked(supplyEntry)) { failReason = "Some of that gear is above your station now. Clear it from the cart."; return false; } if (supplyEntry.Kind == SupplyKind.Service) { if (!MaskNotoriety.CanRedisguise(out var reason)) { failReason = reason; return false; } flag = true; num += SupplyCatalog.Price(supplyEntry); } else { for (int i = 0; i < value; i++) { list.Add(supplyEntry.PresetName); } num += SupplyCatalog.Price(supplyEntry) * value; } } if (list.Count == 0 && !flag) { failReason = "Cart's empty. Browse the shelves."; return false; } GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null) { failReason = "Not ready."; return false; } if (instance.money < num) { failReason = $"You're short {num - instance.money}cr. The Syndicate doesn't run tabs."; return false; } bool flag2 = false; bool flag3 = default(bool); try { instance.AddMoney(-num, true, "Syndicate: supplies"); flag2 = true; if (flag) { try { MaskNotoriety.Redisguise(); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Supplies] persona wipe apply failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } if (list.Count > 0) { Data.PendingDeliveries.Add(new DeliveryDto { CaseId = -1, Manifest = list, ArriveAt = StampHours(DeliveryHours), Paid = num }); } ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(38, 3, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Supplies] checkout OK: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" item(s)"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag ? " + persona wipe" : ""); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", -"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("cr."); } logger2.LogInfo(val2); return true; } catch (Exception ex2) { if (flag2) { try { instance.AddMoney(num, false, "Syndicate: refund"); } catch { } } ManualLogSource logger3 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(42, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Supplies] checkout failed (refunded "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(flag2 ? num : 0); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("cr): "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2); } logger3.LogError(val3); failReason = "The deal fell through — your money's back."; return false; } } public static void Tick() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown try { if (!Enabled || SyndicateState.IsWorldLoading) { return; } List pendingDeliveries = Data.PendingDeliveries; if (pendingDeliveries == null || pendingDeliveries.Count == 0) { return; } DeliveryDto[] array = pendingDeliveries.ToArray(); foreach (DeliveryDto deliveryDto in array) { if (deliveryDto == null) { continue; } if (deliveryDto.CaseId >= 0 && deliveryDto.Manifest.Count == 0) { HandleDespawn(deliveryDto); continue; } if (deliveryDto.CaseId >= 0 && StableIds.ResolveInteractable(deliveryDto.CaseId) == null) { deliveryDto.CaseId = -1; } if (deliveryDto.CaseId == -1 && IsDue(deliveryDto)) { SpawnDelivery(deliveryDto); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Supplies] Tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void SpawnDelivery(DeliveryDto dto) { //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Expected O, but got Unknown //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Expected O, but got Unknown //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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_00b7: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } InteractablePreset val = ResolveBriefcasePreset(); if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { Plugin.Logger.LogWarning((object)"[Supplies] no briefcase preset resolved yet — will retry."); return; } Vector3 pos; Vector3 euler; NewDoor door; SpawnMode spawnMode = ResolveSpawn(instance, dto, out pos, out euler, out door); switch (spawnMode) { case SpawnMode.Retry: return; case SpawnMode.AtDoor: { DeliveryDto[] array = Data.PendingDeliveries.ToArray(); foreach (DeliveryDto deliveryDto in array) { if (deliveryDto != null && deliveryDto != dto && deliveryDto.CaseId >= 0 && deliveryDto.Manifest.Count != 0) { Interactable val2 = StableIds.ResolveInteractable(deliveryDto.CaseId); if (val2 != null && !(Vector3.Distance(val2.wPos, pos) > 2f)) { deliveryDto.Manifest.AddRange(dto.Manifest); deliveryDto.Paid += dto.Paid; Data.PendingDeliveries.Remove(dto); Notify("Another order came through — the courier added it to the case at your door."); Plugin.Logger.LogInfo((object)"[Supplies] merged a due delivery into the live case at the door."); return; } } } break; } } Human val3 = Rewards.ResolveFixer(); Interactable val4 = null; try { val4 = InteractableCreator.Instance.CreateWorldInteractable(val, (Human)(object)instance, val3, (Human)(object)instance, pos, euler, (List)null, (Object)null, ""); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Supplies] case spawn threw: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger.LogWarning(val5); } if (val4 == null) { Plugin.Logger.LogWarning((object)"[Supplies] case spawn returned null — will retry."); return; } dto.CaseId = val4.id; if (spawnMode == SpawnMode.AtDoor) { try { if ((Object)(object)door != (Object)null && door.isClosed && !door.knockingInProgress) { GameplayController.Instance.KnockOnDoor(door, (Actor)(object)instance, 3, 0f); } } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Supplies] knock failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex2.Message); } logger2.LogWarning(val5); } Notify("Knock at the door. A courier left a case for you."); } else { Notify("The courier found you. Your case is at your feet — don't ask how."); } ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(54, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[Supplies] delivery case spawned (id="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(val4.id); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(", mode="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(spawnMode); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(", items="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(dto.Manifest.Count); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(")."); } logger3.LogInfo(val6); } catch (Exception ex3) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Supplies] SpawnDelivery failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex3.Message); } logger4.LogWarning(val5); } } private static SpawnMode ResolveSpawn(Player player, DeliveryDto dto, out Vector3 pos, out Vector3 euler, out NewDoor door) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0085: 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) pos = default(Vector3); euler = Vector3.zero; door = null; try { NewAddress home = ((Human)player).home; if ((Object)(object)home != (Object)null) { NodeAccess mainEntrance = ((NewGameLocation)home).GetMainEntrance(); if (mainEntrance != null) { door = mainEntrance.door; if ((Object)(object)door != (Object)null && door.doorInteractable != null) { Interactable doorInteractable = door.doorInteractable; pos = doorInteractable.wPos + Quaternion.Euler(doorInteractable.wEuler) * DoorOffset; euler = doorInteractable.wEuler; return SpawnMode.AtDoor; } Vector3 worldAccessPoint = mainEntrance.worldAccessPoint; if (worldAccessPoint != Vector3.zero) { pos = worldAccessPoint; euler = Vector3.zero; door = null; return SpawnMode.AtDoor; } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Supplies] door resolve failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } try { if (IsPastDeadline(dto)) { pos = ((Component)player).transform.position + ((Component)player).transform.forward * 0.6f; euler = Vector3.zero; door = null; return SpawnMode.FeetDrop; } } catch { } return SpawnMode.Retry; } private static void HandleDespawn(DeliveryDto dto) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown bool flag = default(bool); try { Interactable val = StableIds.ResolveInteractable(dto.CaseId); if (val == null) { Data.PendingDeliveries.Remove(dto); return; } try { val.SafeDelete(true); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Supplies] SafeDelete threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } if (StableIds.ResolveInteractable(dto.CaseId) == null) { Data.PendingDeliveries.Remove(dto); } } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Supplies] HandleDespawn failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.Message); } logger2.LogWarning(val2); } } public static bool IsCourierCase(int id) { if (id < 0) { return false; } List pendingDeliveries = Data.PendingDeliveries; if (pendingDeliveries == null) { return false; } for (int i = 0; i < pendingDeliveries.Count; i++) { if (pendingDeliveries[i] != null && pendingDeliveries[i].CaseId == id) { return true; } } return false; } public static void OnCaseInteracted(Interactable caseObj) { //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Expected O, but got Unknown //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_0143: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) bool flag2 = default(bool); try { if (caseObj == null) { return; } DeliveryDto deliveryDto = null; foreach (DeliveryDto pendingDelivery in Data.PendingDeliveries) { if (pendingDelivery != null && pendingDelivery.CaseId == caseObj.id) { deliveryDto = pendingDelivery; break; } } if (deliveryDto == null) { return; } Player instance = Player.Instance; FirstPersonItemController instance2 = FirstPersonItemController.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null) { return; } Human val = Rewards.ResolveFixer(); bool flag = false; int num = 0; Vector3 val2 = caseObj.wPos + Vector3.up * 0.05f; foreach (string item in new List(deliveryDto.Manifest)) { SupplyKind supplyKind = SupplyCatalog.Find(item)?.Kind ?? SupplyKind.Standard; if (supplyKind == SupplyKind.Ammo) { supplyKind = SupplyKind.Standard; } if (supplyKind == SupplyKind.SyncDisk) { if (GrantSyncDisk(caseObj, instance, val, num, item)) { deliveryDto.Manifest.Remove(item); num++; } continue; } InteractablePreset interactablePreset = Toolbox.Instance.GetInteractablePreset(item); if ((SoCustomComparison)(object)interactablePreset == (SoCustomComparison)null) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(56, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Supplies] manifest item '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' has no preset — dropping it."); } logger.LogWarning(val3); deliveryDto.Manifest.Remove(item); continue; } if (supplyKind == SupplyKind.Standard && !instance2.IsSlotAvailable()) { flag = true; continue; } Interactable val4 = null; try { val4 = InteractableCreator.Instance.CreateWorldInteractable(interactablePreset, (Human)(object)instance, val, (Human)(object)instance, val2, Vector3.zero, (List)null, (Object)null, ""); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Supplies] item spawn threw for '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } if (val4 == null) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(59, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Supplies] item spawn null for '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' — keeping it in the case."); } logger3.LogWarning(val3); continue; } if (supplyKind == SupplyKind.SelfRouting) { try { instance2.PickUpItem(val4, false, false, false, true, true); } catch (Exception ex2) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(45, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Supplies] self-routing pickup threw for '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2.Message); } logger4.LogWarning(val3); } deliveryDto.Manifest.Remove(item); continue; } bool flag3 = false; try { flag3 = instance2.PickUpItem(val4, false, false, false, true, true); } catch (Exception ex3) { ManualLogSource logger5 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(32, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Supplies] pickup threw for '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex3.Message); } logger5.LogWarning(val3); } if (flag3) { deliveryDto.Manifest.Remove(item); continue; } try { val4.SafeDelete(true); } catch { } flag = true; } if (deliveryDto.Manifest.Count == 0) { Notify("That's everything. Leave the case — it was never here."); try { caseObj.SafeDelete(true); } catch { } if (StableIds.ResolveInteractable(caseObj.id) == null) { Data.PendingDeliveries.Remove(deliveryDto); } } else if (flag) { Notify("Your hands are full. What you can't carry stays in the case — come back for it."); } } catch (Exception ex4) { ManualLogSource logger6 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Supplies] OnCaseInteracted failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex4.Message); } logger6.LogWarning(val3); } } private static bool GrantSyncDisk(Interactable caseObj, Player player, Human fixer, int seq, string entryKey) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_004c: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) bool flag2 = default(bool); try { SyncDisk val = ((entryKey == "MaskDisk") ? Rewards.MaskDisk : Rewards.GlovesDisk); object obj; if (val == null) { obj = null; } else { SyncDiskPreset preset = val.Preset; obj = ((preset != null) ? preset.interactable : null); } if ((SoCustomComparison)obj == (SoCustomComparison)null) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(70, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Supplies] sync-disk preset not ready for '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(entryKey); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' — keeping it in the case."); } logger.LogWarning(val2); return false; } InteractablePreset interactable = val.Preset.interactable; Vector3 val3 = caseObj.wPos + Vector3.up * 0.1f + Quaternion.Euler(0f, (float)seq * 72f, 0f) * new Vector3(0.2f, 0f, 0f); Interactable val4 = null; try { val4 = InteractableCreator.Instance.CreateWorldInteractable(interactable, (Human)(object)player, fixer, (Human)(object)player, val3, Vector3.zero, (List)null, (Object)null, ""); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Supplies] disk spawn threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } if (val4 == null) { return false; } try { val4.syncDisk = val.Preset; } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(60, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Supplies] disk stamp failed — removing orphan, will retry: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.Message); } logger3.LogWarning(val2); try { val4.SafeDelete(true); } catch { } return false; } Notify("The disk is with the case. Take it to a sync clinic."); return true; } catch (Exception ex3) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Supplies] GrantSyncDisk failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex3.Message); } logger4.LogWarning(val2); return false; } } private static InteractablePreset ResolveBriefcasePreset() { string[] array = new string[3] { "BriefcaseCustom", "Briefcase", "BriefcaseDocuments" }; foreach (string text in array) { try { InteractablePreset interactablePreset = Toolbox.Instance.GetInteractablePreset(text); if ((SoCustomComparison)(object)interactablePreset != (SoCustomComparison)null) { return interactablePreset; } } catch { } } return null; } private static string StampHours(int h) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) try { TimeData val = Lib.Time.CurrentDateTime; val = ((TimeData)(ref val)).AddHours(h); return ((TimeData)(ref val)).Serialize(); } catch { return ""; } } private static bool IsDue(DeliveryDto dto) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(dto.ArriveAt)) { return true; } try { return Lib.Time.CurrentDateTime >= TimeData.Deserialize(dto.ArriveAt); } catch { return true; } } private static bool IsPastDeadline(DeliveryDto dto) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(dto.ArriveAt)) { return true; } try { TimeData currentDateTime = Lib.Time.CurrentDateTime; TimeData val = TimeData.Deserialize(dto.ArriveAt); return currentDateTime >= ((TimeData)(ref val)).AddHours(24); } catch { return true; } } private static void Notify(string msg) { MessageQueue.Enqueue(msg); } public static int DebugDeliverNow() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown int num = 0; foreach (DeliveryDto pendingDelivery in Data.PendingDeliveries) { if (pendingDelivery != null && pendingDelivery.CaseId == -1) { pendingDelivery.ArriveAt = StampHours(0); num++; } } ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(57, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Supplies] debug: advanced "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" pending delivery(ies) to now."); } logger.LogInfo(val); return num; } } } namespace TheSyndicate.State { internal static class StableIds { public static long LocationKey(NewGameLocation loc) { try { if ((Object)(object)loc == (Object)null) { return 0L; } NewAddress thisAsAddress = loc.thisAsAddress; if ((Object)(object)thisAsAddress != (Object)null) { return 0x100000000L | (long)(uint)thisAsAddress.id; } StreetController thisAsStreet = loc.thisAsStreet; if ((Object)(object)thisAsStreet != (Object)null) { return 0x200000000L | (long)(uint)thisAsStreet.streetID; } } catch { } return 0L; } public static NewGameLocation ResolveLocation(long key) { if (key == 0L) { return null; } int num = (int)key; long num2 = key >> 32; try { CityData instance = CityData.Instance; if ((Object)(object)instance == (Object)null) { return null; } if (num2 == 1 && instance.addressDirectory != null) { Enumerator enumerator = instance.addressDirectory.GetEnumerator(); while (enumerator.MoveNext()) { NewAddress current = enumerator.Current; if ((Object)(object)current != (Object)null && current.id == num) { return (NewGameLocation)(object)current; } } } else if (num2 == 2 && instance.streetDirectory != null) { Enumerator enumerator2 = instance.streetDirectory.GetEnumerator(); while (enumerator2.MoveNext()) { StreetController current2 = enumerator2.Current; if ((Object)(object)current2 != (Object)null && current2.streetID == num) { return (NewGameLocation)(object)current2; } } } } catch { } return null; } public static Human ResolveHumanIncludingDead(int humanId) { try { CityData instance = CityData.Instance; if ((Object)(object)instance == (Object)null) { return null; } Human val = null; if (instance.GetHuman(humanId, ref val, false) && (Object)(object)val != (Object)null) { return val; } if (instance.citizenDirectory != null) { Enumerator enumerator = instance.citizenDirectory.GetEnumerator(); while (enumerator.MoveNext()) { Citizen current = enumerator.Current; if ((Object)(object)current != (Object)null && ((Human)current).humanID == humanId) { return (Human)(object)current; } } } if (instance.deadCitizensDirectory != null) { Enumerator enumerator2 = instance.deadCitizensDirectory.GetEnumerator(); while (enumerator2.MoveNext()) { Human current2 = enumerator2.Current; if ((Object)(object)current2 != (Object)null && current2.humanID == humanId) { return current2; } } } } catch { } return null; } public static Interactable ResolveInteractable(int id) { if (id < 0) { return null; } try { CityData instance = CityData.Instance; if ((Object)(object)instance == (Object)null || instance.interactableDirectory == null) { return null; } Enumerator enumerator = instance.interactableDirectory.GetEnumerator(); while (enumerator.MoveNext()) { Interactable current = enumerator.Current; if (current != null && current.id == id) { return current; } } } catch { } return null; } } public enum SuspicionState { Clean, Suspicious, Identified } internal sealed class TolerantSuspicionStateConverter : JsonConverter { public override SuspicionState Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { try { switch (reader.TokenType) { case JsonTokenType.String: { if (Enum.TryParse(reader.GetString(), ignoreCase: true, out var result)) { return result; } break; } case JsonTokenType.Number: { if (reader.TryGetInt32(out var value) && Enum.IsDefined(typeof(SuspicionState), value)) { return (SuspicionState)value; } break; } case JsonTokenType.StartObject: case JsonTokenType.StartArray: reader.Skip(); break; } } catch { } return SuspicionState.Clean; } public override void Write(Utf8JsonWriter writer, SuspicionState value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); } } public class ObjectiveData { public string Type { get; set; } = ""; public float Bonus { get; set; } public string Outcome { get; set; } = "Pending"; public string DeadlineAt { get; set; } = ""; public bool ItemMailed { get; set; } public float Penalty { get; set; } public string Variant { get; set; } = ""; public bool KilledWithIssued { get; set; } } public class ContractData { public int TargetId { get; set; } = -1; public string TargetName { get; set; } = ""; public string Type { get; set; } = "Lethal"; public string Status { get; set; } = "Active"; public int Tier { get; set; } = 1; public int Reward { get; set; } public bool RequiresCallingCard { get; set; } public float TimeOfDeath { get; set; } = -1f; public int Seq { get; set; } public string InfoLevel { get; set; } = "Full"; public int BasePayout { get; set; } public string LeadText { get; set; } = ""; public string OfferedAt { get; set; } = ""; public int CaseId { get; set; } = -1; public string KilledAt { get; set; } = ""; public string PayoutState { get; set; } = ""; public bool ForensicsIdentified { get; set; } public string PayableAt { get; set; } = ""; public string SettledAt { get; set; } = ""; public bool RewardGranted { get; set; } public string TippedAt { get; set; } = ""; public string IssuedWeaponPreset { get; set; } = ""; public int IssuedWeaponId { get; set; } = -1; public List Objectives { get; set; } = new List(); } public class PrintDto { public long InteractableId { get; set; } public int RoomId { get; set; } = -1; public long LocKey { get; set; } public int Heat { get; set; } public string ObjectName { get; set; } = "object"; } public class WitnessDto { public int HumanId { get; set; } public string Name { get; set; } = ""; public bool SawKill { get; set; } public string ReportDue { get; set; } = ""; public bool Counted { get; set; } public bool MaskedAtSighting { get; set; } } public class CrimeSceneDto { public int VictimId { get; set; } public string VictimName { get; set; } = ""; public long LocKey { get; set; } public string LocationName { get; set; } = ""; public List Witnesses { get; set; } = new List(); public int WeaponId { get; set; } = -1; public string WeaponName { get; set; } = ""; public bool WeaponHadPlayerPrintAtKill { get; set; } public bool Discovered { get; set; } public int BaselineDiscoveredBy { get; set; } = int.MinValue; public bool NativeReported { get; set; } public string WelfareExpires { get; set; } = ""; public string ColdExpires { get; set; } = ""; public string KillAt { get; set; } = ""; public bool WelfareRaidDispatched { get; set; } public string WelfareRaidFallbackDue { get; set; } = ""; public bool MaskedDescriptionReported { get; set; } public bool ForgedOverdose { get; set; } public bool ForgedFall { get; set; } public bool CameraNearNoted { get; set; } public bool ForgeWasViolent { get; set; } public bool CameraNearRecorded { get; set; } public string CameraNearHeatDue { get; set; } = ""; } public class FineRecordDto { public int VictimId { get; set; } = -1; public string VictimName { get; set; } = ""; public int Amount { get; set; } public int Paid { get; set; } public string Issued { get; set; } = ""; public string Reason { get; set; } = ""; } public class TrackedWeaponDto { public int WeaponId { get; set; } = -1; public int VictimId { get; set; } = -1; public string VictimName { get; set; } = ""; public string WeaponName { get; set; } = ""; public bool HadPlayerPrintAtKill { get; set; } } public class DeliveryDto { public int CaseId { get; set; } = -1; public List Manifest { get; set; } = new List(); public string ArriveAt { get; set; } = ""; public int Paid { get; set; } } public class HomeVacateDto { public int VictimId { get; set; } = -1; public long HomeLocKey { get; set; } public string HomeName { get; set; } = ""; public string DueAt { get; set; } = ""; public bool Applied { get; set; } } public class SyndicateData { public int SchemaVersion { get; set; } = 5; public int UnderworldRep { get; set; } public int LastRewardedLevel { get; set; } = -1; public int LastSeenLevel { get; set; } = -1; public int PlayerHeatScore { get; set; } [JsonConverter(typeof(TolerantSuspicionStateConverter))] public SuspicionState SuspicionState { get; set; } public bool ActiveWarrant { get; set; } public string WarrantExpires { get; set; } = ""; public bool InvestigationActive { get; set; } public string InvestigationExpires { get; set; } = ""; public bool BustedPending { get; set; } public bool RaidLaunched { get; set; } public bool StakeoutPosted { get; set; } public int StakeoutGuardId { get; set; } = -1; public int WarrantMurderCount { get; set; } public List WarrantSceneLocKeys { get; set; } = new List(); public bool IsWearingGloves { get; set; } public bool GlovesDiskInstalled { get; set; } public bool GlovesDiskDelivered { get; set; } public bool IsWearingMask { get; set; } public bool MaskDiskInstalled { get; set; } public bool MaskDiskDelivered { get; set; } public int FixerHumanId { get; set; } = -1; public int HitTokens { get; set; } public int HitTokensEarnedTotal { get; set; } public bool CruncherUnlockAnnounced { get; set; } public int NextContractSeq { get; set; } = 1; public string NextContractDueAt { get; set; } = ""; public List ActiveContracts { get; set; } = new List(); public List OfferBoard { get; set; } = new List(); public string BoardRefreshedAt { get; set; } = ""; public string LastPlayerBoardRefreshAt { get; set; } = ""; public List CrimeScenes { get; set; } = new List(); public List PendingHomeVacates { get; set; } = new List(); public List Prints { get; set; } = new List(); public List Fines { get; set; } = new List(); public List MurderWeapons { get; set; } = new List(); public bool RaidWeaponSweepDone { get; set; } public bool CruncherRaidCheckDone { get; set; } public bool ContractsPaused { get; set; } public bool SyndicateActivated { get; set; } public string ActivationBaselineAt { get; set; } = ""; public bool IntroVmailSent { get; set; } public bool ReminderCheckIn1Sent { get; set; } public bool ReminderCheckIn2Sent { get; set; } public bool FirstContractDelivered { get; set; } public bool TutCamerasShown { get; set; } public bool TutPostKillShown { get; set; } public bool TutMaskEquipShown { get; set; } public int LegacyLvlVmailCap { get; set; } = -1; public string LegacyJobsBodyFrozen { get; set; } = ""; public List PendingDeliveries { get; set; } = new List(); public Dictionary GunMagazines { get; set; } = new Dictionary(); public Dictionary BoxRounds { get; set; } = new Dictionary(); public Dictionary GunLoadedAmmo { get; set; } = new Dictionary(); public Dictionary PoisonDoses { get; set; } = new Dictionary(); public Dictionary FingerprintRemoverCharges { get; set; } = new Dictionary(); public Dictionary SedativeDoses { get; set; } = new Dictionary(); public HashSet ViolentVictims { get; set; } = new HashSet(); public HashSet FallUnreportable { get; set; } = new HashSet(); public List PendingPoisons { get; set; } = new List(); public float ResidualHeat { get; set; } public List ResidualHeatContributors { get; set; } = new List(); public List MoleMails { get; set; } = new List(); public HeistDto Heist { get; set; } = new HeistDto(); public int HeistCycleCounter { get; set; } public bool HeatPunishLatched { get; set; } public float MaskNotoriety { get; set; } public string MaskNotorietyDecayStamp { get; set; } = ""; public List MaskedIncidents { get; set; } = new List(); public bool MaskedBustPending { get; set; } public List NewsEvents { get; set; } = new List(); public string NewsBakedMain { get; set; } = ""; public string NewsBakedSecondary { get; set; } = ""; } public class NewsEventDto { public string Type { get; set; } = ""; public float GameTime { get; set; } = -1f; public int VictimId { get; set; } = -1; public string VictimName { get; set; } = ""; public string LocationName { get; set; } = ""; public string District { get; set; } = ""; public string Extra { get; set; } = ""; } public class HeistDto { public string Stage { get; set; } = "None"; public int OfferCycle { get; set; } public bool VmailSent { get; set; } public long TargetLocKey { get; set; } public string TargetLocName { get; set; } = ""; public string TargetKind { get; set; } = ""; public int FolderId { get; set; } = -1; public int CaseId { get; set; } = -1; public int OrphanFolderId { get; set; } = -1; public int PendingCloseCaseId { get; set; } = -1; } public class ResidualHeatContributionDto { public int VictimId { get; set; } = -1; public string VictimName { get; set; } = ""; public float Amount { get; set; } } public class MoleMailDto { public int VictimId { get; set; } = -1; public string Body { get; set; } = ""; } public class MaskedIncidentDto { public int VictimId { get; set; } = -1; public string VictimName { get; set; } = ""; public long LocKey { get; set; } public string LocationName { get; set; } = ""; public string At { get; set; } = ""; public string Channel { get; set; } = ""; public float NotorietyAdded { get; set; } public bool Merged { get; set; } } public class PendingPoisonDto { public int VictimId { get; set; } = -1; public string VictimName { get; set; } = ""; public string DueAt { get; set; } = ""; public int WeaponId { get; set; } = -1; public string ExpireAt { get; set; } = ""; public bool PrintedAtFeed { get; set; } public bool CleanKO { get; set; } = true; } internal static class SyndicateState { private const string FileName = "syndicate.json"; private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions { WriteIndented = true, Converters = { (JsonConverter)new TolerantSuspicionStateConverter() } }; private static bool _loadingSave; internal static bool? GlovesActiveOverride; public static SyndicateData Data { get; private set; } = new SyndicateData(); public static string LastSyncStatus { get; private set; } = "fresh (no save loaded)"; public static bool IsWorldLoading { get { try { if (_loadingSave) { return true; } if (!Lib.Time.IsInitialized) { return true; } } catch { return true; } return false; } } public static int Level { get { int underworldRep = Data.UnderworldRep; int num = SyndicateConfig.Level1Rep?.Value ?? 20; int num2 = SyndicateConfig.Level2Rep?.Value ?? 50; int num3 = SyndicateConfig.Level3Rep?.Value ?? 100; if (underworldRep >= num3) { return 3; } if (underworldRep >= num2) { return 2; } if (underworldRep >= num) { return 1; } return 0; } } public static int Tier => Math.Max(1, Level); public static bool GlovesActive => GlovesActiveOverride ?? Data.GlovesDiskInstalled; public static bool MaskActive { get { if (Data.MaskDiskInstalled) { return Data.IsWearingMask; } return false; } } public static void Hook() { Lib.SaveGame.OnBeforeSave += OnBeforeSave; Lib.SaveGame.OnBeforeLoad += OnBeforeLoad; Lib.SaveGame.OnAfterLoad += OnAfterLoad; Lib.SaveGame.OnAfterNewGame += OnAfterNewGame; Lib.SaveGame.OnAfterDelete += OnAfterDelete; } private static void OnBeforeSave(object sender, SaveGameArgs e) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown bool flag = default(bool); try { Data.CrimeScenes = CrimeSceneManager.CaptureDtos(); Data.Prints = PlayerEvidence.CaptureDtos(); string saveGameDataPath = Lib.SaveGame.GetSaveGameDataPath(e, "syndicate.json"); File.WriteAllText(saveGameDataPath, JsonSerializer.Serialize(Data, JsonOptions)); LastSyncStatus = $"saved {DateTime.Now:HH:mm:ss}"; ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Syndicate state saved to "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(saveGameDataPath); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to save Syndicate state: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger2.LogError(val2); } } private static void OnBeforeLoad(object sender, SaveGameArgs e) { _loadingSave = true; ResetSession(); } private static void OnAfterLoad(object sender, SaveGameArgs e) { //IL_0825: Unknown result type (might be due to invalid IL or missing references) //IL_082c: Expected O, but got Unknown //IL_0866: Unknown result type (might be due to invalid IL or missing references) //IL_086d: Expected O, but got Unknown //IL_08a7: Unknown result type (might be due to invalid IL or missing references) //IL_08ae: Expected O, but got Unknown //IL_08e8: Unknown result type (might be due to invalid IL or missing references) //IL_08ef: Expected O, but got Unknown //IL_0929: Unknown result type (might be due to invalid IL or missing references) //IL_0930: Expected O, but got Unknown //IL_09bf: Unknown result type (might be due to invalid IL or missing references) //IL_09c6: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Expected O, but got Unknown bool flag = default(bool); try { string saveGameDataPath = Lib.SaveGame.GetSaveGameDataPath(e, "syndicate.json"); if (File.Exists(saveGameDataPath)) { Data = JsonSerializer.Deserialize(File.ReadAllText(saveGameDataPath)) ?? new SyndicateData(); LastSyncStatus = $"loaded {DateTime.Now:HH:mm:ss}"; ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(72, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Syndicate state loaded from "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(saveGameDataPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (rep="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Data.UnderworldRep); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", heat="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Data.PlayerHeatScore); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", contracts="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Data.ActiveContracts.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", scenes="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Data.CrimeScenes.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", prints="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Data.Prints.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logger.LogInfo(val); if (Data.SchemaVersion < 4) { int schemaVersion = Data.SchemaVersion; int num = Data.ActiveContracts?.Count((ContractData c) => c.Status == "Completed") ?? 0; Data.HitTokens = num; Data.HitTokensEarnedTotal = num; Data.SchemaVersion = 4; ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(71, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[State] schema v"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(schemaVersion); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("->4: backfilled "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" hit token(s) from completed contracts."); } logger2.LogInfo(val); } if (Data.SchemaVersion < 5) { int num2 = 0; if (Data.ActiveContracts != null) { foreach (ContractData activeContract in Data.ActiveContracts) { if (activeContract != null && activeContract.Status == "Completed" && !activeContract.RewardGranted) { activeContract.RewardGranted = true; num2++; } } } Data.SchemaVersion = 5; ManualLogSource logger3 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(150, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[State] schema v4->5: latched RewardGranted on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" already-killed contract(s) so the kill->collect rep/token move never double-credits an in-flight save."); } logger3.LogInfo(val); } } else { Data = new SyndicateData(); LastSyncStatus = "no data for this save (fresh)"; Plugin.Logger.LogInfo((object)"No Syndicate state for this save; starting fresh."); } if (Data.LegacyLvlVmailCap == -1) { Data.LegacyLvlVmailCap = Math.Max(1, Data.LastRewardedLevel); } PlayerEvidence.RestoreFrom(Data.Prints); CrimeSceneManager.RestoreFrom(Data.CrimeScenes); try { if (Data.GunMagazines != null && Data.GunMagazines.Count > 0) { List list = new List(); foreach (int key in Data.GunMagazines.Keys) { if (key >= 0 && StableIds.ResolveInteractable(key) == null) { list.Add(key); } } foreach (int item in list) { Data.GunMagazines.Remove(item); Data.GunLoadedAmmo?.Remove(item); } if (list.Count > 0) { ManualLogSource logger4 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Firearms] pruned "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stale gun magazine id(s)."); } logger4.LogInfo(val); } } if (Data.BoxRounds != null && Data.BoxRounds.Count > 0) { List list2 = new List(); foreach (int key2 in Data.BoxRounds.Keys) { if (key2 >= 0 && StableIds.ResolveInteractable(key2) == null) { list2.Add(key2); } } foreach (int item2 in list2) { Data.BoxRounds.Remove(item2); } } if (Data.PoisonDoses != null && Data.PoisonDoses.Count > 0) { List list3 = new List(); foreach (int key3 in Data.PoisonDoses.Keys) { if (key3 >= 0 && StableIds.ResolveInteractable(key3) == null) { list3.Add(key3); } } foreach (int item3 in list3) { Data.PoisonDoses.Remove(item3); } } if (Data.FingerprintRemoverCharges != null && Data.FingerprintRemoverCharges.Count > 0) { List list4 = new List(); foreach (int key4 in Data.FingerprintRemoverCharges.Keys) { if (key4 >= 0 && StableIds.ResolveInteractable(key4) == null) { list4.Add(key4); } } foreach (int item4 in list4) { Data.FingerprintRemoverCharges.Remove(item4); } } if (Data.SedativeDoses != null && Data.SedativeDoses.Count > 0) { List list5 = new List(); foreach (int key5 in Data.SedativeDoses.Keys) { if (key5 >= 0 && StableIds.ResolveInteractable(key5) == null) { list5.Add(key5); } } foreach (int item5 in list5) { Data.SedativeDoses.Remove(item5); } } if (Data.ViolentVictims != null && Data.ViolentVictims.Count > 0) { List list6 = new List(); Human val2 = default(Human); foreach (int violentVictim in Data.ViolentVictims) { bool flag2 = false; try { flag2 = (Object)(object)CityData.Instance != (Object)null && CityData.Instance.GetHuman(violentVictim, ref val2, false) && (Object)(object)val2 != (Object)null && !((Actor)val2).isDead; } catch { } if (!flag2) { list6.Add(violentVictim); } } foreach (int item6 in list6) { Data.ViolentVictims.Remove(item6); } } } catch (Exception ex) { ManualLogSource logger5 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Firearms] magazine prune failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger5.LogWarning(val3); } try { PoisonScheduler.PruneOnLoad(); } catch (Exception ex2) { ManualLogSource logger6 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Poison] pending prune failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2.Message); } logger6.LogWarning(val3); } try { FallForge.RecoverUnreportableOnLoad(); } catch (Exception ex3) { ManualLogSource logger7 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] unreportable recovery failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex3.Message); } logger7.LogWarning(val3); } try { OnboardingController.ReconcileOnLoad(); } catch (Exception ex4) { ManualLogSource logger8 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Onboarding] load reconcile failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex4.Message); } logger8.LogWarning(val3); } try { ContractManager.MigrateNoViolenceOverdoseOnly(); } catch (Exception ex5) { ManualLogSource logger9 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Contracts] no-violence migration failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex5.Message); } logger9.LogWarning(val3); } if (string.IsNullOrEmpty(Data.LegacyJobsBodyFrozen)) { try { Data.LegacyJobsBodyFrozen = ContractDispatcher.BuildJobsBody(); } catch { } } try { Rewards.EnsureDdsRegistered(); } catch { } try { MoleMail.EnsureDdsRegistered(); } catch { } try { NewsEngine.OnLoaded(); } catch { } try { HomeVacateQueue.ReapplyOnLoad(); } catch { } } catch (Exception ex6) { Data = new SyndicateData(); ManualLogSource logger10 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Failed to load Syndicate state: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex6); } logger10.LogError(val4); } finally { _loadingSave = false; } } private static void OnAfterNewGame(object sender, EventArgs e) { _loadingSave = false; Data = new SyndicateData(); if (Data.LegacyLvlVmailCap == -1) { Data.LegacyLvlVmailCap = Math.Max(1, Data.LastRewardedLevel); } ResetSession(); LastSyncStatus = "new game (fresh)"; Plugin.Logger.LogInfo((object)"New game started; Syndicate state reset."); } private static void ResetSession() { PlayerEvidence.Clear(); CrimeSceneManager.Reset(); SyndicateKills.Victims.Clear(); PoisonScheduler.ResetSession(); FallForge.Reset(); CrippleController.ResetSession(); EvidenceHeist.ResetSession(); NewsEngine.ResetSession(); MaskNotoriety.ResetSession(); } private static void OnAfterDelete(object sender, SaveGameArgs e) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown try { string saveGameDataPath = Lib.SaveGame.GetSaveGameDataPath(e, "syndicate.json"); if (File.Exists(saveGameDataPath)) { File.Delete(saveGameDataPath); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to delete Syndicate state file: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } } namespace TheSyndicate.Progression { internal static class ProgressionManager { public static void Evaluate() { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown if (SyndicateState.IsWorldLoading) { return; } SyndicateData data = SyndicateState.Data; int level = SyndicateState.Level; if (data.LastRewardedLevel < 0) { data.LastRewardedLevel = level; data.LastSeenLevel = level; return; } if (data.LastSeenLevel < 0) { data.LastSeenLevel = level; } if (level > data.LastRewardedLevel) { for (int i = data.LastRewardedLevel + 1; i <= level; i++) { GrantLevelReward(i); } data.LastRewardedLevel = level; } else if (level > data.LastSeenLevel) { Notify($"Back in the Syndicate's good graces — Level {level}, {RankName(level)}."); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(83, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Progression] Re-crossed to Level "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(level); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (already earned — no reward, notification only)."); } logger.LogInfo(val); } data.LastSeenLevel = level; if (level >= 2) { Rewards.DeliverGlovesDiskOnce(); } if (level >= 1) { Rewards.DeliverMaskDiskOnce(); } if (level >= 3) { AnnounceCruncherUnlockOnce(); } } private static void GrantLevelReward(int level) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown int num = RewardMoney(level); string text = RankName(level); bool flag = default(bool); if (num > 0) { try { GameplayController.Instance.AddMoney(num, true, "Syndicate promotion"); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Progression] AddMoney failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(49, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Progression] LEVEL UP -> "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(level); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("). Reward: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("cr. (rep "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(SyndicateState.Data.UnderworldRep); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } logger2.LogInfo(val2); Notify((num > 0) ? $"The Syndicate has taken notice — you've risen to Level {level}, {text}. {num}cr deposited." : $"The Syndicate has taken notice — you've risen to Level {level}, {text}."); if (level == 1) { Rewards.DeliverMaskDiskOnce(); } if (level == 2) { Rewards.DeliverGlovesDiskOnce(); } Rewards.SendLevelVmail(level); if (level >= 3) { AnnounceCruncherUnlockOnce(); } } private static int RewardMoney(int level) { return level switch { 1 => SyndicateConfig.Level1Reward?.Value ?? 500, 2 => SyndicateConfig.Level2Reward?.Value ?? 1500, 3 => SyndicateConfig.Level3Reward?.Value ?? 4000, _ => 0, }; } internal static string RankName(int level) { return level switch { 1 => "Associate", 2 => "Operative", 3 => "Lieutenant", _ => "Recruit", }; } private static void AnnounceCruncherUnlockOnce() { SyndicateData data = SyndicateState.Data; if (!data.CruncherUnlockAnnounced) { data.CruncherUnlockAnnounced = true; Notify("The Syndicate's contract board is open to you now — browse and pick your own jobs from the Syndicate app on your home cruncher."); Plugin.LogVerbose("[Progression] L3 contract-board unlock announced (once per save)."); } } private static void Notify(string text) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { MessageQueue.Enqueue(text); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Progression] Notify failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } internal static class Rewards { internal const string GlovesDiskName = "Second Skin"; internal const string MaskDiskName = "False Face"; private const string BlockDict = "dds.blocks"; private const string TreeId = "syn_lvl_tree"; internal static SyncDisk GlovesDisk; internal static int GlovesEffectId = -1; internal static SyncDisk MaskDisk; internal static int MaskEffectId = -1; private static readonly string[] LevelVmailText = new string[4] { "", "Word travels — the people I answer to are calling you one of ours now. Payment's in your account, and there's a little something from our tailor waiting in your mailbox. Bond it at any sync clinic and pull it on before a job: witnesses will swear they saw a masked figure, never your face. Know its limit, though — it fools eyes, not evidence. Prints, weapons, and forensics still point straight back to you, so wear the mask and still work clean. A covered face draws eyes, too, so wear it working, not walking. Keep your mouth shut. — S", "You've earned a look at the good hardware. Check your mailbox — a little something else from our tailor. Bonds at any sync clinic. Wear it working, and the only prints they'll find are everyone else's. — S", "You run crews now, not errands. There's more work than hands, and the kind of work that pays. We'll talk on your terminal. — S" }; public static void Register() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown bool flag = default(bool); try { GlovesDisk = Lib.SyncDisks.Builder("Second Skin", "Kropath.TheSyndicate", true).AddEffect("Dermal Veil", "Microfilament dermal sheath — while worn, you leave no fingerprints.", ref GlovesEffectId, (string)null).SetManufacturer((Manufacturer)5) .SetRarity((Rarity)0) .SetPrice(2500) .SetWorldSpawnOption(false) .SetCanBeSideJobReward(false) .AddSaleLocation((SyncDiskSaleLocation[])(object)new SyncDiskSaleLocation[1] { (SyncDiskSaleLocation)23 }) .CreateAndRegister(); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(59, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] 'Second Skin' gloves disk registered (effectId="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GlovesEffectId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Rewards] gloves-disk registration FAILED: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger2.LogError(val2); } try { MaskDisk = Lib.SyncDisks.Builder("False Face", "Kropath.TheSyndicate", true).AddEffect("Blank Mask", "Projected identity veil — while worn, witnesses can describe a masked figure but never your face.", ref MaskEffectId, (string)null).SetManufacturer((Manufacturer)5) .SetRarity((Rarity)0) .SetPrice(3000) .SetWorldSpawnOption(false) .SetCanBeSideJobReward(false) .AddSaleLocation((SyncDiskSaleLocation[])(object)new SyncDiskSaleLocation[1] { (SyncDiskSaleLocation)23 }) .CreateAndRegister(); ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(56, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] 'False Face' mask disk registered (effectId="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(MaskEffectId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger3.LogInfo(val); } catch (Exception ex2) { ManualLogSource logger4 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Rewards] mask-disk registration FAILED: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2); } logger4.LogError(val2); } try { Lib.SyncDisks.OnAfterSyncDiskInstalled += OnGlovesInstalled; Lib.SyncDisks.OnAfterSyncDiskUninstalled += OnGlovesUninstalled; Lib.SyncDisks.OnAfterSyncDiskInstalled += OnMaskInstalled; Lib.SyncDisks.OnAfterSyncDiskUninstalled += OnMaskUninstalled; Lib.SaveGame.OnAfterLoad += OnGameLoaded; Lib.SaveGame.OnAfterNewGame += OnNewGame; Plugin.Logger.LogInfo((object)"[Rewards] event handlers subscribed."); } catch (Exception ex3) { ManualLogSource logger5 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Rewards] event subscription FAILED: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex3); } logger5.LogError(val2); } } private static void OnGameLoaded(object sender, SaveGameArgs e) { EnsureDdsRegistered(); } private static void OnNewGame(object sender, EventArgs e) { EnsureDdsRegistered(); } private static void OnGlovesInstalled(object sender, SyncDiskArgs args) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown bool flag2 = default(bool); try { object obj; if (args == null) { obj = null; } else { SyncDisk syncDisk = args.SyncDisk; obj = ((syncDisk != null) ? syncDisk.Name : null); } if (!((string?)obj != "Second Skin")) { SyndicateData data = SyndicateState.Data; bool flag = !data.GlovesDiskInstalled; data.GlovesDiskInstalled = true; if (flag && !SyndicateState.IsWorldLoading) { data.IsWearingGloves = true; Lib.GameMessage.Broadcast("Second Skin bonded. You leave no prints while it's worn.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(54, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] Second Skin INSTALLED (firstArm="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", loading="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateState.IsWorldLoading); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Rewards] install handler failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static void OnGlovesUninstalled(object sender, SyncDiskArgs args) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown try { object obj; if (args == null) { obj = null; } else { SyncDisk syncDisk = args.SyncDisk; obj = ((syncDisk != null) ? syncDisk.Name : null); } if (!((string?)obj != "Second Skin")) { SyndicateState.Data.GlovesDiskInstalled = false; Plugin.Logger.LogInfo((object)"[Rewards] Second Skin UNINSTALLED — fingerprint suppression off."); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] uninstall handler failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void OnMaskInstalled(object sender, SyncDiskArgs args) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) bool flag2 = default(bool); try { object obj; if (args == null) { obj = null; } else { SyncDisk syncDisk = args.SyncDisk; obj = ((syncDisk != null) ? syncDisk.Name : null); } if (!((string?)obj != "False Face")) { SyndicateData data = SyndicateState.Data; bool flag = !data.MaskDiskInstalled; data.MaskDiskInstalled = true; if (flag && !SyndicateState.IsWorldLoading) { ConfigEntry maskToggleKey = SyndicateConfig.MaskToggleKey; KeyCode val = (KeyCode)((maskToggleKey == null) ? 110 : ((int)maskToggleKey.Value)); Lib.GameMessage.Broadcast(((int)val != 0) ? $"False Face bonded — press {val} to pull it on before a job. Witnesses can't name you while it's worn, but a masked face draws eyes." : "False Face bonded — toggle it on before a job. Witnesses can't name you while it's worn, but a masked face draws eyes.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(53, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Rewards] False Face INSTALLED (firstArm="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", loading="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(SyndicateState.IsWorldLoading); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } logger.LogInfo(val2); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Rewards] mask install handler failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } private static void OnMaskUninstalled(object sender, SyncDiskArgs args) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown try { object obj; if (args == null) { obj = null; } else { SyncDisk syncDisk = args.SyncDisk; obj = ((syncDisk != null) ? syncDisk.Name : null); } if (!((string?)obj != "False Face")) { SyndicateState.Data.MaskDiskInstalled = false; Plugin.Logger.LogInfo((object)"[Rewards] False Face UNINSTALLED — witness identity-block off."); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] mask uninstall handler failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static void EnsureDdsRegistered() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown try { Toolbox instance = Toolbox.Instance; if ((Object)(object)instance == (Object)null || instance.allDDSTrees == null) { return; } for (int i = 1; i <= 3; i++) { bool flag = false; try { flag = instance.allDDSTrees.ContainsKey($"syn_lvl_tree_{i}"); } catch { } if (!flag) { RegisterLevelTree(instance, i); } } bool flag2 = false; try { flag2 = instance.allDDSTrees.ContainsKey("syn_lvl_tree"); } catch { } if (!flag2) { RegisterSyndicateTree(instance); } else { try { Lib.DdsStrings.AddOrUpdate("dds.blocks", "syn_lvl_congrats", BuildAccumulatedText(FrozenLegacyLevel())); } catch { } } ContractDispatcher.EnsureJobsDdsRegistered(); EvidenceHeist.EnsureDdsRegistered(); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag3 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] EnsureDdsRegistered failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void RegisterSyndicateTree(Toolbox tb) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown DDSBlockSave val = new DDSBlockSave { id = "syn_lvl_congrats", name = "syn_lvl_congrats" }; DDSMessageSave val2 = new DDSMessageSave { id = "syn_lvl_congrats_msg", name = "syn_lvl_congrats_msg" }; val2.AddBlock("syn_lvl_congrats"); try { val2.blocks[0].alwaysDisplay = true; } catch { } DDSTreeSave val3 = new DDSTreeSave { id = "syn_lvl_tree", name = "syn_lvl_tree" }; val3.treeType = (TreeType)1; val3.triggerPoint = (TriggerPoint)5; val3.participantA = new DDSParticipant(); val3.participantB = new DDSParticipant(); val3.participantC = new DDSParticipant(); val3.participantD = new DDSParticipant(); val3.AddMessage("syn_lvl_congrats_msg"); DDSMessageSettings val4 = val3.messages[0]; val4.instanceID = "syn_lvl_inst_1"; try { val4.saidBy = 0; val4.saidTo = 1; } catch { } val3.startingMessage = "syn_lvl_inst_1"; val3.messageRef = new Dictionary(); val3.messageRef.Add("syn_lvl_inst_1", val4); tb.allDDSBlocks["syn_lvl_congrats"] = val; tb.allDDSMessages["syn_lvl_congrats_msg"] = val2; tb.allDDSTrees["syn_lvl_tree"] = val3; Lib.DdsStrings.AddOrUpdate("dds.blocks", "syn_lvl_congrats", BuildAccumulatedText(FrozenLegacyLevel())); } private static string BuildAccumulatedText(int maxLevel) { if (maxLevel < 1) { maxLevel = 1; } if (maxLevel > 3) { maxLevel = 3; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 1; i <= maxLevel; i++) { if (i > 1) { stringBuilder.Append("\n\n— — — — —\n\n"); } stringBuilder.Append(LevelVmailText[i]); } return stringBuilder.ToString(); } private static int HighestVmailLevel() { int num = SyndicateState.Data.LastRewardedLevel; if (num < 1) { num = 1; } if (num > 3) { num = 3; } return num; } private static int FrozenLegacyLevel() { int legacyLvlVmailCap = SyndicateState.Data.LegacyLvlVmailCap; if (legacyLvlVmailCap < 1) { return HighestVmailLevel(); } return Math.Min(legacyLvlVmailCap, 3); } private static void RegisterLevelTree(Toolbox tb, int level) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown string text = $"syn_lvl_block_{level}"; string text2 = $"syn_lvl_msg_{level}"; string text3 = $"syn_lvl_tree_{level}"; DDSBlockSave val = new DDSBlockSave { id = text, name = text }; DDSMessageSave val2 = new DDSMessageSave { id = text2, name = text2 }; val2.AddBlock(text); try { val2.blocks[0].alwaysDisplay = true; } catch { } DDSTreeSave val3 = new DDSTreeSave { id = text3, name = text3 }; val3.treeType = (TreeType)1; val3.triggerPoint = (TriggerPoint)5; val3.participantA = new DDSParticipant(); val3.participantB = new DDSParticipant(); val3.participantC = new DDSParticipant(); val3.participantD = new DDSParticipant(); string text4 = $"syn_lvl_inst_{level}"; val3.AddMessage(text2); DDSMessageSettings val4 = val3.messages[0]; val4.instanceID = text4; try { val4.saidBy = 0; val4.saidTo = 1; } catch { } val3.startingMessage = text4; val3.messageRef = new Dictionary(); val3.messageRef.Add(text4, val4); tb.allDDSBlocks[text] = val; tb.allDDSMessages[text2] = val2; tb.allDDSTrees[text3] = val3; Lib.DdsStrings.AddOrUpdate("dds.blocks", text, LevelVmailText[level]); } internal static void SendLevelVmail(int level) { //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown bool flag = default(bool); try { if (level < 1 || level > 3) { return; } EnsureDdsRegistered(); Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } Human val = ResolveFixer(); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogWarning((object)"[Rewards] SendLevelVmail: no fixer resolved."); return; } float num = (((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.gameTime : 0f); string text = $"syn_lvl_tree_{level}"; MessageThreadSave val2 = FindThreadByTree(text); if (val2 == null) { val2 = Toolbox.Instance.NewVmailThread(val, (Human)(object)instance, (Human)null, (Human)null, (List)null, text, num, 1, (CustomDataSource)0, -1); } if (val2 == null) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(66, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Rewards] SendLevelVmail: could not create/find the level-"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(level); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" thread."); } logger.LogWarning(val3); return; } try { val2.time = num; } catch { } Lib.GameMessage.Broadcast("New v-mail received — check a cruncher.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(59, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Rewards] Level-"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(level); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" v-mail sent (treeId="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", threadID="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(val2.threadID); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", fixer=#"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(val.humanID); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")."); } logger2.LogInfo(val4); } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Rewards] SendLevelVmail failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger3.LogWarning(val3); } } internal static MessageThreadSave FindThreadByTree(string treeId) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.messageThreads == null || string.IsNullOrEmpty(treeId)) { return null; } Enumerator enumerator = instance.messageThreads.Values.GetEnumerator(); while (enumerator.MoveNext()) { MessageThreadSave current = enumerator.Current; if (current != null && current.treeID == treeId) { return current; } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] FindThreadByTree failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } return null; } public static void ClearSyndicateVmails() { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown bool flag = default(bool); try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.messageThreads == null) { Plugin.Logger.LogWarning((object)"[Rewards] ClearSyndicateVmails: no messageThreads."); return; } List list = new List(); Enumerator enumerator = instance.messageThreads.Values.GetEnumerator(); while (enumerator.MoveNext()) { MessageThreadSave current = enumerator.Current; if (current != null) { string text = null; try { text = current.treeID; } catch { } if (text != null && (text == "syn_lvl_tree" || text.StartsWith("syn_lvl_tree") || text.StartsWith("syn_job_tree") || text == "syn_jobs_tree")) { list.Add(current.threadID); } } } foreach (int item in list) { try { instance.messageThreads.Remove(item); } catch { } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(93, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Rewards] Cleared "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Syndicate v-mail thread(s). Next level-up / contract starts fresh threads."); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Rewards] ClearSyndicateVmails failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } internal static Human ResolveFixer() { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown bool flag = default(bool); try { CityData instance = CityData.Instance; Player instance2 = Player.Instance; if ((Object)(object)instance == (Object)null || instance.citizenDirectory == null || (Object)(object)instance2 == (Object)null) { return null; } SyndicateData data = SyndicateState.Data; List citizenDirectory = instance.citizenDirectory; if (data.FixerHumanId >= 0) { for (int i = 0; i < citizenDirectory.Count; i++) { Citizen val = citizenDirectory[i]; if ((Object)(object)val != (Object)null && ((Human)val).humanID == data.FixerHumanId && !((Actor)val).isDead) { return (Human)(object)val; } } } int humanID = ((Human)instance2).humanID; for (int j = 0; j < citizenDirectory.Count; j++) { Citizen val2 = citizenDirectory[j]; if (!((Object)(object)val2 == (Object)null) && !((Actor)val2).isDead && ((Human)val2).humanID != humanID) { data.FixerHumanId = ((Human)val2).humanID; ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(25, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Rewards] fixer = "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Actor((Human)(object)val2)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (id "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Human)val2).humanID); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")."); } logger.LogInfo(val3); return (Human)(object)val2; } } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Rewards] ResolveFixer failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); } return null; } public static void DeliverGlovesDiskOnce() { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = SyndicateState.Data; if (data.GlovesDiskDelivered || SyndicateState.IsWorldLoading) { return; } SyncDisk glovesDisk = GlovesDisk; object obj; if (glovesDisk == null) { obj = null; } else { SyncDiskPreset preset = glovesDisk.Preset; obj = ((preset != null) ? preset.interactable : null); } if ((SoCustomComparison)obj == (SoCustomComparison)null) { return; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } InteractablePreset interactable = GlovesDisk.Preset.interactable; Human val = ResolveFixer(); Interactable val2 = null; Interactable mailbox = Toolbox.Instance.GetMailbox((Human)(object)instance); if (mailbox != null) { if (mailbox.locked) { try { mailbox.SetLockedState(false, (Actor)null, false, true); } catch { } } Vector3 val3 = mailbox.wPos + Quaternion.Euler(mailbox.wEuler) * new Vector3(0.1f, 0f, -0.15f); try { val2 = InteractableCreator.Instance.CreateWorldInteractable(interactable, (Human)(object)instance, val, (Human)(object)instance, val3, mailbox.wEuler, (List)null, (Object)null, ""); } catch { try { val2 = InteractableCreator.Instance.CreateFurnitureSpawnedInteractable(interactable, mailbox.furnitureParent, (SubObject)null, (Human)(object)instance, val, (Human)(object)instance, (List)null, (LightingPreset)null, (Object)null, ""); } catch { } } } if (val2 == null) { try { val2 = InteractableCreator.Instance.CreateWorldInteractable(interactable, (Human)(object)instance, val, (Human)(object)instance, ((Component)instance).transform.position + ((Component)instance).transform.forward * 0.6f, Vector3.zero, (List)null, (Object)null, ""); } catch { } } if (val2 == null) { Plugin.Logger.LogWarning((object)"[Rewards] gloves-disk delivery failed everywhere — will retry."); return; } try { val2.syncDisk = GlovesDisk.Preset; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(60, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Rewards] delivery stamp failed — not latching, will retry: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger.LogWarning(val4); return; } data.GlovesDiskDelivered = true; Lib.GameMessage.Broadcast("A package was delivered to your mailbox.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Rewards] Second Skin delivered (interId="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(val2.id); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(")."); } logger2.LogInfo(val5); } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Rewards] DeliverGlovesDiskOnce failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex2.Message); } logger3.LogWarning(val4); } } public static void DeliverMaskDiskOnce() { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = SyndicateState.Data; if (data.MaskDiskDelivered || SyndicateState.IsWorldLoading) { return; } SyncDisk maskDisk = MaskDisk; object obj; if (maskDisk == null) { obj = null; } else { SyncDiskPreset preset = maskDisk.Preset; obj = ((preset != null) ? preset.interactable : null); } if ((SoCustomComparison)obj == (SoCustomComparison)null) { return; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } InteractablePreset interactable = MaskDisk.Preset.interactable; Human val = ResolveFixer(); Interactable val2 = null; Interactable mailbox = Toolbox.Instance.GetMailbox((Human)(object)instance); if (mailbox != null) { if (mailbox.locked) { try { mailbox.SetLockedState(false, (Actor)null, false, true); } catch { } } Vector3 val3 = mailbox.wPos + Quaternion.Euler(mailbox.wEuler) * new Vector3(0.1f, 0f, -0.15f); try { val2 = InteractableCreator.Instance.CreateWorldInteractable(interactable, (Human)(object)instance, val, (Human)(object)instance, val3, mailbox.wEuler, (List)null, (Object)null, ""); } catch { try { val2 = InteractableCreator.Instance.CreateFurnitureSpawnedInteractable(interactable, mailbox.furnitureParent, (SubObject)null, (Human)(object)instance, val, (Human)(object)instance, (List)null, (LightingPreset)null, (Object)null, ""); } catch { } } } if (val2 == null) { try { val2 = InteractableCreator.Instance.CreateWorldInteractable(interactable, (Human)(object)instance, val, (Human)(object)instance, ((Component)instance).transform.position + ((Component)instance).transform.forward * 0.6f, Vector3.zero, (List)null, (Object)null, ""); } catch { } } if (val2 == null) { Plugin.Logger.LogWarning((object)"[Rewards] mask-disk delivery failed everywhere — will retry."); return; } try { val2.syncDisk = MaskDisk.Preset; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(65, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Rewards] mask delivery stamp failed — not latching, will retry: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger.LogWarning(val4); return; } data.MaskDiskDelivered = true; Lib.GameMessage.Broadcast("A package was delivered to your mailbox.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Rewards] False Face delivered (interId="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(val2.id); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(")."); } logger2.LogInfo(val5); } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Rewards] DeliverMaskDiskOnce failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex2.Message); } logger3.LogWarning(val4); } } } internal static class StandingStore { public static bool CanBuy(out string reason) { if (SyndicateState.Level < 1) { reason = "You're nobody yet — reach Syndicate Level 1."; return false; } if (SyndicateState.Data.HitTokens < 1) { reason = "No hit tokens — complete a contract first."; return false; } int num = Math.Max(0, SyndicateConfig.SocialCreditPurchaseMoneyCost?.Value ?? 500); GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null) { reason = "Not ready."; return false; } if (instance.money < num) { reason = $"You need {num}cr on hand."; return false; } reason = null; return true; } public static bool TryBuyStanding() { //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; GameplayController instance = GameplayController.Instance; int num = Math.Max(0, SyndicateConfig.SocialCreditPurchaseMoneyCost?.Value ?? 500); int num2 = Math.Max(0, SyndicateConfig.SocialCreditPerToken?.Value ?? 350); bool flag = false; bool flag2 = false; bool flag3 = default(bool); try { if (!CanBuy(out var reason)) { Notify(reason); return false; } data.HitTokens--; flag = true; instance.AddMoney(-num, true, "Syndicate: standing purchase"); flag2 = true; instance.AddSocialCredit(num2, true, "Syndicate connections"); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(87, 6, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Standing] Bought standing: -1 token (now "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.HitTokens); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), -"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr, +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" social credit "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(SC="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.socialCredit); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", level="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.GetCurrentSocialCreditLevel()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", next@"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.GetNextSocialCreditLevelThreshold()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogInfo(val); return true; } catch (Exception ex) { if (flag) { data.HitTokens++; } bool flag4 = true; if (flag2) { try { instance.AddMoney(num, false, "Syndicate: refund"); } catch { flag4 = false; } } if (flag4) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(48, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Standing] purchase failed — rolled back token"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag2 ? " + money" : ""); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); Notify("The deal fell through — you keep your token and money."); } else { ManualLogSource logger3 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(78, 3, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Standing] purchase failed AND the "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("cr refund also failed — player is owed "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("cr: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger3.LogError(val3); Notify($"Something went wrong — your hit token is back, but the {num}cr refund didn't go through."); } return false; } } private static void Notify(string text) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { MessageQueue.Enqueue(text); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Standing] Notify failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } } namespace TheSyndicate.Poison { internal static class ChloroformController { private static float _nextUse; internal const string SedatePromptText = "Sedate"; private static float _promptCacheAt = -999f; private static bool _promptCache; internal static string Preset => SyndicateConfig.ChloroformPreset?.Value ?? "Sleeping Pills"; internal static bool IsHolding(out Interactable held) { held = null; try { Interactable equippedInteractableCached = KillSwitchPatch.GetEquippedInteractableCached(); if (equippedInteractableCached != null && (SoCustomComparison)(object)equippedInteractableCached.preset != (SoCustomComparison)null && ((Object)equippedInteractableCached.preset).name == Preset) { held = equippedInteractableCached; return true; } } catch { } return false; } internal static bool IsHolding() { Interactable held; return IsHolding(out held); } internal static bool PromptShouldOverride() { try { ConfigEntry chloroformEnabled = SyndicateConfig.ChloroformEnabled; if (chloroformEnabled != null && !chloroformEnabled.Value) { return false; } ConfigEntry sedatePromptOverride = SyndicateConfig.SedatePromptOverride; if (sedatePromptOverride != null && !sedatePromptOverride.Value) { return false; } if (!IsHolding(out var held)) { return false; } if (Time.unscaledTime - _promptCacheAt < 0.15f) { return _promptCache; } _promptCacheAt = Time.unscaledTime; _promptCache = CanSedateNow(held); return _promptCache; } catch { return false; } } private static bool CanSedateNow(Interactable held) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) try { if (SedativeDoses.Get(held) <= 0) { return false; } CameraController instance = CameraController.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.cam == (Object)null) { return false; } float num = Mathf.Max(0.5f, SyndicateConfig.ChloroformRange?.Value ?? 2f); if (FirearmsController.ShouldYieldToWorldInteraction(num)) { return false; } Transform transform = ((Component)instance.cam).transform; RaycastHit val = default(RaycastHit); if (!Physics.Raycast(transform.position, transform.forward, ref val, num, Toolbox.Instance.physicalObjectsLayerMask)) { return false; } Actor val2 = ((Component)((RaycastHit)(ref val)).transform).gameObject.GetComponent() ?? ((Component)((RaycastHit)(ref val)).transform).gameObject.GetComponentInParent(); if ((Object)(object)val2 == (Object)null || val2.isPlayer) { return false; } Citizen val3 = ((Il2CppObjectBase)val2).TryCast(); if ((Object)(object)val3 == (Object)null || ((Actor)val3).isDead || (Object)(object)((Actor)val3).ai == (Object)null || ((Actor)val3).ai.ko) { return false; } if (ProtectedCitizens.IsProtected((Human)(object)val3)) { return false; } if (!IsAsleep(val3) && !IsBehind(val3)) { return false; } if (SeenByOthers(val3)) { return false; } return true; } catch { return false; } } internal static bool Use() { //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { ConfigEntry chloroformEnabled = SyndicateConfig.ChloroformEnabled; if (chloroformEnabled != null && !chloroformEnabled.Value) { return false; } if (!IsHolding(out var held)) { return false; } if (Time.time < _nextUse) { return true; } _nextUse = Time.time + 0.6f; CameraController instance = CameraController.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.cam == (Object)null) { return true; } float num = Mathf.Max(0.5f, SyndicateConfig.ChloroformRange?.Value ?? 2f); if (FirearmsController.ShouldYieldToWorldInteraction(num)) { return false; } if (SedativeDoses.Get(held) <= 0) { Toast("The pack's empty — no doses left."); return true; } Transform transform = ((Component)instance.cam).transform; Citizen val = null; RaycastHit val2 = default(RaycastHit); try { if (Physics.Raycast(transform.position, transform.forward, ref val2, num, Toolbox.Instance.physicalObjectsLayerMask)) { Actor val3 = ((Component)((RaycastHit)(ref val2)).transform).gameObject.GetComponent() ?? ((Component)((RaycastHit)(ref val2)).transform).gameObject.GetComponentInParent(); if ((Object)(object)val3 != (Object)null && !val3.isPlayer) { val = ((Il2CppObjectBase)val3).TryCast(); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Sedative] aim raycast failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger.LogWarning(val4); } if ((Object)(object)val == (Object)null || ((Actor)val).isDead || (Object)(object)((Actor)val).ai == (Object)null) { Toast("No one in reach."); return true; } if (((Actor)val).ai.ko) { Toast("They're already out."); return true; } if (ProtectedCitizens.IsProtected((Human)(object)val)) { ProtectedCitizens.DegradeToKO(val); Toast("Down — but that one's off-limits for the real work."); return true; } if (!IsAsleep(val) && !IsBehind(val)) { Toast("Get behind them first — they can't see it coming."); return true; } if (SeenByOthers(val)) { Toast("Too many eyes on you — wait for a clear moment."); return true; } try { ((Actor)val).ai.SetKO(true, ((RaycastHit)(ref val2)).point, transform.forward, false, 0f, true, 1f); } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Sedative] SetKO failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex2.Message); } logger2.LogWarning(val4); return true; } SedativeDoses.Spend(held); int num2 = SedativeDoses.Get(held); Lib.GameMessage.Broadcast("Out cold — and not a mark on them.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(58, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Sedative] Stealth-sedated "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(Redact.Actor((Human)(object)val)); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(((Human)val).humanID); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(") — clean KO, "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" dose(s) left."); } logger3.LogInfo(val5); return true; } catch (Exception ex3) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(23, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Sedative] Use failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex3.Message); } logger4.LogWarning(val4); return true; } } private static bool IsAsleep(Citizen victim) { try { return (Object)(object)victim != (Object)null && ((Actor)victim).isAsleep; } catch { return false; } } private static bool IsBehind(Citizen victim) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return false; } Vector3 forward = ((Component)victim).transform.forward; forward.y = 0f; Vector3 val = ((Component)instance).transform.position - ((Component)victim).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f || ((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { return true; } return Vector3.Dot(((Vector3)(ref forward)).normalized, ((Vector3)(ref val)).normalized) <= (SyndicateConfig.ChloroformBehindDot?.Value ?? (-0.25f)); } catch { return false; } } private static bool SeenByOthers(Citizen victim) { try { NewRoom currentRoom = ((Actor)victim).currentRoom; HashSet val = (((Object)(object)currentRoom != (Object)null) ? currentRoom.currentOccupants : null); if (val == null) { return false; } Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Actor current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !current.isPlayer && !current.isDead && !(((Il2CppObjectBase)current).Pointer == ((Il2CppObjectBase)victim).Pointer) && CrimeSceneManager.SeesPlayer(current)) { return true; } } return false; } catch { return false; } } private static void Toast(string s) { try { Lib.GameMessage.Broadcast(s, (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } private static string SafeName(Citizen c) { try { return ((Human)c).GetCitizenName(); } catch { return "target"; } } } internal static class CleanKOTracker { internal static void MarkViolent(int humanID) { try { (SyndicateState.Data?.ViolentVictims)?.Add(humanID); } catch { } } internal static bool WasViolent(int humanID) { try { return (SyndicateState.Data?.ViolentVictims)?.Contains(humanID) ?? false; } catch { return false; } } } internal static class FallForge { private sealed class Track { public bool Dragging; public float HeldY; public float HeldTime; public bool InFlight; public float ReleaseY; public float ReleaseTime; public float LastY; public float LastTime; public bool SawFreeFall; public bool Killed; public int SettleCount; public float KilledSince; public int Nudges; } private const float MinFreeFallSpeed = 5f; private const float MaxWatchSeconds = 4f; private const float SettleSpeed = 0.4f; private const int SettlePollsNeeded = 2; private const float MaxLandingSeconds = 5f; private const float StallSpeed = 1.2f; private const float GroundProbe = 1.6f; private const int MaxNudges = 8; private const int RagdollLayer = 24; private static readonly Dictionary _tracks = new Dictionary(); private static float _next; internal static void Reset() { _tracks.Clear(); } internal static void Tick() { //IL_0582: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Expected O, but got Unknown try { if (Time.time < _next) { return; } _next = Time.time + 0.3f; if (SyndicateState.IsWorldLoading) { return; } ConfigEntry fallKillsEnabled = SyndicateConfig.FallKillsEnabled; if (fallKillsEnabled != null && !fallKillsEnabled.Value) { if (_tracks.Count > 0) { _tracks.Clear(); } ReleaseAllUnreportable("fall kills disabled"); return; } bool sceneAtLanding = SyndicateConfig.FallSceneAtLanding?.Value ?? true; bool flag = SyndicateConfig.FallAntiSnagEnabled?.Value ?? true; InteractionController instance = InteractionController.Instance; RigidbodyDragObject val = (((Object)(object)instance != (Object)null) ? instance.currentlyDragging : null); Human val2 = null; try { val2 = (((Object)(object)val != (Object)null && (Object)(object)val.ai != (Object)null) ? val.ai.human : null); } catch { } int num = (((Object)(object)val2 != (Object)null) ? val2.humanID : (-1)); if ((Object)(object)val2 != (Object)null && !((Actor)val2).isDead) { Track orAdd = GetOrAdd(num); if (!orAdd.Killed) { float num2 = BodyY(val2); if (!float.IsNaN(num2)) { orAdd.HeldY = num2; orAdd.HeldTime = Time.time; } orAdd.Dragging = true; orAdd.InFlight = false; } } float num3 = Math.Max(1f, SyndicateConfig.LethalFallHeight?.Value ?? 6f); List list = null; foreach (KeyValuePair track in _tracks) { int key = track.Key; Track value = track.Value; if (value.Dragging && key != num && !value.Killed) { value.Dragging = false; value.ReleaseY = value.HeldY; value.LastY = value.HeldY; value.LastTime = value.HeldTime; value.ReleaseTime = Time.time; value.SawFreeFall = false; value.InFlight = true; } if (!value.InFlight) { continue; } Human val3 = ResolveHuman(key); if ((Object)(object)val3 == (Object)null) { ClearFallUnreportable(key, null); (list ?? (list = new List())).Add(key); continue; } float time = Time.time; if (value.Killed) { if (!((Actor)val3).isDead) { ClearFallUnreportable(key, val3); (list ?? (list = new List())).Add(key); continue; } if (key == num) { value.SettleCount = 0; continue; } float num4 = BodyY(val3); if (!float.IsNaN(num4)) { float num5 = Math.Max(0.05f, time - value.LastTime); float value2 = (value.LastY - num4) / num5; value.LastY = num4; value.LastTime = time; bool flag2 = NearGround(val3); if (Math.Abs(value2) < 0.4f && flag2) { value.SettleCount++; } else { value.SettleCount = 0; } if (flag && Math.Abs(value2) < 1.2f && !flag2) { TryDislodge(val3, value); } if (value.SettleCount >= 2) { FinalizeCorpse(key, sceneAtLanding); (list ?? (list = new List())).Add(key); continue; } } if (time - value.KilledSince > 5f) { FinalizeCorpse(key, sceneAtLanding); (list ?? (list = new List())).Add(key); } continue; } NewAIController ai = ((Actor)val3).ai; if ((Object)(object)ai != (Object)null && !ai.ko && !ai.isRagdoll) { (list ?? (list = new List())).Add(key); continue; } if (((Actor)val3).isDead) { (list ?? (list = new List())).Add(key); continue; } float num6 = BodyY(val3); if (!float.IsNaN(num6)) { float num7 = Math.Max(0.05f, time - value.LastTime); float num8 = (value.LastY - num6) / num7; if (num8 >= 5f) { value.SawFreeFall = true; } else if (flag && value.SawFreeFall && num8 < 1.2f && !NearGround(val3)) { TryDislodge(val3, value); } value.LastY = num6; value.LastTime = time; if (value.SawFreeFall && value.ReleaseY - num6 >= num3) { DoFallKill(key); Human val4 = ResolveHuman(key); if ((Object)(object)val4 != (Object)null && ((Actor)val4).isDead) { value.Killed = true; value.KilledSince = time; value.SettleCount = 0; value.LastY = num6; value.LastTime = time; } else { (list ?? (list = new List())).Add(key); } continue; } } if (time - value.ReleaseTime > 4f) { (list ?? (list = new List())).Add(key); } } if (list == null) { return; } foreach (int item in list) { _tracks.Remove(item); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag3 = default(bool); BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Fall] Tick failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger.LogWarning(val5); } } private static void DoFallKill(int id) { //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown bool flag = default(bool); try { Human val = ResolveHuman(id); Citizen val2 = (((Object)(object)val != (Object)null) ? ((Il2CppObjectBase)val).TryCast() : null); if ((Object)(object)val2 == (Object)null || ((Actor)val2).isDead) { return; } Interactable interactable = ((Actor)val2).interactable; PoisonController.SetKillMethod(id, "fallForge"); bool? glovesActiveOverride = SyndicateState.GlovesActiveOverride; SyndicateState.GlovesActiveOverride = true; try { KillSwitchPatch.ApplyLethal(val2, (Human)(object)Player.Instance, interactable); } finally { SyndicateState.GlovesActiveOverride = glovesActiveOverride; PoisonController.ClearKillMethod(id); } if (((Actor)val2).isDead) { MarkFallUnreportable(val2); try { CrimeSceneManager.SetForgedFall(id); } catch { } try { ContractManager.ResolveForgeViolence(id, !CleanKOTracker.WasViolent(id)); } catch { } try { Lib.GameMessage.Broadcast("They went over the edge. It'll read as a fall.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(103, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] Forged fall kill: #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Actor((Human)(object)val2)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("). A clean case reads as an accidental fall; an identified one is a murder."); } logger.LogInfo(val3); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(28, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Fall] DoFallKill #"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); } } private static void FinalizeCorpse(int id, bool sceneAtLanding) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown Human val = null; bool flag = default(bool); try { val = ResolveHuman(id); if ((Object)(object)val == (Object)null) { return; } NewNode val2 = null; try { val2 = ((Actor)val).currentNode; } catch { } try { ((Actor)val).UpdateGameLocation(0f, true); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] UpdateGameLocation #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); } try { Death death = val.death; NewNode currentNode = ((Actor)val).currentNode; if (death != null && currentNode != null) { death.UpdateDeathLocation(currentNode); if (val2 != null && ((Il2CppObjectBase)currentNode).Pointer == ((Il2CppObjectBase)val2).Pointer) { ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(127, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Fall] #"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": settled node == kill node — no resolvable node at the landing; enforcer dispatch may still read the kill-floor coord."); } logger2.LogInfo(val4); } } } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] UpdateDeathLocation #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2.Message); } logger3.LogWarning(val3); } if (!sceneAtLanding) { return; } try { NewGameLocation currentGameLocation = ((Actor)val).currentGameLocation; if ((Object)(object)currentGameLocation != (Object)null) { CrimeSceneManager.ReanchorFallScene(id, currentGameLocation); } } catch (Exception ex3) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(35, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] ReanchorFallScene #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex3.Message); } logger4.LogWarning(val3); } } catch (Exception ex4) { ManualLogSource logger5 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(32, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] FinalizeCorpse #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex4.Message); } logger5.LogWarning(val3); } finally { ClearFallUnreportable(id, val); } } private static void MarkFallUnreportable(Citizen c) { try { if (!((Object)(object)c == (Object)null)) { ((Actor)c).unreportable = true; (SyndicateState.Data?.FallUnreportable)?.Add(((Human)c).humanID); } } catch { } } private static void ClearFallUnreportable(int id, Human h) { try { if ((Object)(object)h != (Object)null) { ((Actor)h).unreportable = false; } } catch { } try { SyndicateState.Data?.FallUnreportable?.Remove(id); } catch { } } internal static void RecoverUnreportableOnLoad() { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown bool flag2 = default(bool); try { HashSet hashSet = SyndicateState.Data?.FallUnreportable; if (hashSet == null || hashSet.Count == 0) { return; } int num = 0; int num2 = 0; foreach (int item in new List(hashSet)) { try { Human val = ResolveHuman(item); bool flag = false; try { flag = (Object)(object)val != (Object)null && ((Actor)val).isDead; } catch { } if (!flag) { ClearFallUnreportable(item, val); num2++; continue; } Track orAdd = GetOrAdd(item); orAdd.Killed = true; orAdd.InFlight = true; orAdd.Dragging = false; orAdd.KilledSince = Time.time; orAdd.SettleCount = 0; orAdd.Nudges = 0; orAdd.LastY = BodyY(val); orAdd.LastTime = Time.time; num++; } catch { } } if (num > 0 || num2 > 0) { ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(106, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Fall] load recovery: re-armed "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" settling corpse(s), dropped "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (reporting stays suppressed until they rest)."); } logger.LogInfo(val2); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] RecoverUnreportableOnLoad failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } private static void ReleaseAllUnreportable(string reason) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown bool flag = default(bool); try { HashSet hashSet = SyndicateState.Data?.FallUnreportable; if (hashSet == null || hashSet.Count == 0) { return; } int num = 0; foreach (int item in new List(hashSet)) { Human h = null; try { h = ResolveHuman(item); } catch { } ClearFallUnreportable(item, h); num++; } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(66, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Fall] released "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" pending fall victim(s) ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — reporting re-enabled."); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(41, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Fall] ReleaseAllUnreportable ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static void TryDislodge(Human h, Track t) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) try { if (t.Nudges >= 8) { return; } CitizenAnimationController animationController = ((Actor)h).animationController; if ((Object)(object)animationController == (Object)null) { return; } float num = Math.Max(1f, SyndicateConfig.FallAntiSnagForce?.Value ?? 6f); Vector3 val = Vector3.down * num; int num2 = 0; List createdRBs = animationController.createdRBs; if (createdRBs != null) { for (int i = 0; i < createdRBs.Count; i++) { Rigidbody val2 = createdRBs[i]; if ((Object)(object)val2 != (Object)null) { try { val2.AddForce(val, (ForceMode)2); num2++; } catch { } } } } if (num2 == 0 && (Object)(object)animationController.upperTorsoRB != (Object)null) { try { animationController.upperTorsoRB.AddForce(val, (ForceMode)2); num2++; } catch { } } if (num2 > 0) { t.Nudges++; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(38, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Fall] anti-snag dislodge #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(h.humanID); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (nudge "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(t.Nudges); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(8); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")."); } logger.LogInfo(val3); } } catch { } } private static bool NearGround(Human h) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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) try { CitizenOutfitController outfitController = h.outfitController; Transform val = (((Object)(object)outfitController != (Object)null) ? outfitController.GetBodyAnchor((CharacterAnchor)0) : null); if ((Object)(object)val == (Object)null) { return false; } int num = -16777221; Vector3 val2 = val.position + Vector3.up * 0.1f; return Physics.Raycast(val2, Vector3.down, 1.6f, num) || Physics.Raycast(val2 + new Vector3(0.35f, 0f, 0f), Vector3.down, 1.6f, num) || Physics.Raycast(val2 + new Vector3(-0.35f, 0f, 0f), Vector3.down, 1.6f, num) || Physics.Raycast(val2 + new Vector3(0f, 0f, 0.35f), Vector3.down, 1.6f, num) || Physics.Raycast(val2 + new Vector3(0f, 0f, -0.35f), Vector3.down, 1.6f, num); } catch { return false; } } private static float BodyY(Human h) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) try { CitizenOutfitController outfitController = h.outfitController; if ((Object)(object)outfitController == (Object)null) { return float.NaN; } Transform bodyAnchor = outfitController.GetBodyAnchor((CharacterAnchor)0); return ((Object)(object)bodyAnchor != (Object)null) ? bodyAnchor.position.y : float.NaN; } catch { return float.NaN; } } private static Human ResolveHuman(int id) { try { Human val = default(Human); return ((Object)(object)CityData.Instance != (Object)null && CityData.Instance.GetHuman(id, ref val, false)) ? val : null; } catch { return null; } } private static Track GetOrAdd(int id) { if (!_tracks.TryGetValue(id, out var value)) { value = new Track(); _tracks[id] = value; } return value; } private static string SafeName(Citizen c) { try { return ((Human)c).GetCitizenName(); } catch { return "target"; } } } public class FallHeaveHotkey : MonoBehaviour { private GUIStyle _hintStyle; public FallHeaveHotkey(IntPtr ptr) : base(ptr) { } private void Update() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) try { ConfigEntry fallKillsEnabled = SyndicateConfig.FallKillsEnabled; if ((fallKillsEnabled == null || fallKillsEnabled.Value) && InPlay()) { ConfigEntry heaveKey = SyndicateConfig.HeaveKey; KeyCode val = (KeyCode)((heaveKey == null) ? 103 : ((int)heaveKey.Value)); if ((int)val != 0 && Input.GetKeyDown(val)) { Heave(); } } } catch { } } private void FixedUpdate() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) try { ConfigEntry fallKillsEnabled = SyndicateConfig.FallKillsEnabled; if (fallKillsEnabled != null && !fallKillsEnabled.Value) { return; } float num = Mathf.Clamp01(SyndicateConfig.DragLiftAssist?.Value ?? 0.5f); if (num <= 0f || (Object)(object)SessionData.Instance == (Object)null || !SessionData.Instance.play) { return; } Human val = DraggedLivingBody(); if ((Object)(object)val == (Object)null) { return; } CitizenAnimationController animationController = ((Actor)val).animationController; if ((Object)(object)animationController == (Object)null) { return; } Vector3 val2 = -Physics.gravity * num; int num2 = 0; List createdRBs = animationController.createdRBs; if (createdRBs != null) { for (int i = 0; i < createdRBs.Count; i++) { Rigidbody val3 = createdRBs[i]; if ((Object)(object)val3 != (Object)null) { try { val3.AddForce(val2, (ForceMode)5); num2++; } catch { } } } } if (num2 != 0 || !((Object)(object)animationController.upperTorsoRB != (Object)null)) { return; } try { animationController.upperTorsoRB.AddForce(val2, (ForceMode)5); } catch { } } catch { } } private void OnGUI() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown try { ConfigEntry fallKillsEnabled = SyndicateConfig.FallKillsEnabled; if ((fallKillsEnabled != null && !fallKillsEnabled.Value) || !InPlay()) { return; } ConfigEntry heaveKey = SyndicateConfig.HeaveKey; KeyCode val = (KeyCode)((heaveKey == null) ? 103 : ((int)heaveKey.Value)); if ((int)val != 0 && !((Object)(object)DraggedLivingBody() == (Object)null)) { if (_hintStyle == null) { _hintStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 16, fontStyle = (FontStyle)1 }; } string text = $"Drag to the edge — press [{val}] to throw the body over"; float num = 620f; float num2 = 28f; float num3 = ((float)Screen.width - num) * 0.5f; float num4 = (float)Screen.height * 0.72f; _hintStyle.normal.textColor = new Color(0f, 0f, 0f, 0.75f); GUI.Label(new Rect(num3 + 1f, num4 + 1f, num, num2), text, _hintStyle); _hintStyle.normal.textColor = SynUI.Caution; GUI.Label(new Rect(num3, num4, num, num2), text, _hintStyle); } } catch { } } private static void Heave() { //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { InteractionController instance = InteractionController.Instance; RigidbodyDragObject val = (((Object)(object)instance != (Object)null) ? instance.currentlyDragging : null); if ((Object)(object)val == (Object)null) { return; } Human val2 = null; try { val2 = (((Object)(object)val.ai != (Object)null) ? val.ai.human : null); } catch { } if ((Object)(object)val2 == (Object)null || ((Actor)val2).isDead) { return; } Transform val3 = (((Object)(object)CameraController.Instance != (Object)null && (Object)(object)CameraController.Instance.cam != (Object)null) ? ((Component)CameraController.Instance.cam).transform : null); if ((Object)(object)val3 == (Object)null) { return; } float num = Mathf.Max(0f, SyndicateConfig.HeaveSpeed?.Value ?? 4f); if (num <= 0f) { return; } Vector3 val4 = val3.forward + Vector3.up * 0.2f; Vector3 val5 = ((Vector3)(ref val4)).normalized * num; int num2 = 0; CitizenAnimationController animationController = ((Actor)val2).animationController; if ((Object)(object)animationController != (Object)null) { List createdRBs = animationController.createdRBs; if (createdRBs != null) { for (int i = 0; i < createdRBs.Count; i++) { Rigidbody val6 = createdRBs[i]; if ((Object)(object)val6 != (Object)null) { try { val6.AddForce(val5, (ForceMode)2); num2++; } catch { } } } } if (num2 == 0 && (Object)(object)animationController.upperTorsoRB != (Object)null) { try { animationController.upperTorsoRB.AddForce(val5, (ForceMode)2); num2++; } catch { } } } if (num2 == 0 && (Object)(object)val.targetRigidbody != (Object)null) { try { val.targetRigidbody.AddForce(val5, (ForceMode)2); num2++; } catch { } } try { val.CancelDrag(); } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(39, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("[Fall] heave: launched #"); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(val2.humanID); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" at "); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(num, "0.#"); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" m/s ("); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" rb)."); } logger.LogInfo(val7); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val8 = new BepInExWarningLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val8).AppendLiteral("[Fall] Heave failed: "); ((BepInExLogInterpolatedStringHandler)val8).AppendFormatted(ex.Message); } logger2.LogWarning(val8); } } private static Human DraggedLivingBody() { try { InteractionController instance = InteractionController.Instance; RigidbodyDragObject val = (((Object)(object)instance != (Object)null) ? instance.currentlyDragging : null); if ((Object)(object)val == (Object)null) { return null; } Human val2 = (((Object)(object)val.ai != (Object)null) ? val.ai.human : null); return ((Object)(object)val2 != (Object)null && !((Actor)val2).isDead) ? val2 : null; } catch { return null; } } private static bool InPlay() { try { if ((Object)(object)SessionData.Instance == (Object)null || !SessionData.Instance.play) { return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || ((Actor)instance).isDead) { return false; } if (instance.computerInteractable != null) { return false; } return true; } catch { return false; } } } internal static class PoisonController { internal enum Kind { Syringe, Vial } internal enum Outcome { Used, Empty, NoTarget, WrongState, NotPoison, Disabled, OnCooldown, WorldInteractable } internal const string SyringePreset = "Syringe"; internal const string VialPreset = "PoisonBottle"; internal const string MethodSyringe = "syringe"; internal const string MethodVialForge = "vialForge"; internal const string MethodFallForge = "fallForge"; private static readonly Dictionary _killMethod = new Dictionary(); private static bool _using; private static float _nextUseTime; private static float _lastEmptyMsgTime = -999f; private static float _lastToastTime = -999f; internal const string SyringePromptText = "Inject"; internal const string VialPromptText = "Force-feed"; private static float _promptCacheAt = -999f; private static bool _promptCache; private static string _promptText = "Inject"; internal static void SetKillMethod(int victimId, string method) { _killMethod[victimId] = method; } internal static string PeekKillMethod(int victimId) { if (!_killMethod.TryGetValue(victimId, out var value)) { return null; } return value; } internal static void ClearKillMethod(int victimId) { _killMethod.Remove(victimId); } internal static bool IsHoldingPoison(out Interactable held, out Kind kind) { held = null; kind = Kind.Syringe; try { Interactable equippedInteractableCached = KillSwitchPatch.GetEquippedInteractableCached(); if (equippedInteractableCached == null || (SoCustomComparison)(object)equippedInteractableCached.preset == (SoCustomComparison)null) { return false; } string name = ((Object)equippedInteractableCached.preset).name; if (name == "Syringe") { held = equippedInteractableCached; kind = Kind.Syringe; return true; } if (name == "PoisonBottle") { held = equippedInteractableCached; kind = Kind.Vial; return true; } return false; } catch { return false; } } internal static Kind KindOf(Interactable item) { try { return ((SoCustomComparison)(object)((item != null) ? item.preset : null) != (SoCustomComparison)null && ((Object)item.preset).name == "PoisonBottle") ? Kind.Vial : Kind.Syringe; } catch { return Kind.Syringe; } } internal static bool IsPoisonItem(Interactable item) { try { object obj; if (item == null) { obj = null; } else { InteractablePreset preset = item.preset; obj = ((preset != null) ? ((Object)preset).name : null); } string text = (string)obj; return text == "Syringe" || text == "PoisonBottle"; } catch { return false; } } internal static Outcome Use() { //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) ConfigEntry poisonEnabled = SyndicateConfig.PoisonEnabled; if (poisonEnabled != null && !poisonEnabled.Value) { return Outcome.Disabled; } if (_using) { return Outcome.OnCooldown; } if (!IsHoldingPoison(out var held, out var kind)) { return Outcome.NotPoison; } CameraController instance = CameraController.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.cam == (Object)null) { return Outcome.NotPoison; } float num = Mathf.Max(0.5f, SyndicateConfig.PoisonRange?.Value ?? 2f); Transform transform = ((Component)instance.cam).transform; RaycastHit hit; Citizen val = AcquireCitizen(transform, num, out hit); if ((Object)(object)val == (Object)null) { if (FirearmsController.ShouldYieldToWorldInteraction(num)) { return Outcome.WorldInteractable; } Toast((kind == Kind.Syringe) ? "No one in reach for the needle." : "No one in reach to dose."); return Outcome.NoTarget; } if (PoisonDoses.Get(held) <= 0) { EmptyClick(kind); return Outcome.Empty; } if (Time.time < _nextUseTime) { return Outcome.OnCooldown; } _using = true; try { if (((Actor)val).isDead || (Object)(object)((Actor)val).ai == (Object)null) { Toast((kind == Kind.Syringe) ? "No one in reach for the needle." : "No one in reach to dose."); return Outcome.NoTarget; } if (ProtectedCitizens.IsProtected((Human)(object)val)) { ProtectedCitizens.DegradeToKO(val); return Outcome.WrongState; } return (kind == Kind.Syringe) ? UseSyringe(held, val, ((RaycastHit)(ref hit)).point, transform.forward) : UseVial(held, val, ((RaycastHit)(ref hit)).point, transform.forward); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Poison] Use failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger.LogError(val2); return Outcome.NoTarget; } finally { _using = false; } } private static Citizen AcquireCitizen(Transform camT, float range, out RaycastHit hit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) hit = default(RaycastHit); try { if (Physics.Raycast(camT.position, camT.forward, ref hit, range, Toolbox.Instance.physicalObjectsLayerMask)) { Actor val = ((Component)((RaycastHit)(ref hit)).transform).gameObject.GetComponent() ?? ((Component)((RaycastHit)(ref hit)).transform).gameObject.GetComponentInParent(); if ((Object)(object)val != (Object)null && !val.isPlayer) { Citizen val2 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val2 != (Object)null) { return val2; } } } InteractionController instance = InteractionController.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.currentLookingAtInteractable != (Object)null && (Object)(object)instance.currentLookingAtInteractable.isActor != (Object)null) { RaycastHit playerCurrentRaycastHit = instance.playerCurrentRaycastHit; if (((RaycastHit)(ref playerCurrentRaycastHit)).distance <= range) { Actor isActor = instance.currentLookingAtInteractable.isActor; if (!isActor.isPlayer) { Citizen val3 = ((Il2CppObjectBase)isActor).TryCast(); if ((Object)(object)val3 != (Object)null) { playerCurrentRaycastHit = instance.playerCurrentRaycastHit; ((RaycastHit)(ref hit)).point = ((RaycastHit)(ref playerCurrentRaycastHit)).point; return val3; } } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Poison] acquire failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger.LogWarning(val4); } return null; } internal static bool PromptOverride(out string text) { text = _promptText; try { ConfigEntry poisonEnabled = SyndicateConfig.PoisonEnabled; if (poisonEnabled != null && !poisonEnabled.Value) { return false; } ConfigEntry poisonPromptOverride = SyndicateConfig.PoisonPromptOverride; if (poisonPromptOverride != null && !poisonPromptOverride.Value) { return false; } if (!IsHoldingPoison(out var held, out var kind)) { return false; } _promptText = ((kind == Kind.Vial) ? "Force-feed" : "Inject"); text = _promptText; if (Time.unscaledTime - _promptCacheAt < 0.15f) { return _promptCache; } _promptCacheAt = Time.unscaledTime; _promptCache = CanUseOnTarget(held, kind); return _promptCache; } catch { return false; } } private static bool CanUseOnTarget(Interactable held, Kind kind) { try { if (PoisonDoses.Get(held) <= 0) { return false; } CameraController instance = CameraController.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.cam == (Object)null) { return false; } float range = Mathf.Max(0.5f, SyndicateConfig.PoisonRange?.Value ?? 2f); RaycastHit hit; Citizen val = AcquireCitizen(((Component)instance.cam).transform, range, out hit); if ((Object)(object)val == (Object)null || ((Actor)val).isDead || (Object)(object)((Actor)val).ai == (Object)null) { return false; } if (ProtectedCitizens.IsProtected((Human)(object)val)) { return false; } if (kind == Kind.Vial && !((Actor)val).ai.ko) { return false; } return true; } catch { return false; } } private static Outcome UseSyringe(Interactable held, Citizen victim, Vector3 hitPos, Vector3 dir) { //IL_0137: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((Actor)victim).ai != (Object)null && !((Actor)victim).ai.ko) { try { CitizenAnimationController animationController = ((Actor)victim).animationController; if (animationController != null) { animationController.TakeDamageRecoil(hitPos); } } catch { } try { ((Human)victim).AddDrunk(Mathf.Clamp01(SyndicateConfig.SyringeStaggerDrunk?.Value ?? 0.6f)); } catch { } float num = Mathf.Max(0f, SyndicateConfig.SyringeKillDelayGameMinutes?.Value ?? 5f); if (num > 0f) { PoisonScheduler.ScheduleSyringeSequence(victim, held, hitPos, dir, num); try { int num2 = Mathf.Max(1, Mathf.RoundToInt(num)); string value = "The mark"; try { string citizenName = ((Human)victim).GetCitizenName(); if (!string.IsNullOrEmpty(citizenName)) { value = citizenName; } } catch { } MessageQueue.Enqueue($"{value} is dosed — collapses in about {num2} minute{((num2 == 1) ? "" : "s")}. Walk away clean."); } catch { } } else { KillNow(victim, held, hitPos, dir); } } else { KillNow(victim, held, hitPos, dir); } PoisonDoses.Spend(held); _lastToastTime = Time.time; _nextUseTime = Time.time + Mathf.Max(0.05f, SyndicateConfig.PoisonCooldownSeconds?.Value ?? 1.2f); return Outcome.Used; } internal static void KillNow(Citizen victim, Interactable syringe, Vector3 hitPos, Vector3 dir) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)victim == (Object)null || ((Actor)victim).isDead) { return; } bool flag = default(bool); try { if ((Object)(object)((Actor)victim).ai != (Object)null && !((Actor)victim).ai.ko) { try { ((Actor)victim).ai.SetKO(true, hitPos, dir, false, 0f, true, 1f); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] SetKO prep failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } int humanID = ((Human)victim).humanID; SetKillMethod(humanID, "syringe"); try { KillSwitchPatch.ApplyLethal(victim, (Human)(object)Player.Instance, syringe); } finally { ClearKillMethod(humanID); } } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] syringe kill failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2.Message); } logger2.LogWarning(val); } } private static Outcome UseVial(Interactable held, Citizen victim, Vector3 hitPos, Vector3 dir) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((Actor)victim).ai == (Object)null || !((Actor)victim).ai.ko) { Toast("They're awake — you can't force-feed a conscious target. Put them down first."); return Outcome.WrongState; } if (PoisonScheduler.HasPendingFor(((Human)victim).humanID)) { Toast("They've already had a dose. Give it time."); return Outcome.WrongState; } PoisonScheduler.ScheduleForge(victim, held, hitPos, dir); _nextUseTime = Time.time + Mathf.Max(0.05f, SyndicateConfig.PoisonCooldownSeconds?.Value ?? 1.2f); Toast("Down the throat. It'll look like an overdose — give it about half an hour."); return Outcome.Used; } private static void EmptyClick(Kind kind) { if (!(Time.time - _lastEmptyMsgTime < 2.5f)) { _lastEmptyMsgTime = Time.time; Toast((kind == Kind.Vial) ? "The vial is empty." : "The syringe is spent — no doses left."); } } private static void Toast(string msg) { if (Time.time - _lastToastTime < 0.25f) { return; } _lastToastTime = Time.time; try { Lib.GameMessage.Broadcast(msg, (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } } internal static class PoisonDoses { internal static int CapacityFor(Interactable item) { try { int val = ((PoisonController.KindOf(item) != PoisonController.Kind.Vial) ? (SyndicateConfig.SyringeDoses?.Value ?? 3) : (SyndicateConfig.VialDoses?.Value ?? 3)); return Math.Max(1, val); } catch { return 3; } } internal static int Get(Interactable item) { try { if (item == null) { return 0; } if (SyndicateState.Data.PoisonDoses.TryGetValue(item.id, out var value)) { return Math.Max(0, value); } return CapacityFor(item); } catch { return 0; } } internal static void Spend(Interactable item) { try { if (item != null) { SyndicateState.Data.PoisonDoses[item.id] = Math.Max(0, Get(item) - 1); } } catch { } } internal static void MarkSpent(int itemId) { try { if (itemId >= 0) { SyndicateState.Data.PoisonDoses[itemId] = 0; } } catch { } } } internal static class PoisonMailer { private static float _lastMissingPresetLog = -999f; internal static void MailContractItems(ContractData c) { //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown try { if (c == null || c.Objectives == null || SyndicateState.IsWorldLoading) { return; } bool flag = false; bool flag2 = false; ObjectiveData objectiveData = null; foreach (ObjectiveData objective in c.Objectives) { if (objective != null) { if (objective.Type == "PoisonKill") { flag = true; } else if (objective.Type == "ForgeSuicide" && objective.Variant != "Fall") { flag2 = true; } else if (objective.Type == "DisposeAtSea") { objectiveData = objective; } } } bool flag3 = objectiveData != null && (flag || flag2); foreach (ObjectiveData objective2 in c.Objectives) { if (objective2 == null || objective2.ItemMailed) { continue; } if (objective2.Type == "ForgeSuicide" && objective2.Variant == "Fall") { objective2.ItemMailed = true; continue; } if (objective2.Type == "DisposeAtSea" && flag3) { if (flag2) { objective2.ItemMailed = true; } continue; } string text = ((objective2.Type == "PoisonKill") ? "Syringe" : ((objective2.Type == "ForgeSuicide") ? "PoisonBottle" : ((objective2.Type == "DisposeAtSea") ? c.IssuedWeaponPreset : null))); if (string.IsNullOrEmpty(text) || !TryMailOne(text, out var inter)) { continue; } objective2.ItemMailed = true; if (objective2.Type == "DisposeAtSea" && inter != null) { c.IssuedWeaponId = inter.id; } if (objective2.Type == "PoisonKill" && flag3 && inter != null) { c.IssuedWeaponId = inter.id; if (objectiveData != null) { objectiveData.ItemMailed = true; } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag4 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] MailContractItems failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static void Tick() { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown try { if (SyndicateState.IsWorldLoading) { return; } List activeContracts = SyndicateState.Data.ActiveContracts; if (activeContracts == null) { return; } for (int i = 0; i < activeContracts.Count; i++) { ContractData contractData = activeContracts[i]; if (contractData == null || contractData.Status != "Active" || contractData.Objectives == null) { continue; } bool flag = false; foreach (ObjectiveData objective in contractData.Objectives) { if (objective != null && !objective.ItemMailed && (objective.Type == "PoisonKill" || objective.Type == "ForgeSuicide" || objective.Type == "DisposeAtSea")) { flag = true; break; } } if (flag) { MailContractItems(contractData); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] mailer tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static bool TryMailOne(string presetName, out Interactable inter) { //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Expected O, but got Unknown inter = null; bool flag3 = default(bool); try { InteractablePreset interactablePreset = Toolbox.Instance.GetInteractablePreset(presetName); if ((SoCustomComparison)(object)interactablePreset == (SoCustomComparison)null) { if (Time.time - _lastMissingPresetLog > 10f) { _lastMissingPresetLog = Time.time; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(52, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] mail: preset '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(presetName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' not found — cannot deliver."); } logger.LogWarning(val); } return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return false; } Human val2 = Rewards.ResolveFixer(); bool flag2 = false; Interactable mailbox = Toolbox.Instance.GetMailbox((Human)(object)instance); if (mailbox != null) { if (mailbox.locked) { try { mailbox.SetLockedState(false, (Actor)null, false, true); } catch { } } Vector3 val3 = mailbox.wPos + Quaternion.Euler(mailbox.wEuler) * new Vector3(0.1f, 0f, -0.15f); try { inter = InteractableCreator.Instance.CreateWorldInteractable(interactablePreset, (Human)(object)instance, val2, (Human)(object)instance, val3, mailbox.wEuler, (List)null, (Object)null, ""); flag2 = inter != null; } catch { try { inter = InteractableCreator.Instance.CreateFurnitureSpawnedInteractable(interactablePreset, mailbox.furnitureParent, (SubObject)null, (Human)(object)instance, val2, (Human)(object)instance, (List)null, (LightingPreset)null, (Object)null, ""); flag2 = inter != null; } catch { } } } if (inter == null) { try { inter = InteractableCreator.Instance.CreateWorldInteractable(interactablePreset, (Human)(object)instance, val2, (Human)(object)instance, ((Component)instance).transform.position + ((Component)instance).transform.forward * 0.6f, Vector3.zero, (List)null, (Object)null, ""); } catch { } } if (inter == null) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(58, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] mail: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(presetName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' delivery failed everywhere — will retry."); } logger2.LogWarning(val); return false; } Lib.GameMessage.Broadcast(flag2 ? "The kit for the job is in your mailbox." : "The kit for the job was left at your feet.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(42, 3, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Poison] mailed '"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(presetName); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("' (interId="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(inter.id); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", atMailbox="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")."); } logger3.LogInfo(val4); return true; } catch (Exception ex) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] TryMailOne('"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(presetName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("') failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger4.LogWarning(val); return false; } } } internal static class PoisonScheduler { private sealed class SyringeBeat { public Citizen Victim; public Interactable Syringe; public Vector3 HitPos; public Vector3 Dir; public float PukeGameTime; public float CollapseGameTime; public bool PukeFired; } private static readonly List _beats = new List(); internal static void ResetSession() { _beats.Clear(); } internal static void ScheduleSyringeSequence(Citizen victim, Interactable syringe, Vector3 hitPos, Vector3 dir, float collapseGameMinutes) { //IL_0055: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)victim == (Object)null)) { float num = (((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.gameTime : 0f); float num2 = Mathf.Max(0f, collapseGameMinutes) / 60f; _beats.Add(new SyringeBeat { Victim = victim, Syringe = syringe, HitPos = hitPos, Dir = dir, PukeGameTime = num + num2 * 0.9f, CollapseGameTime = num + num2 }); } } internal static void ScheduleForge(Citizen victim, Interactable vial, Vector3 hitPos, Vector3 dir) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { if ((Object)(object)victim == (Object)null) { return; } bool printed; Interactable val = SpawnBottle(victim, atPlayerFeet: true, out printed); if (val != null) { ContractManager.BindDisposalWeapon(((Human)victim).humanID, val.id); } ConsumeHeldItem(vial); try { if ((Object)(object)((Actor)victim).ai != (Object)null) { ((Actor)victim).ai.SetKO(true, hitPos, dir, true, PinHours(), false, 1f); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Poison] forge KO pin failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } int num = Math.Max(1, SyndicateConfig.ForgeDelayMinutes?.Value ?? 30); PendingPoisonDto pendingPoisonDto = new PendingPoisonDto { VictimId = ((Human)victim).humanID, VictimName = SafeName((Human)(object)victim), WeaponId = ((val != null) ? val.id : (-1)), PrintedAtFeed = printed, CleanKO = !CleanKOTracker.WasViolent(((Human)victim).humanID) }; TimeData val3; try { val3 = Lib.Time.CurrentDateTime; val3 = ((TimeData)(ref val3)).AddMinutes(num); pendingPoisonDto.DueAt = ((TimeData)(ref val3)).Serialize(); } catch { } try { val3 = Lib.Time.CurrentDateTime; val3 = ((TimeData)(ref val3)).AddMinutes(num); val3 = ((TimeData)(ref val3)).AddHours(12); pendingPoisonDto.ExpireAt = ((TimeData)(ref val3)).Serialize(); } catch { } SyndicateState.Data.PendingPoisons.Add(pendingPoisonDto); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(77, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Poison] Forged overdose scheduled for "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(Redact.Name(pendingPoisonDto.VictimName, pendingPoisonDto.VictimId)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(pendingPoisonDto.VictimId); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(") at "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(pendingPoisonDto.DueAt); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" (bottle id "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(pendingPoisonDto.WeaponId); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", printedAtFeed="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(printed); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")."); } logger2.LogInfo(val4); } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Poison] ScheduleForge failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex2); } logger3.LogError(val5); } } internal static bool HasPendingFor(int victimId) { List pendingPoisons = SyndicateState.Data.PendingPoisons; if (pendingPoisons == null) { return false; } foreach (PendingPoisonDto item in pendingPoisons) { if (item != null && item.VictimId == victimId) { return true; } } return false; } private static Interactable SpawnBottle(Citizen victim, bool atPlayerFeet, out bool printed) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) printed = false; try { InteractablePreset interactablePreset = Toolbox.Instance.GetInteractablePreset("PoisonBottle"); if ((SoCustomComparison)(object)interactablePreset == (SoCustomComparison)null || (Object)(object)victim == (Object)null) { return null; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return null; } Vector3 val = (atPlayerFeet ? ((Component)instance).transform.position : ((Component)victim).transform.position) + Vector3.up * 0.1f; Interactable val2 = InteractableCreator.Instance.CreateWorldInteractable(interactablePreset, (Human)(object)instance, (Human)(object)instance, (Human)null, val, Vector3.zero, (List)null, (Object)null, ""); if (val2 == null) { return null; } try { if ((Object)(object)val2.controller != (Object)null) { val2.controller.DropThis(false); } else { val2.ForcePhysicsActive(false, true, Vector3.zero, (ForceMode)2, false); } } catch { } try { printed = PlayerInteractionPrintPatch.EnsurePlayerPrint(val2, recordInEvidence: false); } catch { } PoisonDoses.MarkSpent(val2.id); return val2; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Poison] SpawnBottle failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); return null; } } private static void ConsumeHeldItem(Interactable item) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown try { if (item == null) { return; } FirstPersonItemController instance = FirstPersonItemController.Instance; if (((instance != null) ? instance.slots : null) == null) { return; } Enumerator enumerator = instance.slots.GetEnumerator(); while (enumerator.MoveNext()) { InventorySlot current = enumerator.Current; if (current != null) { Interactable interactable = current.GetInteractable(); if (interactable != null && interactable.id == item.id) { instance.EmptySlot(current, false, true, true, false); break; } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] consume vial failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static void TickBeats() { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (_beats.Count == 0) { return; } float num = (((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.gameTime : (-1f)); if (num < 0f) { return; } bool flag = default(bool); for (int num2 = _beats.Count - 1; num2 >= 0; num2--) { SyringeBeat syringeBeat = _beats[num2]; if (syringeBeat == null) { _beats.RemoveAt(num2); } else { try { if ((Object)(object)syringeBeat.Victim == (Object)null || ((Actor)syringeBeat.Victim).isDead) { _beats.RemoveAt(num2); } else { if (!syringeBeat.PukeFired && num >= syringeBeat.PukeGameTime) { syringeBeat.PukeFired = true; SpawnVomit(syringeBeat.Victim); } if (num >= syringeBeat.CollapseGameTime) { _beats.RemoveAt(num2); PoisonController.KillNow(syringeBeat.Victim, syringeBeat.Syringe, syringeBeat.HitPos, syringeBeat.Dir); } } } catch (Exception ex) { _beats.RemoveAt(num2); ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] syringe beat failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } } private static void SpawnVomit(Citizen victim) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)victim == (Object)null || ((Actor)victim).isDead || (Object)(object)((Human)victim).outfitController == (Object)null) { return; } Transform bodyAnchor = ((Human)victim).outfitController.GetBodyAnchor((CharacterAnchor)2); if (!((Object)(object)bodyAnchor == (Object)null)) { SpatterPatternPreset val = (((Object)(object)CitizenControls.Instance != (Object)null) ? CitizenControls.Instance.vomitSpatter : null); if (!((SoCustomComparison)(object)val == (SoCustomComparison)null)) { ((Actor)victim).RecieveDamage(0.02f, (Actor)null, bodyAnchor.position, bodyAnchor.forward, val, (SpatterPatternPreset)null, (EraseMode)3, false, false, 0f, 0f, false, false, 1f); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Poison] SpawnVomit failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } } internal static void Tick() { //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) List pendingPoisons = SyndicateState.Data.PendingPoisons; if (pendingPoisons == null || pendingPoisons.Count == 0 || SyndicateState.IsWorldLoading) { return; } bool flag = default(bool); for (int num = pendingPoisons.Count - 1; num >= 0; num--) { PendingPoisonDto pendingPoisonDto = pendingPoisons[num]; if (pendingPoisonDto == null) { pendingPoisons.RemoveAt(num); } else { try { Human val = StableIds.ResolveHumanIncludingDead(pendingPoisonDto.VictimId); if ((Object)(object)val == (Object)null) { if (Due(pendingPoisonDto.ExpireAt)) { pendingPoisons.RemoveAt(num); ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(64, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Poison] pending overdose for #"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(pendingPoisonDto.VictimId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" dropped — victim never resolved."); } logger.LogWarning(val2); } } else if (((Actor)val).isDead) { pendingPoisons.RemoveAt(num); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(72, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Poison] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(pendingPoisonDto.VictimName, pendingPoisonDto.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(pendingPoisonDto.VictimId); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") died by other means before the overdose — pending dropped."); } logger2.LogInfo(val3); } else { Citizen val4 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val4 == (Object)null) { pendingPoisons.RemoveAt(num); } else if (ProtectedCitizens.IsProtected((Human)(object)val4)) { pendingPoisons.RemoveAt(num); ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(64, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Poison] pending overdose on "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(pendingPoisonDto.VictimName, pendingPoisonDto.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(pendingPoisonDto.VictimId); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") dropped — target is protected."); } logger3.LogInfo(val3); } else if (!Due(pendingPoisonDto.DueAt)) { if ((Object)(object)((Actor)val4).ai != (Object)null && !((Actor)val4).ai.ko) { try { ((Actor)val4).ai.SetKO(true, ((Component)val4).transform.position, Vector3.up, true, PinHours(), false, 1f); } catch { } } } else { FireVial(pendingPoisonDto, val4); pendingPoisons.RemoveAt(num); } } } catch (Exception ex) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(32, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Poison] pending tick #"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(pendingPoisonDto.VictimId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger4.LogWarning(val2); } } } } private static void FireVial(PendingPoisonDto p, Citizen citizen) { //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_00b6: 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) bool printed = default(bool); try { Interactable val = ((p.WeaponId >= 0) ? StableIds.ResolveInteractable(p.WeaponId) : null); if (val == null) { val = SpawnBottle(citizen, atPlayerFeet: false, out printed); } if (val != null) { ContractManager.BindDisposalWeapon(((Human)citizen).humanID, val.id); } if (val == null) { val = ((Actor)citizen).interactable; ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(88, 1, ref printed); if (printed) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Poison] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Redact.Name(p.VictimName, p.VictimId)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" overdose: no bottle resolvable — using the body interactable as murder weapon."); } logger.LogWarning(val2); } if ((Object)(object)((Actor)citizen).ai != (Object)null && !((Actor)citizen).ai.ko) { try { ((Actor)citizen).ai.SetKO(true, ((Component)citizen).transform.position, Vector3.up, false, 0f, true, 1f); } catch { } } int humanID = ((Human)citizen).humanID; PoisonController.SetKillMethod(humanID, "vialForge"); bool? glovesActiveOverride = SyndicateState.GlovesActiveOverride; SyndicateState.GlovesActiveOverride = true; try { KillSwitchPatch.ApplyLethal(citizen, (Human)(object)Player.Instance, val); } finally { SyndicateState.GlovesActiveOverride = glovesActiveOverride; PoisonController.ClearKillMethod(humanID); } try { CrimeSceneManager.SetForgedWeaponPrint(humanID, p.PrintedAtFeed); } catch { } try { CrimeSceneManager.SetForgedOverdose(humanID); } catch { } try { ContractManager.ResolveForgeViolence(humanID, p.CleanKO); } catch { } ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(120, 3, ref printed); if (printed) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Poison] Forged overdose fired for "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(p.VictimName, p.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(humanID); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", printedAtFeed="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(p.PrintedAtFeed); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("). A clean case reads as a suicide; an identified one is a murder."); } logger2.LogInfo(val3); } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 2, ref printed); if (printed) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Poison] FireVial #"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(p.VictimId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger3.LogWarning(val2); } } internal static void PruneOnLoad() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown List pendingPoisons = SyndicateState.Data.PendingPoisons; if (pendingPoisons == null || pendingPoisons.Count == 0) { return; } int count = pendingPoisons.Count; for (int num = pendingPoisons.Count - 1; num >= 0; num--) { PendingPoisonDto pendingPoisonDto = pendingPoisons[num]; if (pendingPoisonDto == null) { pendingPoisons.RemoveAt(num); } else { bool flag = false; try { flag = (Object)(object)StableIds.ResolveHumanIncludingDead(pendingPoisonDto.VictimId) != (Object)null; } catch { } if (!flag && Due(pendingPoisonDto.ExpireAt)) { pendingPoisons.RemoveAt(num); } } } if (pendingPoisons.Count != count) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(53, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Poison] pruned "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(count - pendingPoisons.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" expired pending overdose(s) at load."); } logger.LogInfo(val); } } private static float PinHours() { int num = Math.Max(1, SyndicateConfig.ForgeDelayMinutes?.Value ?? 30); return Math.Max(1f, (float)num / 60f * 1.5f); } private static bool Due(string serialized) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(serialized)) { return false; } try { return Lib.Time.CurrentDateTime >= TimeData.Deserialize(serialized); } catch { return false; } } private static string SafeName(Human h) { try { return ((Object)(object)h != (Object)null) ? h.GetCitizenName() : "the target"; } catch { return "the target"; } } } internal static class SedativeDoses { internal static int Capacity => Math.Max(1, SyndicateConfig.ChloroformDoses?.Value ?? 3); internal static int Get(Interactable item) { try { if (item == null) { return 0; } if (SyndicateState.Data.SedativeDoses.TryGetValue(item.id, out var value)) { return Math.Max(0, value); } return Capacity; } catch { return 0; } } internal static void Spend(Interactable item) { try { if (item != null) { SyndicateState.Data.SedativeDoses[item.id] = Math.Max(0, Get(item) - 1); } } catch { } } } } namespace TheSyndicate.News { internal static class NewsEngine { private sealed class Cand { public int Prio; public float Time; public int VictimId; public string Text; } private const string BlockDict = "dds.blocks"; private const string MainBlockId = "syn_news_main_block"; private const string MainMsgId = "syn_news_main_msg"; private const string SecBlockId = "syn_news_2_block"; private const string SecMsgId = "syn_news_2_msg"; private const int RingCap = 24; private static string _bakedMain = "THE SYNDICATE\nNo Syndicate news today.\n\nThis placeholder should never appear on a live paper."; private static string _bakedSecondary = ""; private static bool _regenPending; private const string DefaultMain = "THE SYNDICATE\nNo Syndicate news today.\n\nThis placeholder should never appear on a live paper."; internal static bool DebugForceTestStory; internal static string DebugForceStory; private static SyndicateData Data => SyndicateState.Data; internal static void ResetSession() { DebugForceTestStory = false; DebugForceStory = null; _regenPending = false; } internal static void OnLoaded() { try { SyndicateData data = Data; if (data != null) { if (!string.IsNullOrEmpty(data.NewsBakedMain)) { _bakedMain = data.NewsBakedMain; } if (!string.IsNullOrEmpty(data.NewsBakedSecondary)) { _bakedSecondary = data.NewsBakedSecondary; } } } catch { } EnsureRegistered(); } internal static void EnsureRegistered() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown try { Toolbox instance = Toolbox.Instance; if (!((Object)(object)instance == (Object)null)) { bool flag = false; try { flag = instance.allDDSMessages.ContainsKey("syn_news_main_msg"); } catch { } if (!flag) { RegisterMsg(instance, "syn_news_main_block", "syn_news_main_msg", _bakedMain); RegisterMsg(instance, "syn_news_2_block", "syn_news_2_msg", _bakedSecondary); } else { SetBlockText("syn_news_main_block", _bakedMain); SetBlockText("syn_news_2_block", _bakedSecondary); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] EnsureRegistered failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void RegisterMsg(Toolbox tb, string blockId, string msgId, string text) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown DDSBlockSave val = new DDSBlockSave { id = blockId, name = blockId }; DDSMessageSave val2 = new DDSMessageSave { id = msgId, name = msgId }; val2.AddBlock(blockId); try { val2.blocks[0].alwaysDisplay = true; } catch { } tb.allDDSBlocks[blockId] = val; tb.allDDSMessages[msgId] = val2; SetBlockText(blockId, text); } private static void SetBlockText(string blockId, string text) { try { Lib.DdsStrings.AddOrUpdate("dds.blocks", blockId, string.IsNullOrEmpty(text) ? "" : text); } catch { } } internal static void Push(string type, int victimId = -1, string victimName = "", string locationName = "", string district = "", string extra = "") { //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown bool flag = default(bool); try { if ((SyndicateConfig.NewsEnabled != null && !SyndicateConfig.NewsEnabled.Value) || SyndicateState.IsWorldLoading) { return; } SyndicateData data = Data; if (data != null) { if (data.NewsEvents == null) { data.NewsEvents = new List(); } float gameTime = 0f; try { gameTime = (((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.gameTime : 0f); } catch { } data.NewsEvents.Add(new NewsEventDto { Type = (type ?? ""), GameTime = gameTime, VictimId = victimId, VictimName = San(victimName), LocationName = San(locationName), District = San(district), Extra = San(extra) }); while (data.NewsEvents.Count > 24) { data.NewsEvents.RemoveAt(0); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(50, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] event pushed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" victim='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(victimName, victimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'(#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") at '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Place(locationName)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' extra='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(extra); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } logger.LogInfo(val); RequestRegen(); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[News] Push failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } internal static void Apply() { //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown try { if (SyndicateConfig.NewsEnabled != null && !SyndicateConfig.NewsEnabled.Value) { return; } NewspaperController instance = NewspaperController.Instance; if ((Object)(object)instance == (Object)null) { return; } NewspaperState currentState = instance.currentState; if (currentState == null) { return; } EnsureRegistered(); bool flag = DebugForceTestStory || DebugForceStory != null; string secText = null; string mainText; if (DebugForceTestStory) { mainText = ComposeTestStory(); } else if (DebugForceStory == "Wanted") { mainText = ComposeWanted(NewestOfType("Identified"), forceBreaking: true); } else if (DebugForceStory == "CrimeWave") { mainText = ComposeCrimeWave(RecentKillStats(out var names), names, forceDemo: true); } else if (!SelectStories(out mainText, out secText)) { return; } if (string.IsNullOrEmpty(mainText)) { return; } _bakedMain = mainText; SetBlockText("syn_news_main_block", mainText); if (!flag) { try { Data.NewsBakedMain = mainText; } catch { } } if (VanillaMainIsActiveKidnap(currentState) && !string.IsNullOrEmpty(currentState.mainArticle)) { currentState.article2 = "syn_news_main_msg"; currentState.art2Context = 0; if (!string.IsNullOrEmpty(secText)) { _bakedSecondary = secText; SetBlockText("syn_news_2_block", secText); if (!flag) { try { Data.NewsBakedSecondary = secText; } catch { } } currentState.article3 = "syn_news_2_msg"; currentState.art3Context = 0; } } else { string mainArticle = currentState.mainArticle; int mainContext = currentState.mainContext; currentState.mainArticle = "syn_news_main_msg"; currentState.mainContext = 0; if (!string.IsNullOrEmpty(secText)) { _bakedSecondary = secText; SetBlockText("syn_news_2_block", secText); if (!flag) { try { Data.NewsBakedSecondary = secText; } catch { } } currentState.article2 = "syn_news_2_msg"; currentState.art2Context = 0; } else if (!string.IsNullOrEmpty(mainArticle) && mainArticle != "syn_news_main_msg") { currentState.article2 = mainArticle; currentState.art2Context = mainContext; } } instance.UpdateText(true); Plugin.Logger.LogInfo((object)"[News] Syndicate story applied to the front page."); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(21, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] Apply failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static bool VanillaMainIsActiveKidnap(NewspaperState st) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Invalid comparison between Unknown and I4 //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 try { if (st.murderID < 0) { return false; } MurderController instance = MurderController.Instance; if ((Object)(object)instance == (Object)null || instance.activeMurders == null) { return false; } for (int i = 0; i < instance.activeMurders.Count; i++) { Murder val = instance.activeMurders[i]; if (val != null && val.murderID == st.murderID) { if (!((SoCustomComparison)(object)val.preset != (SoCustomComparison)null) || (int)val.preset.caseType != 2) { return false; } return (int)val.state >= 6 || val.kidnapKillPhase; } } } catch { } return false; } private static bool SelectStories(out string mainText, out string secText) { mainText = null; secText = null; SyndicateData data = Data; if (data?.NewsEvents == null) { return false; } float num = Now(); float num2 = SyndicateConfig.NewsFreshHours?.Value ?? 48; HashSet hashSet = new HashSet(); foreach (NewsEventDto newsEvent in data.NewsEvents) { if (newsEvent != null && newsEvent.Type == "Identified" && newsEvent.VictimId >= 0) { hashSet.Add(newsEvent.VictimId); } } Dictionary dictionary = new Dictionary(); List list = new List(); foreach (NewsEventDto newsEvent2 in data.NewsEvents) { if (newsEvent2 == null || newsEvent2.Type == "Identified" || num - newsEvent2.GameTime > num2) { continue; } if (newsEvent2.VictimId >= 0) { if (!hashSet.Contains(newsEvent2.VictimId) && (!dictionary.TryGetValue(newsEvent2.VictimId, out var value) || newsEvent2.GameTime >= value.GameTime)) { dictionary[newsEvent2.VictimId] = newsEvent2; } } else { list.Add(newsEvent2); } } List list2 = new List(); foreach (KeyValuePair item in dictionary) { AddCand(list2, item.Value); } foreach (NewsEventDto item2 in list) { AddCand(list2, item2); } if (data.ActiveWarrant) { NewsEventDto newsEventDto = NewestOfType("Identified"); bool flag = ((newsEventDto != null) ? (num - newsEventDto.GameTime) : 999f) <= 24f; list2.Add(new Cand { Prio = (flag ? 80 : 60), Time = (newsEventDto?.GameTime ?? num), VictimId = -1, Text = ComposeWanted(newsEventDto, flag) }); } List names; int num3 = RecentKillStats(out names); if (num3 >= (SyndicateConfig.NewsRoundupMinKills?.Value ?? 3)) { list2.Add(new Cand { Prio = 75, Time = num, VictimId = -2, Text = ComposeCrimeWave(num3, names, forceDemo: false) }); } if (list2.Count == 0) { return false; } list2.Sort((Cand a, Cand b) => (a.Prio == b.Prio) ? b.Time.CompareTo(a.Time) : b.Prio.CompareTo(a.Prio)); mainText = list2[0].Text; ConfigEntry newsSecondaryEnabled = SyndicateConfig.NewsSecondaryEnabled; if ((newsSecondaryEnabled == null || newsSecondaryEnabled.Value) && list2.Count > 1) { secText = list2[1].Text; } return !string.IsNullOrEmpty(mainText); } private static void AddCand(List cands, NewsEventDto e) { int num = PrioFor(e.Type); if (num > 0) { cands.Add(new Cand { Prio = num, Time = e.GameTime, VictimId = e.VictimId, Text = Compose(e) }); } } private static int PrioFor(string type) { return type switch { "Busted" => 92, "ColdCasesReopened" => 88, "RecordsStolen" => 85, "MaskedSuspect" => 65, "BodyFound" => 60, "SuicideRuled" => 58, "FallRuled" => 57, "CaseCold" => 50, "WarrantExpired" => 45, _ => 0, }; } private static int RecentKillStats(out List names) { names = new List(); SyndicateData data = Data; if (data?.NewsEvents == null) { return 0; } float num = Now(); float num2 = (float)(SyndicateConfig.NewsRoundupWindowDays?.Value ?? 3) * 24f; HashSet hashSet = new HashSet(); float num3 = -999f; int num4 = 0; for (int num5 = data.NewsEvents.Count - 1; num5 >= 0; num5--) { NewsEventDto newsEventDto = data.NewsEvents[num5]; if (newsEventDto != null && (!(newsEventDto.Type != "BodyFound") || !(newsEventDto.Type != "SuicideRuled") || !(newsEventDto.Type != "FallRuled") || !(newsEventDto.Type != "CaseCold") || !(newsEventDto.Type != "Identified")) && !(num - newsEventDto.GameTime > num2) && (newsEventDto.VictimId < 0 || hashSet.Add(newsEventDto.VictimId))) { num4++; if (newsEventDto.GameTime > num3) { num3 = newsEventDto.GameTime; } if (names.Count < 3) { names.Add(NonEmpty(newsEventDto.VictimName, "a local resident")); } } } if (num3 < 0f || num - num3 > 24f) { names = new List(); return 0; } return num4; } private static NewsEventDto NewestOfType(string type) { SyndicateData data = Data; if (data?.NewsEvents == null) { return null; } for (int num = data.NewsEvents.Count - 1; num >= 0; num--) { if (data.NewsEvents[num] != null && data.NewsEvents[num].Type == type) { return data.NewsEvents[num]; } } return null; } private static string Compose(NewsEventDto e) { return e.Type switch { "BodyFound" => ComposeBodyFound(e), "SuicideRuled" => ComposeSuicide(e), "FallRuled" => ComposeFall(e), "CaseCold" => ComposeCold(e), "MaskedSuspect" => ComposeMasked(e), "RecordsStolen" => ComposeRecords(e), "ColdCasesReopened" => ComposeReopened(e), "Busted" => ComposeBusted(), "WarrantExpired" => ComposeLapsed(e), _ => null, }; } private static string ComposeBodyFound(NewsEventDto e) { string value = V(e); string value2 = L(e); string value3 = D(e); string value4 = DayPhrase(e); if (e.Extra == "welfare") { return "WELFARE CHECK FINDS BODY\n" + $"A welfare check on {value} ended in grim discovery {value4}.\n\n" + $"Enforcers responding to concerns for the resident's wellbeing found {value} dead at {value2} in {value3}. " + "The scene has been sealed and an investigation opened. Anyone with information is urged to contact their local enforcer branch."; } return $"BODY FOUND AT {value2}\n{value} was found dead {value4} at {value2} in {value3}.\n\n" + "Enforcers have sealed the scene and an investigation is under way. Neighbours described the victim as quiet and keeping to themselves. Anyone with information is urged to contact their local enforcer branch without delay."; } private static string ComposeSuicide(NewsEventDto e) { string text = V(e); string value = L(e); string value2 = D(e); return "DEATH RULED AN OVERDOSE\nThe death of " + text + " has been ruled a self-inflicted overdose by enforcer investigators.\n\n" + $"The deceased was found at {value} in {value2} beside an empty bottle of prescription medication. Investigators found no signs of " + "forced entry and no evidence that another party was involved. The case has been closed."; } private static string ComposeFall(NewsEventDto e) { string text = V(e); string value = L(e); string value2 = D(e); return "DEATH RULED AN ACCIDENT\nThe death of " + text + " has been ruled an accidental fall by enforcer investigators.\n\n" + $"The deceased was found on the ground near {value} in {value2}, having fallen from height. Investigators found no signs of " + "a struggle and no evidence that another party was involved. The case has been closed."; } private static string ComposeCold(NewsEventDto e) { string value = V(e); string value2 = L(e); string value3 = D(e); string value4 = ((e.Extra == "traces") ? "Evidence recovered at the scene has yet to produce a match." : "The scene, sources say, was remarkably clean."); return $"NO SUSPECTS IN {value} KILLING\nThe investigation into the death of {value} has stalled, enforcer sources admit.\n\nDespite a sweep of the {value2} scene in {value3}, investigators have named no suspect and made no arrest. {value4} " + "The case file remains open but unassigned."; } private static string ComposeMasked(NewsEventDto e) { string value = V(e); string text = D(e); return $"MASKED FIGURE SOUGHT IN {value} CASE\nEnforcers are hunting an unidentified masked figure seen at the scene of {value}'s death.\n\n" + "Witnesses could offer no description of the suspect's face. Investigators concede the trail is thin: no name, and no warrant. Residents of " + text + " are asked to report sightings of suspicious masked individuals."; } private static string ComposeRecords(NewsEventDto e) { string text = NonEmpty(e.LocationName, "an enforcer division office"); return "RECORDS VANISH FROM ENFORCER DIVISION\nAn internal audit has discovered case files missing from " + text + ".\n\nThe missing folder contained physical evidence relating to several unsolved deaths. Sources describe the branch as embarrassed. An internal review is under way; no suspects, fittingly, have been identified."; } private static string ComposeReopened(NewsEventDto e) { string text = NonEmpty(e.Extra, "several"); return $"{text.ToUpperInvariant()} COLD CASES REOPENED\nEnforcer command has reopened {text} unsolved deaths after an evidence review.\n\n" + "Investigators say accumulated forensic material now points to a single individual. A warrant has been issued and back-fines assessed. We never really close a file, a spokesman said."; } private static string ComposeBusted() { string text = PlayerName(); return "SUSPECT IN CUSTODY\nThe manhunt is over: enforcers have apprehended their suspect.\n\n" + text + " was taken into custody following a confrontation with enforcer units. Outstanding fines have been assessed against the suspect's assets. The branch thanked the public for their vigilance."; } private static string ComposeLapsed(NewsEventDto e) { NewsEventDto newsEventDto = NewestOfType("Identified"); string text = ((newsEventDto != null) ? NonEmpty(newsEventDto.VictimName, "recent killings") : "recent killings"); return "TRAIL GOES COLD IN MANHUNT\nThe search for the suspect in the " + text + " case has been scaled back.\n\nAfter days without a confirmed sighting, enforcer command has reassigned patrol units. The warrant lapses unserved. They can't hide forever, one investigator insisted. The file joins a growing stack."; } private static string ComposeWanted(NewsEventDto idev, bool forceBreaking) { string text = ((idev != null) ? NonEmpty(idev.VictimName, "a recent killing") : "a recent killing"); string text2 = ((idev != null) ? NonEmpty(idev.District, "the city") : "the city"); string text3 = ((idev != null) ? (idev.Extra ?? "") : ""); string text4 = PlayerName(); int num = 0; try { num = ((Data != null) ? Data.WarrantMurderCount : 0); } catch { } string text5 = ((num >= 2) ? $"{num} killings" : "the killing"); if (!forceBreaking) { return "MANHUNT CONTINUES\nThe search for " + text4 + " enters another day.\n\nThe suspect remains wanted in connection with " + text5 + ". Citizens are advised not to approach. Enforcer patrols remain heavy across " + text2 + "."; } string text6 = (text3.Contains("witness") ? ("WITNESS NAMES SUSPECT IN " + text + " KILLING") : (text3.Contains("camera") ? "CAMERA FOOTAGE IDENTIFIES KILLER" : (text3.Contains("forensic") ? ("FORENSICS CRACK " + text + " CASE") : ((!text3.Contains("red-handed")) ? ("SUSPECT NAMED IN " + text + " KILLING") : "KILLER SURPRISED AT SCENE")))); return text6 + "\nEnforcers have issued a warrant in the killing of " + text + ".\n\n" + $"The suspect, named as {text4}, is wanted in connection with {text5}. Citizens are advised not to approach. " + "Enforcer patrols have been stepped up across " + text2 + "."; } private static string ComposeCrimeWave(int n, List victims, bool forceDemo) { string text = CityName(); if (forceDemo && n == 0) { victims = new List { "a dockworker", "a shopkeeper", "a clerk" }; n = 3; } int value = SyndicateConfig.NewsRoundupWindowDays?.Value ?? 3; string value2 = ((victims != null && victims.Count > 0) ? string.Join(", ", victims) : "several residents"); return $"DEATH STALKS {text.ToUpperInvariant()}\nA string of violent deaths has {text} on edge.\n\n{n} bodies in {value} days — {value2} — and the enforcer branch has yet to name a single suspect. The councilman's office " + "declined to comment on patrol funding. Street vendors report brisk sales of door chains and pepper spray."; } private static string ComposeTestStory() { string text = CityName(); return "SYNDICATE TEST HEADLINE\nA test story is running in " + text + "'s Herald.\n\nIf you can read this paragraph flowing across the columns of the physical newspaper, then the DDS message-and-block chain is rendering correctly through GenerateNewNewspaper and our Postfix, and the street news ticker should be carrying this headline. The quick brown fox jumps over the lazy dog again and again to fill three full columns of grey newsprint."; } private static string V(NewsEventDto e) { return NonEmpty(e.VictimName, "a local resident"); } private static string L(NewsEventDto e) { return NonEmpty(e.LocationName, "a city address"); } private static string D(NewsEventDto e) { return NonEmpty(e.District, "the city"); } private static string DayPhrase(NewsEventDto e) { try { int num = (int)((double)(Now() - e.GameTime) / 24.0); if (num <= 0) { return "today"; } if (num == 1) { return "yesterday"; } return "earlier this week"; } catch { return "recently"; } } private static string PlayerName() { try { string text = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).GetCitizenName() : null); if (!string.IsNullOrEmpty(text)) { return San(text); } } catch { } return "an unnamed suspect"; } private static string CityName() { try { string text = (((Object)(object)CityData.Instance != (Object)null) ? CityData.Instance.cityName : null); if (!string.IsNullOrEmpty(text)) { return San(text); } } catch { } return "the city"; } private static float Now() { try { return ((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.gameTime : 0f; } catch { return 0f; } } private static string NonEmpty(string s, string fallback) { if (!string.IsNullOrEmpty(s)) { return s; } return fallback; } private static string San(string s) { if (!string.IsNullOrEmpty(s)) { return s.Replace("|", ""); } return ""; } internal static void DebugForceTest() { DebugForceTestStory = true; DebugForceStory = null; RegenerateNow(); Plugin.Logger.LogInfo((object)"[News] Debug: forced TEST story; paper regenerated. Open/read a physical newspaper to verify."); } internal static void DebugToggleForce(string story) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown DebugForceTestStory = false; DebugForceStory = ((DebugForceStory == story) ? null : story); RegenerateNow(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] Debug: force story = "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DebugForceStory ?? "off (live selection)"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger.LogInfo(val); } internal static void ClearForced() { DebugForceTestStory = false; DebugForceStory = null; _bakedMain = "THE SYNDICATE\nNo Syndicate news today.\n\nThis placeholder should never appear on a live paper."; _bakedSecondary = ""; try { SyndicateData data = Data; if (data != null) { data.NewsBakedMain = ""; data.NewsBakedSecondary = ""; } } catch { } RegenerateNow(); Plugin.Logger.LogInfo((object)"[News] Debug: cleared forced story; paper regenerated (live selection / vanilla)."); } internal static void ClearEvents() { try { if (Data?.NewsEvents != null) { Data.NewsEvents.Clear(); } } catch { } RegenerateNow(); Plugin.Logger.LogInfo((object)"[News] Debug: news event ring cleared."); } internal static void DebugSeed(string type, string extra = "") { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown try { Citizen val = PickRandomCitizen(); int victimId = -1; string victimName = "a local resident"; string text = ""; string district = ""; if ((Object)(object)val != (Object)null) { victimId = ((Human)val).humanID; try { victimName = ((Human)val).GetCitizenName(); } catch { } try { NewAddress home = ((Human)val).home; if ((Object)(object)home != (Object)null) { try { text = ((Object)home).name; } catch { } try { if ((Object)(object)((NewGameLocation)home).district != (Object)null) { district = ((Object)((NewGameLocation)home).district).name; } } catch { } } } catch { } } if (type == "RecordsStolen") { victimId = -1; victimName = ""; text = NonEmpty(text, "Beta Enforcer Division"); } switch (type) { case "ColdCasesReopened": case "Busted": case "WarrantExpired": victimId = -1; victimName = ""; text = ""; district = ""; break; } Push(type, victimId, victimName, text, district, extra); RegenerateNow(); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(27, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[News] DebugSeed("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(type); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } } private static Citizen PickRandomCitizen() { try { List val = (((Object)(object)CityData.Instance != (Object)null) ? CityData.Instance.citizenDirectory : null); if (val == null || val.Count == 0) { return null; } int num = Random.Range(0, val.Count); for (int i = 0; i < val.Count; i++) { Citizen val2 = val[(num + i) % val.Count]; if ((Object)(object)val2 != (Object)null) { return val2; } } } catch { } return null; } internal static void RequestRegen() { _regenPending = true; } internal static void Tick() { if (_regenPending) { RegenerateNow(); } } internal static void RegenerateNow() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown _regenPending = false; try { NewspaperController instance = NewspaperController.Instance; if ((Object)(object)instance == (Object)null) { Plugin.Logger.LogWarning((object)"[News] RegenerateNow: no NewspaperController yet."); } else { instance.GenerateNewNewspaper(); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] RegenerateNow failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static void DumpState() { //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Expected O, but got Unknown //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Expected O, but got Unknown //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown bool flag = default(bool); try { NewspaperController instance = NewspaperController.Instance; if ((Object)(object)instance == (Object)null || instance.currentState == null) { Plugin.Logger.LogInfo((object)"[News] DumpState: no paper yet."); return; } NewspaperState currentState = instance.currentState; Plugin.Logger.LogInfo((object)"[News] ---- paper state ----"); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] murderID="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentState.murderID); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" forceTest="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DebugForceTestStory); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" forceStory="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DebugForceStory ?? "off"); } logger.LogInfo(val); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] main msg='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentState.mainArticle); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ctx="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentState.mainContext); } logger2.LogInfo(val); ManualLogSource logger3 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] art2 msg='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentState.article2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ctx="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentState.art2Context); } logger3.LogInfo(val); ManualLogSource logger4 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] art3 msg='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentState.article3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ctx="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentState.art3Context); } logger4.LogInfo(val); SyndicateData data = Data; int valueOrDefault = (data?.NewsEvents?.Count).GetValueOrDefault(); ManualLogSource logger5 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] ring: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(valueOrDefault); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" event(s)"); } logger5.LogInfo(val); if (data?.NewsEvents != null) { float num = Now(); foreach (NewsEventDto newsEvent in data.NewsEvents) { ManualLogSource logger6 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(37, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(newsEvent.Type.PadRight(16)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" age="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num - newsEvent.GameTime, "0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("d victim='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(newsEvent.VictimName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'(#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(newsEvent.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") extra='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(newsEvent.Extra); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); } logger6.LogInfo(val); } } try { string textForComponent = Strings.GetTextForComponent(currentState.mainArticle, (Object)null, (Human)null, (Human)null, "\n", false, (Object)null, (LinkSetting)2, (List)null); ManualLogSource logger7 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[News] main resolved: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Trunc(textForComponent, 320)); } logger7.LogInfo(val); } catch (Exception ex) { ManualLogSource logger8 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[News] main resolve failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger8.LogWarning(val2); } Plugin.Logger.LogInfo((object)"[News] ----------------------"); } catch (Exception ex2) { ManualLogSource logger9 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[News] DumpState failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.Message); } logger9.LogWarning(val2); } } private static string Trunc(string s, int n) { if (!string.IsNullOrEmpty(s)) { if (s.Length > n) { return s.Substring(0, n) + "…"; } return s; } return ""; } } } namespace TheSyndicate.Money { internal static class FineLedger { private static List Fines => SyndicateState.Data.Fines; private static int MinBalance => SyndicateConfig.FineMinimumBalance?.Value ?? 5; private static int PayoffPct => SyndicateConfig.FineEarlyPayoffPercent?.Value ?? 60; public static int Outstanding { get { int num = 0; foreach (FineRecordDto fine in Fines) { num += Math.Max(0, fine.Amount - fine.Paid); } return num; } } public static int UnpaidCount { get { int num = 0; foreach (FineRecordDto fine in Fines) { if (fine.Amount - fine.Paid > 0) { num++; } } return num; } } public static void AddFine(string victimName, int victimId, int amount, string reason) { if (amount > 0) { string text = AddRecord(victimName, victimId, amount, reason); if (text != null) { Notify($"A {amount}cr bounty-fine has been logged against you for {text}."); } } } private static string AddRecord(string victimName, int victimId, int amount, string reason) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown if (amount <= 0) { return null; } bool flag = default(bool); try { string text = (string.IsNullOrEmpty(victimName) ? "a victim" : victimName); Fines.Add(new FineRecordDto { VictimId = victimId, VictimName = text, Amount = amount, Paid = 0, Issued = SafeNow(), Reason = (reason ?? "") }); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(45, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Fines] +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(amount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr fine for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(text, victimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("). Outstanding now "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Outstanding); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr."); } logger.LogInfo(val); return text; } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Fines] AddRecord failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); return null; } } public static void Surcharge(string victimName, int victimId, int amount, string reason) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown if (amount <= 0) { return; } bool flag = default(bool); try { foreach (FineRecordDto fine in Fines) { if (fine.VictimId == victimId && fine.Amount - fine.Paid > 0) { fine.Amount += amount; ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Fines] +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(amount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr surcharge on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(fine.VictimName, fine.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("). Outstanding now "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Outstanding); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr."); } logger.LogInfo(val); return; } } AddRecord(victimName, victimId, amount, reason); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Fines] Surcharge failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } internal static bool TryGetNewestUnpaid(out string victimName, out int victimId) { victimName = null; victimId = -1; for (int num = Fines.Count - 1; num >= 0; num--) { FineRecordDto fineRecordDto = Fines[num]; if (fineRecordDto != null && fineRecordDto.Amount - fineRecordDto.Paid > 0) { victimName = fineRecordDto.VictimName; victimId = fineRecordDto.VictimId; return true; } } return false; } public static int CollectOnBust() { //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown bool flag = default(bool); try { int outstanding = Outstanding; if (outstanding <= 0) { return 0; } GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null) { return 0; } int money = instance.money; int num = Math.Min(outstanding, Math.Max(0, money - MinBalance)); if (num > 0) { instance.AddMoney(-num, true, "Murder fines"); Allocate(num); } int outstanding2 = Outstanding; Notify((outstanding2 > 0) ? $"The court seized {num}cr. {outstanding2}cr in fines remain on your record until you pay them." : $"The court seized {num}cr — your fines are settled."); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(48, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Fines] CollectOnBust: owed "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(outstanding); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", paid "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", remaining "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(outstanding2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger.LogInfo(val); return num; } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Fines] CollectOnBust failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); return 0; } } public static bool SettleEarly() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown bool flag = default(bool); try { int outstanding = Outstanding; if (outstanding <= 0) { Notify("You have no outstanding fines."); return false; } GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null) { return false; } int num = Math.Max(1, (int)Math.Round((double)(outstanding * PayoffPct) / 100.0)); if (instance.money - num < MinBalance) { Notify($"Settling your fines early costs {num}cr — you can't cover it right now."); return false; } instance.AddMoney(-num, true, "Fine settlement"); Fines.Clear(); Notify($"Settled {outstanding}cr in fines for {num}cr. Your record is clean."); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Fines] Settled "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(outstanding); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(PayoffPct); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("%)."); } logger.LogInfo(val); return true; } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Fines] SettleEarly failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); return false; } } public static string HudLine() { int outstanding = Outstanding; if (outstanding <= 0) { return ""; } int unpaidCount = UnpaidCount; return $"Fines outstanding: {outstanding:n0}cr ({unpaidCount} unpaid) — settle for {PayoffPct}% before capture"; } public static List ItemizedLines() { List list = new List(); foreach (FineRecordDto fine in Fines) { int num = fine.Amount - fine.Paid; if (num > 0) { list.Add($"{fine.VictimName}: {num:n0}cr ({fine.Reason})"); } } return list; } private static void Allocate(int amount) { for (int i = 0; i < Fines.Count; i++) { if (amount <= 0) { break; } int num = Fines[i].Amount - Fines[i].Paid; if (num > 0) { int num2 = Math.Min(num, amount); Fines[i].Paid += num2; amount -= num2; } } Fines.RemoveAll((FineRecordDto f) => f.Amount - f.Paid <= 0); } private static string SafeNow() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) try { TimeData currentDateTime = Lib.Time.CurrentDateTime; return ((TimeData)(ref currentDateTime)).Serialize(); } catch { return ""; } } private static void Notify(string text) { try { MessageQueue.Enqueue(text); } catch { } } } } namespace TheSyndicate.Mask { public class MaskHotkey : MonoBehaviour { private const float DreadInterval = 0.5f; private static float _nextDreadTime; public MaskHotkey(IntPtr ptr) : base(ptr) { } private void Update() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) try { if (InPlay()) { ConfigEntry maskToggleKey = SyndicateConfig.MaskToggleKey; KeyCode val = (KeyCode)((maskToggleKey == null) ? 110 : ((int)maskToggleKey.Value)); if ((int)val != 0 && Input.GetKeyDown(val)) { ToggleMask(); } if (SyndicateState.MaskActive && Time.time >= _nextDreadTime) { _nextDreadTime = Time.time + 0.5f; ApplyMaskDread(); } } } catch { } } private static void ToggleMask() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = SyndicateState.Data; if (!data.MaskDiskInstalled) { Lib.GameMessage.Broadcast("You have no False Face disk installed — bond one at a sync clinic first.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); return; } data.IsWearingMask = !data.IsWearingMask; Lib.GameMessage.Broadcast(data.IsWearingMask ? "False Face on — witnesses can't name you. But a covered face makes people nervous." : "False Face off — you're showing your real face again.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Mask] IsWearingMask -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.IsWearingMask); } logger.LogInfo(val); if (!data.IsWearingMask) { CrimeSceneManager.OnPlayerUnmasked(); } else { OnboardingController.OnMaskEquipped(); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Mask] ToggleMask failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static void ApplyMaskDread() { //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) try { ConfigEntry maskScareEnabled = SyndicateConfig.MaskScareEnabled; if (maskScareEnabled != null && !maskScareEnabled.Value) { return; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } float num = SyndicateConfig.MaskScareNerve?.Value ?? (-0.05f); if (num >= 0f) { return; } float num2 = Mathf.Max(0.5f, SyndicateConfig.MaskScareRange?.Value ?? 8f); bool flag = SyndicateConfig.MaskScareEnforcers?.Value ?? false; NewRoom currentRoom = ((Actor)instance).currentRoom; HashSet val = (((Object)(object)currentRoom != (Object)null) ? currentRoom.currentOccupants : null); if (val == null) { return; } float num3 = num2 * num2; Vector3 position = ((Component)instance).transform.position; List list = new List(); Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Actor current = enumerator.Current; if ((Object)(object)current == (Object)null || current.isPlayer || current.isDead) { continue; } try { if (flag) { goto IL_0113; } Human val2 = ((Il2CppObjectBase)current).TryCast(); if (!((Object)(object)val2 != (Object)null) || !((Actor)val2).isEnforcer) { goto IL_0113; } goto end_IL_00f2; IL_0113: Vector3 val3 = ((Component)current).transform.position - position; if (((Vector3)(ref val3)).sqrMagnitude <= num3) { list.Add(current); } end_IL_00f2:; } catch { } } bool enabled = MaskNotoriety.Enabled; float num4 = (enabled ? MaskNotoriety.Value : 0f); float num5 = SyndicateConfig.MaskNerveDrainMult?.Value ?? 4f; foreach (Actor item in list) { try { float num6; if (!enabled) { num6 = 1f; } else { bool flag2 = num4 > 0.02f && CrimeSceneManager.SeesPlayer(item); num6 = 0.1f + 0.9f * num4 + (flag2 ? (num5 * num4) : 0f); } item.AddNerve(num * num6, (Actor)(object)instance); } catch { } } } catch { } } private static bool InPlay() { try { if ((Object)(object)SessionData.Instance == (Object)null || !SessionData.Instance.play) { return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || ((Actor)instance).isDead) { return false; } if (instance.computerInteractable != null) { return false; } return true; } catch { return false; } } } public static class MaskNotoriety { private static readonly Dictionary _softStopCooldowns = new Dictionary(); private static bool _softStopToastShown; public static float Value => Mathf.Clamp01(SyndicateState.Data?.MaskNotoriety ?? 0f); public static bool HasUnmergedIncidents { get { List list = SyndicateState.Data?.MaskedIncidents; if (list == null) { return false; } for (int i = 0; i < list.Count; i++) { MaskedIncidentDto maskedIncidentDto = list[i]; if (maskedIncidentDto != null && !maskedIncidentDto.Merged) { return true; } } return false; } } internal static bool Enabled => SyndicateConfig.MaskNotorietyEnabled?.Value ?? true; public static void ResetSession() { _softStopCooldowns.Clear(); _softStopToastShown = false; } internal static void OnMaskedIncident(CrimeScene s, string channel, int extraSeers) { //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown bool flag = default(bool); try { if (!Enabled) { return; } SyndicateData data = SyndicateState.Data; if (data != null && s != null) { float maskNotoriety = data.MaskNotoriety; data.MaskNotoriety = Mathf.Clamp01(data.MaskNotoriety + BrazennessAdd(s, extraSeers)); SyndicateData syndicateData = data; if (syndicateData.MaskedIncidents == null) { List list = (syndicateData.MaskedIncidents = new List()); } data.MaskedIncidents.Add(new MaskedIncidentDto { VictimId = s.VictimId, VictimName = (s.VictimName ?? ""), LocKey = s.LocKey, LocationName = (s.LocationName ?? ""), At = SafeNow(), Channel = (channel ?? ""), NotorietyAdded = data.MaskNotoriety - maskNotoriety, Merged = false }); if (string.IsNullOrEmpty(data.MaskNotorietyDecayStamp)) { data.MaskNotorietyDecayStamp = SafeNow(); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(65, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] masked incident ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(channel); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskNotoriety - maskNotoriety, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> notoriety "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskNotoriety, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskedIncidents.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" incident(s))."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Persona] OnMaskedIncident failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static float BrazennessAdd(CrimeScene s, int extraSeers) { float num = SyndicateConfig.MaskIncidentBase?.Value ?? 0.1f; float num2 = SyndicateConfig.MaskWitnessWeight?.Value ?? 0.15f; float num3 = SyndicateConfig.MaskPublicPlaceMult?.Value ?? 1.5f; float num4 = SyndicateConfig.MaskDaytimeMult?.Value ?? 1.25f; float num5 = SyndicateConfig.MaskIncidentMax?.Value ?? 0.3f; int num6 = (s.Witnesses?.Count ?? 0) + Mathf.Max(0, extraSeers); return Mathf.Min(num * (1f + num2 * (float)Mathf.Clamp(num6 - 1, 0, 4)) * (IsPublic(s) ? num3 : 1f) * (IsDaytime() ? num4 : 1f), num5); } private static bool IsPublic(CrimeScene s) { try { NewGameLocation location = s.Location; if ((Object)(object)location == (Object)null) { return true; } if ((Object)(object)location.thisAsAddress == (Object)null) { return true; } if (location.isLobby) { return true; } } catch { } return false; } private static bool IsDaytime() { try { float num = (((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.decimalClock : 12f); return num >= 7f && num < 21f; } catch { return true; } } public static void Tick() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown try { if (Enabled) { SyndicateData data = SyndicateState.Data; if (data != null && !SyndicateState.IsWorldLoading) { DecayTick(data); EnforcerSoftStopTick(data); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(23, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] Tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void DecayTick(SyndicateData d) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) try { List maskedIncidents = d.MaskedIncidents; if (maskedIncidents != null && maskedIncidents.Count > 32) { for (int num = maskedIncidents.Count - 1; num >= 0; num--) { MaskedIncidentDto maskedIncidentDto = maskedIncidents[num]; if (maskedIncidentDto == null || maskedIncidentDto.Merged) { maskedIncidents.RemoveAt(num); } } } if (d.MaskNotoriety <= 0f) { d.MaskNotorietyDecayStamp = SafeNow(); return; } if (string.IsNullOrEmpty(d.MaskNotorietyDecayStamp)) { d.MaskNotorietyDecayStamp = SafeNow(); return; } double totalHours; try { totalHours = (Lib.Time.CurrentDateTime - TimeData.Deserialize(d.MaskNotorietyDecayStamp)).TotalHours; } catch { d.MaskNotorietyDecayStamp = SafeNow(); return; } if (totalHours <= 0.0) { d.MaskNotorietyDecayStamp = SafeNow(); return; } float num2 = (SyndicateConfig.MaskNotorietyDecayPerDay?.Value ?? 0.15f) * (float)(totalHours / 24.0); if (num2 > 0f) { d.MaskNotoriety = Mathf.Clamp01(d.MaskNotoriety - num2); d.MaskNotorietyDecayStamp = SafeNow(); } } catch { } } private static void EnforcerSoftStopTick(SyndicateData d) { //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected O, but got Unknown //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) bool flag2 = default(bool); try { ConfigEntry maskEnforcerSoftStopEnabled = SyndicateConfig.MaskEnforcerSoftStopEnabled; if (maskEnforcerSoftStopEnabled == null || !maskEnforcerSoftStopEnabled.Value || !SyndicateState.MaskActive || d.ActiveWarrant) { return; } float value = Value; if (value < (SyndicateConfig.MaskEnforcerSoftStopThreshold?.Value ?? 0.5f)) { return; } GameplayController instance = GameplayController.Instance; Player instance2 = Player.Instance; if ((Object)(object)instance == (Object)null || instance.enforcers == null || (Object)(object)instance2 == (Object)null || ((Actor)instance2).isHiding) { return; } Interactable interactable = ((Actor)instance2).interactable; if (interactable == null) { return; } Vector3 position = ((Component)instance2).transform.position; float num = Mathf.Max(1f, SyndicateConfig.MaskEnforcerSoftStopRange?.Value ?? 12f); float num2 = num * num; float num3 = SyndicateConfig.MaskEnforcerSoftStopCooldownSeconds?.Value ?? 90f; int num4 = ((value >= 0.85f) ? 1 : 0); Enumerator enumerator = instance.enforcers.GetEnumerator(); RaycastHit val2 = default(RaycastHit); while (enumerator.MoveNext()) { Human current = enumerator.Current; if ((Object)(object)current == (Object)null || ((Actor)current).isDead) { continue; } NewAIController ai = ((Actor)current).ai; if ((Object)(object)ai == (Object)null || ai.ko) { continue; } try { if (ai.persuit && (Object)(object)ai.persuitTarget != (Object)null && ai.persuitTarget.isPlayer) { continue; } } catch { } float sqrMagnitude; try { Vector3 val = ((Component)current).transform.position - position; sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; } catch { continue; } if (sqrMagnitude > num2) { continue; } bool flag = false; try { flag = ((Actor)current).CanISee(interactable); } catch { } if (!flag) { continue; } try { if (!((Actor)current).ActorRaycastCheck((Actor)(object)instance2, num, ref val2, false, default(Color), default(Color), default(Color), 0f)) { continue; } } catch { } int humanID = current.humanID; if (_softStopCooldowns.TryGetValue(humanID, out var value2) && Time.time - value2 < num3) { continue; } _softStopCooldowns[humanID] = Time.time; try { ai.Investigate(((Actor)instance2).currentNode, ((Component)instance2).transform.position, (Actor)(object)instance2, (ReactionState)1, 5f, num4, false, 1f, (Interactable)null); } catch { } if (!_softStopToastShown) { _softStopToastShown = true; try { Lib.GameMessage.Broadcast("Enforcers are eyeing the mask — the persona's too hot to walk around in now.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(67, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Persona] enforcer soft-stop: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(humanID); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" eyeing the masked player (N="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(value, "P0"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", esc="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num4); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")."); } logger.LogInfo(val3); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Persona] EnforcerSoftStopTick failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); } } internal static void OnVictimIdentified(int victimId) { try { List list = SyndicateState.Data?.MaskedIncidents; if (list == null) { return; } for (int i = 0; i < list.Count; i++) { MaskedIncidentDto maskedIncidentDto = list[i]; if (maskedIncidentDto != null && maskedIncidentDto.VictimId == victimId && !maskedIncidentDto.Merged) { maskedIncidentDto.Merged = true; } } } catch { } } internal static void MergeOnSlip(string reason, bool viaBust) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown bool flag = default(bool); try { if (!Enabled) { return; } SyndicateData data = SyndicateState.Data; if (data == null) { return; } try { CrimeSceneManager.MergeResolveMaskedScenes(reason, viaBust); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] merge open scenes failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } int num = 0; List maskedIncidents = data.MaskedIncidents; if (maskedIncidents != null && maskedIncidents.Count > 0) { List list = new List(); for (int num2 = maskedIncidents.Count - 1; num2 >= 0; num2--) { MaskedIncidentDto maskedIncidentDto = maskedIncidents[num2]; if (maskedIncidentDto != null && !maskedIncidentDto.Merged) { list.Add(maskedIncidentDto); } } if (list.Count > 0) { float value = Value; float num3 = SyndicateConfig.MaskMergeMinColdShare?.Value ?? 0.25f; float num4 = Mathf.Clamp01(num3 + (1f - num3) * value); int num5 = Mathf.Clamp(Mathf.RoundToInt((float)list.Count * num4), 1, list.Count); if (num5 > 0) { int num6 = SyndicateConfig.MaskMergeFineBasePercent?.Value ?? 50; int num7 = SyndicateConfig.MaskMergeFineNotorietyPercent?.Value ?? 50; int num8 = SyndicateConfig.MurderFineAmount?.Value ?? 2000; int amount = Mathf.Max(0, (int)((float)num8 * ((float)num6 + (float)num7 * value) / 100f)); string victimName = list[0].VictimName; try { ManhuntController.StartHuntNow(string.IsNullOrEmpty(victimName) ? "your masked crimes" : victimName, viaBust ? "The law pulled the mask off you in custody — they've got you for the lot." : ("The mask came off — " + reason + ". Your masked killings just got a name: yours. A warrant is out for all of them.")); } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] merge warrant failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2.Message); } logger2.LogWarning(val); } for (int i = 0; i < num5; i++) { MaskedIncidentDto maskedIncidentDto2 = list[i]; try { ManhuntController.RegisterIdentifiedMurder(maskedIncidentDto2.LocKey); } catch { } try { FineLedger.AddFine(maskedIncidentDto2.VictimName, maskedIncidentDto2.VictimId, amount, "masked spree merged — " + reason); } catch { } try { ManhuntController.ApplySyndicatePenalty(maskedIncidentDto2.VictimId); } catch { } maskedIncidentDto2.Merged = true; num++; ReleaseResidualContribution(data, maskedIncidentDto2.VictimId); } } } } data.MaskNotoriety = 0f; data.MaskNotorietyDecayStamp = SafeNow(); ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(69, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Persona] SLIP ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", bust="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(viaBust); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("): merged "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" cold incident(s); notoriety zeroed."); } logger3.LogInfo(val2); } catch (Exception ex3) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] MergeOnSlip failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex3.Message); } logger4.LogWarning(val); } } private static void ReleaseResidualContribution(SyndicateData d, int victimId) { try { List residualHeatContributors = d.ResidualHeatContributors; if (residualHeatContributors == null || victimId < 0) { return; } for (int num = residualHeatContributors.Count - 1; num >= 0; num--) { ResidualHeatContributionDto residualHeatContributionDto = residualHeatContributors[num]; if (residualHeatContributionDto != null && residualHeatContributionDto.VictimId == victimId) { d.ResidualHeat = Mathf.Clamp01(d.ResidualHeat - residualHeatContributionDto.Amount); residualHeatContributors.RemoveAt(num); } } } catch { } } internal static void DestroyMask() { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown bool flag3 = default(bool); try { SyndicateData data = SyndicateState.Data; if (data == null) { return; } try { UpgradesController instance = UpgradesController.Instance; if ((Object)(object)instance != (Object)null && instance.upgrades != null) { IntPtr intPtr = IntPtr.Zero; try { SyncDisk maskDisk = Rewards.MaskDisk; SyncDiskPreset val = ((maskDisk != null) ? maskDisk.Preset : null); if ((SoCustomComparison)(object)val != (SoCustomComparison)null) { intPtr = ((Il2CppObjectBase)val).Pointer; } } catch { } bool flag = false; for (int i = 0; i < instance.upgrades.Count; i++) { Upgrades val2 = instance.upgrades[i]; if (val2 != null) { bool num = intPtr != IntPtr.Zero && (SoCustomComparison)(object)val2.preset != (SoCustomComparison)null && ((Il2CppObjectBase)val2.preset).Pointer == intPtr; bool flag2 = val2.upgrade == "False Face"; if (num || flag2) { instance.UninstallSyncDisk(val2); flag = true; Plugin.Logger.LogInfo((object)"[Persona] mask disk record uninstalled (native)."); break; } } } if (!flag) { Plugin.Logger.LogWarning((object)"[Persona] no installed mask-disk record found — clearing flags only."); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Persona] UninstallSyncDisk failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); } data.MaskDiskInstalled = false; data.IsWearingMask = false; Plugin.Logger.LogInfo((object)"[Persona] the False Face is gone — you'll need a new mask."); } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Persona] DestroyMask failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2.Message); } logger2.LogWarning(val3); } } internal static bool CanRedisguise(out string reason) { reason = null; SyndicateData data = SyndicateState.Data; if (data == null) { reason = "Not ready."; return false; } if (!Enabled) { reason = "Persona services are offline."; return false; } if (!data.MaskDiskInstalled) { reason = "You need a mask before a tailor can retire its persona."; return false; } if (Value < 0.05f) { reason = "Your masked persona is already cold — nothing worth retiring."; return false; } return true; } internal static void Redisguise() { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown bool flag2 = default(bool); try { SyndicateData data = SyndicateState.Data; if (data == null) { return; } float num = SyndicateConfig.MaskRedisguiseDrop?.Value ?? 1f; float maskNotoriety = data.MaskNotoriety; data.MaskNotoriety = Mathf.Clamp01(data.MaskNotoriety - num); data.MaskNotorietyDecayStamp = SafeNow(); bool flag = SyndicateConfig.MaskRedisguiseClearsHistory?.Value ?? false; if (flag) { data.MaskedIncidents?.Clear(); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(48, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] re-disguise: notoriety "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskNotoriety, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskNotoriety, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; history "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag ? "WIPED" : "kept"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger.LogInfo(val); try { Lib.GameMessage.Broadcast(flag ? "The tailor retires your masked persona — new geometry, clean slate. The figure never existed." : "The tailor retires your masked persona — new geometry, cold trail. The street forgets the figure. The case files don't.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Persona] Redisguise failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static string SafeNow() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) try { TimeData currentDateTime = Lib.Time.CurrentDateTime; return ((TimeData)(ref currentDateTime)).Serialize(); } catch { return ""; } } public static void DebugDump() { //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = SyndicateState.Data; if (data == null) { Plugin.Logger.LogInfo((object)"[Persona] no data."); return; } List maskedIncidents = data.MaskedIncidents; int num = 0; if (maskedIncidents != null) { for (int i = 0; i < maskedIncidents.Count; i++) { if (maskedIncidents[i] != null && !maskedIncidents[i].Merged) { num++; } } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(65, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] notoriety="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskNotoriety, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stamp='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskNotorietyDecayStamp); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' incidents="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidents?.Count ?? 0); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (unmerged "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") bustPending="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskedBustPending); } logger.LogInfo(val); if (maskedIncidents == null) { return; } for (int j = 0; j < maskedIncidents.Count; j++) { MaskedIncidentDto maskedIncidentDto = maskedIncidents[j]; if (maskedIncidentDto != null) { ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(37, 7, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidentDto.Channel.PadRight(8)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidentDto.VictimName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidentDto.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") loc='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidentDto.LocationName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidentDto.NotorietyAdded, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidentDto.At); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" merged="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(maskedIncidentDto.Merged); } logger2.LogInfo(val); } } } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Persona] DebugDump failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger3.LogWarning(val2); } } public static void DebugAddIncident() { //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = SyndicateState.Data; if (data == null) { return; } Player instance = Player.Instance; long locKey = 0L; string text = "(debug)"; try { if ((Object)(object)instance != (Object)null && (Object)(object)((Actor)instance).currentGameLocation != (Object)null) { locKey = StableIds.LocationKey(((Actor)instance).currentGameLocation); text = ((Object)((Actor)instance).currentGameLocation).name; } } catch { } SyndicateData syndicateData = data; if (syndicateData.MaskedIncidents == null) { List list = (syndicateData.MaskedIncidents = new List()); } float maskNotoriety = data.MaskNotoriety; data.MaskNotoriety = Mathf.Clamp01(data.MaskNotoriety + (SyndicateConfig.MaskIncidentBase?.Value ?? 0.1f)); data.MaskedIncidents.Add(new MaskedIncidentDto { VictimId = -1, VictimName = "(debug victim)", LocKey = locKey, LocationName = text, At = SafeNow(), Channel = "debug", NotorietyAdded = data.MaskNotoriety - maskNotoriety, Merged = false }); if (string.IsNullOrEmpty(data.MaskNotorietyDecayStamp)) { data.MaskNotorietyDecayStamp = SafeNow(); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Persona] debug incident added at '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' -> notoriety "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.MaskNotoriety, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Persona] DebugAddIncident failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } } } namespace TheSyndicate.Heat { internal sealed class Witness { public int HumanId; public string Name = ""; public bool SawKill; public string ReportDue = ""; public bool Counted; public bool MaskedAtSighting; } internal sealed class CrimeScene { public int VictimId; public string VictimName = ""; public Human Victim; public NewGameLocation Location; public long LocKey; public string LocationName = ""; public List Witnesses = new List(); public Interactable Weapon; public int WeaponId = -1; public string WeaponName = ""; public bool WeaponHadPlayerPrintAtKill; public bool Discovered; public bool Resolved; public SuspicionState Result; public bool MaskedDescriptionReported; public float NextMaskedPersueAt; public bool ForgedOverdose; public bool ForgedFall; public bool ForgeWasViolent; public int BaselineDiscoveredBy = int.MinValue; public bool NativeReported; public string WelfareExpires = ""; public string ColdExpires = ""; public string KillAt = ""; public bool WelfareRaidDispatched; public string WelfareRaidFallbackDue = ""; public bool Tipped; public bool CameraNearNoted; public bool CameraNearRecorded; public string CameraNearHeatDue = ""; public bool CameraNearStaleLogged; public bool PlayerInsideNoticed; } internal static class CrimeSceneManager { public enum SceneStatus { Undiscovered, Investigating, GoingCold } public readonly struct SceneRow { public readonly string Name; public readonly SceneStatus Status; public readonly int HoursLeft; public readonly bool PayoutPending; public SceneRow(string name, SceneStatus status, int hoursLeft, bool payoutPending) { Name = name; Status = status; HoursLeft = hoursLeft; PayoutPending = payoutPending; } } private enum ScenePresence { AtScene, Away, Unknown } private enum CameraSee { Killing, AtScene, Unmask } private static readonly List Active = new List(); private static readonly HashSet ResolvedVictims = new HashSet(); private static readonly Random Rng = new Random(); private const float WelfareRaidGraceHours = 3f; private static NewGameLocation _cameraSweepLoc; private static EnforcerCall _cameraSweepCall; private static string _cameraSweepDeadline = ""; private static int ReportMinH => SyndicateConfig.WitnessReportMinHours?.Value ?? 2; private static int ReportMaxH => SyndicateConfig.WitnessReportMaxHours?.Value ?? 6; private static int WelfareMinH => SyndicateConfig.WelfareMinHours?.Value ?? 24; private static int WelfareMaxH => SyndicateConfig.WelfareMaxHours?.Value ?? 48; private static int ColdH => SyndicateConfig.SceneColdHours?.Value ?? 8; private static int WitnessInterviewH => SyndicateConfig.WitnessInterviewHours?.Value ?? 2; private static int FpIdHeat => SyndicateConfig.FingerprintIdHeatThreshold?.Value ?? 25; private static int FpIdCount => SyndicateConfig.FingerprintIdCountThreshold?.Value ?? 4; public static int ActiveCount => Active.Count; public static int UnreportedCount { get { int num = 0; foreach (CrimeScene item in Active) { if (!item.Discovered) { num++; } } return num; } } public static int WitnessCount { get { int num = 0; foreach (CrimeScene item in Active) { foreach (Witness witness in item.Witnesses) { if (!witness.Counted) { num++; } } } return num; } } public static List SnapshotForHud(int max, out int total) { List list = new List(); total = 0; try { for (int num = Active.Count - 1; num >= 0; num--) { CrimeScene crimeScene = Active[num]; if (crimeScene != null && !crimeScene.Resolved) { total++; if (list.Count < max) { bool payoutPending = false; try { payoutPending = ContractManager.IsAwaitingForensics(crimeScene.VictimId); } catch { } list.Add(new SceneRow(SceneDisplayName(crimeScene), StatusOf(crimeScene), HoursLeftOf(crimeScene), payoutPending)); } } } } catch { } return list; } private static SceneStatus StatusOf(CrimeScene s) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!s.Discovered) { return SceneStatus.Undiscovered; } try { double totalHours = (TimeData.Deserialize(s.ColdExpires) - Lib.Time.CurrentDateTime).TotalHours; double num = ((ColdH < 1) ? 1 : ColdH); if (totalHours <= 0.4 * num) { return SceneStatus.GoingCold; } } catch { } return SceneStatus.Investigating; } private static int HoursLeftOf(CrimeScene s) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (s == null || !s.Discovered) { return -1; } try { double num = (TimeData.Deserialize(s.ColdExpires) - Lib.Time.CurrentDateTime).TotalHours; if (num < 0.0) { num = 0.0; } return (int)Math.Ceiling(num); } catch { return -1; } } private static string SceneDisplayName(CrimeScene s) { if (s != null && !string.IsNullOrEmpty(s.VictimName)) { return s.VictimName; } return SafeName(s?.Victim); } public static bool PlayerInsideAnyScene() { try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return false; } foreach (CrimeScene item in Active) { if (!item.Resolved && IsInsideScene((Actor)(object)instance, item)) { return true; } } } catch { } return false; } public static void Reset() { Active.Clear(); ResolvedVictims.Clear(); } public static List CaptureDtos() { List list = new List(); foreach (CrimeScene item in Active) { if (item.Resolved) { continue; } CrimeSceneDto crimeSceneDto = new CrimeSceneDto { VictimId = item.VictimId, VictimName = item.VictimName, LocKey = item.LocKey, LocationName = item.LocationName, WeaponId = item.WeaponId, WeaponName = item.WeaponName, WeaponHadPlayerPrintAtKill = item.WeaponHadPlayerPrintAtKill, Discovered = item.Discovered, BaselineDiscoveredBy = item.BaselineDiscoveredBy, NativeReported = item.NativeReported, WelfareExpires = item.WelfareExpires, ColdExpires = item.ColdExpires, KillAt = item.KillAt, WelfareRaidDispatched = item.WelfareRaidDispatched, WelfareRaidFallbackDue = item.WelfareRaidFallbackDue, MaskedDescriptionReported = item.MaskedDescriptionReported, ForgedOverdose = item.ForgedOverdose, ForgedFall = item.ForgedFall, CameraNearNoted = item.CameraNearNoted, CameraNearRecorded = item.CameraNearRecorded, CameraNearHeatDue = item.CameraNearHeatDue, ForgeWasViolent = item.ForgeWasViolent }; foreach (Witness witness in item.Witnesses) { crimeSceneDto.Witnesses.Add(new WitnessDto { HumanId = witness.HumanId, Name = witness.Name, SawKill = witness.SawKill, ReportDue = witness.ReportDue, Counted = witness.Counted, MaskedAtSighting = witness.MaskedAtSighting }); } list.Add(crimeSceneDto); } return list; } public static void RestoreFrom(List dtos) { //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected O, but got Unknown Active.Clear(); if (dtos == null) { return; } foreach (CrimeSceneDto dto in dtos) { CrimeScene crimeScene = new CrimeScene { VictimId = dto.VictimId, VictimName = dto.VictimName, LocKey = dto.LocKey, LocationName = dto.LocationName, WeaponId = dto.WeaponId, WeaponName = dto.WeaponName, WeaponHadPlayerPrintAtKill = dto.WeaponHadPlayerPrintAtKill, Discovered = dto.Discovered, BaselineDiscoveredBy = dto.BaselineDiscoveredBy, NativeReported = dto.NativeReported, WelfareExpires = dto.WelfareExpires, ColdExpires = dto.ColdExpires, KillAt = dto.KillAt, WelfareRaidDispatched = dto.WelfareRaidDispatched, WelfareRaidFallbackDue = dto.WelfareRaidFallbackDue, MaskedDescriptionReported = dto.MaskedDescriptionReported, ForgedOverdose = dto.ForgedOverdose, ForgedFall = dto.ForgedFall, CameraNearNoted = dto.CameraNearNoted, CameraNearRecorded = dto.CameraNearRecorded, CameraNearHeatDue = dto.CameraNearHeatDue, ForgeWasViolent = dto.ForgeWasViolent }; crimeScene.Victim = StableIds.ResolveHumanIncludingDead(dto.VictimId); crimeScene.Location = StableIds.ResolveLocation(dto.LocKey); if (dto.WeaponId >= 0) { crimeScene.Weapon = StableIds.ResolveInteractable(dto.WeaponId); } if (dto.Witnesses != null) { foreach (WitnessDto witness in dto.Witnesses) { crimeScene.Witnesses.Add(new Witness { HumanId = witness.HumanId, Name = witness.Name, SawKill = witness.SawKill, ReportDue = witness.ReportDue, Counted = witness.Counted, MaskedAtSighting = witness.MaskedAtSighting }); } } Active.Add(crimeScene); SyndicateKills.Victims.Add(dto.VictimId); } ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Restored "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Active.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" crime scene(s) from save."); } logger.LogInfo(val); } public static void OpenScene(Human victim, Murder murder) { //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Expected O, but got Unknown //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Expected O, but got Unknown bool flag = default(bool); try { if ((Object)(object)victim == (Object)null || ResolvedVictims.Contains(victim.humanID)) { return; } CrimeScene crimeScene = new CrimeScene { Victim = victim, VictimId = victim.humanID, VictimName = SafeName(victim) }; try { crimeScene.Location = ((Actor)victim).currentGameLocation; } catch { } crimeScene.LocKey = StableIds.LocationKey(crimeScene.Location); crimeScene.LocationName = LocName(crimeScene.Location); try { Death death = victim.death; crimeScene.BaselineDiscoveredBy = ((death != null) ? death.discoveredBy : int.MinValue); } catch { crimeScene.BaselineDiscoveredBy = int.MinValue; } int num = 0; List list = new List(); foreach (Human item in LivingOccupants(crimeScene)) { if (!((Actor)item).isEnforcer) { num++; if (SeesPlayer((Actor)(object)item)) { crimeScene.Witnesses.Add(NewWitness(item, sawKill: true)); } else { list.Add(SafeName(item)); } } } try { crimeScene.Weapon = ((murder != null) ? murder.weapon : null); } catch { } if (crimeScene.Weapon != null) { crimeScene.WeaponId = crimeScene.Weapon.id; try { InteractablePreset preset = crimeScene.Weapon.preset; if ((SoCustomComparison)(object)preset != (SoCustomComparison)null && !string.IsNullOrEmpty(((Object)preset).name)) { crimeScene.WeaponName = ((Object)preset).name; } } catch { } crimeScene.WeaponHadPlayerPrintAtKill = PlayerInteractionPrintPatch.EnsurePlayerPrint(crimeScene.Weapon, recordInEvidence: false); } WeaponConsequences.Register(crimeScene); crimeScene.WelfareExpires = HoursFromNow(WelfareMinH, WelfareMaxH); TimeData currentDateTime = Lib.Time.CurrentDateTime; crimeScene.KillAt = ((TimeData)(ref currentDateTime)).Serialize(); Active.Add(crimeScene); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(115, 7, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Opened at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Loc(crimeScene.LocationName, crimeScene.LocKey)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": victim "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(crimeScene.VictimName, crimeScene.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(crimeScene.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(crimeScene.Witnesses.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" non-enforcer occupant(s) saw the kill "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(mask "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateState.MaskActive ? "ON → any witness can only describe a masked figure, no name" : "off"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("weapon playerPrint="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(crimeScene.WeaponHadPlayerPrintAtKill); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". No heat yet."); } logger.LogInfo(val); if (crimeScene.Witnesses.Count == 0 && num > 0) { ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(112, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] (no eyewitness enrolled — "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" non-enforcer occupant(s) present but none had line-of-sight at the kill: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(string.Join(", ", list)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".)"); } logger2.LogInfo(val); } try { NewRoom currentRoom = ((Actor)victim).currentRoom; if ((Object)(object)currentRoom != (Object)null && RoomForensics.IsPublicPrintSpace(currentRoom)) { Notify("Public spot — your prints here won't single you out. Watch for witnesses and cameras."); } } catch { } try { ConfigEntry camerasIdentify = SyndicateConfig.CamerasIdentify; if ((camerasIdentify == null || camerasIdentify.Value) && (Object)(object)CameraSeeingPlayer(crimeScene) != (Object)null) { OnCameraDetectedPlayer(crimeScene, CameraSee.Killing); } } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] kill-instant camera check failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger3.LogWarning(val2); } } catch (Exception ex2) { ManualLogSource logger4 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] OpenScene failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2); } logger4.LogError(val3); } } public static void MonitorScenes() { //IL_07b8: Unknown result type (might be due to invalid IL or missing references) //IL_07bf: Expected O, but got Unknown //IL_0739: Unknown result type (might be due to invalid IL or missing references) //IL_0740: Expected O, but got Unknown //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Expected O, but got Unknown //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0575: Expected O, but got Unknown //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Expected O, but got Unknown //IL_06ea: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_0702: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Expected O, but got Unknown if (Active.Count == 0 || SyndicateState.IsWorldLoading) { return; } bool flag2 = default(bool); foreach (CrimeScene item in new List(Active)) { if (item.Resolved) { continue; } if ((Object)(object)item.Location == (Object)null && item.LocKey != 0L) { item.Location = StableIds.ResolveLocation(item.LocKey); } if ((Object)(object)item.Victim == (Object)null) { item.Victim = StableIds.ResolveHumanIncludingDead(item.VictimId); } if (item.Weapon == null && item.WeaponId >= 0) { item.Weapon = StableIds.ResolveInteractable(item.WeaponId); } try { ProcessReports(item); if (item.Resolved) { continue; } ProcessCameraNearHeat(item); if (!item.Discovered) { try { Death val = (((Object)(object)item.Victim != (Object)null) ? item.Victim.death : null); if (val != null && (val.reported || val.discoveredBy != item.BaselineDiscoveredBy)) { Discover(item, val.GetDiscoverer()); } } catch { } } bool flag = !item.Resolved && PlayerInsideScene(item); if (flag && !item.PlayerInsideNoticed) { item.PlayerInsideNoticed = true; LogSceneEntry(item); } else if (!flag && item.PlayerInsideNoticed) { item.PlayerInsideNoticed = false; } if (flag) { if (item.Discovered) { List list = null; foreach (Human item2 in LivingOccupants(item)) { if (((Actor)item2).isEnforcer && SeesPlayer((Actor)(object)item2)) { (list ?? (list = new List())).Add(item2); } } if (list != null) { float num = SyndicateConfig.PursuitResponseRange?.Value ?? 5f; if (!SyndicateState.MaskActive) { Human val2 = list[0]; try { if ((Object)(object)((Actor)val2).ai != (Object)null) { ((Actor)val2).ai.SetPersue((Actor)(object)Player.Instance, false, 2, true, num); } } catch { } ResolveIdentified(item, "An enforcer spotted you over " + item.VictimName + "'s body — you're wanted. Get out of sight until the warrant lifts.", "caught red-handed at the scene by enforcer " + SafeName(list[0]), immediate: true); } else { if (Time.time >= item.NextMaskedPersueAt) { foreach (Human item3 in list) { try { if ((Object)(object)((Actor)item3).ai != (Object)null) { ((Actor)item3).ai.SetPersue((Actor)(object)Player.Instance, false, 2, true, num); } } catch { } } item.NextMaskedPersueAt = Time.time + 5f; } if (!item.MaskedDescriptionReported) { item.MaskedDescriptionReported = true; SyndicateState.Data.PlayerHeatScore += SyndicateConfig.MaskedDescriptionHeat?.Value ?? 12; Notify("An enforcer caught a masked figure — you — over " + item.VictimName + "'s body. No name, no warrant… but they're coming. Move."); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(96, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] Enforcer saw the MASKED player at "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(item.VictimName, item.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s scene — pursuit without ID; scene stays Suspicious."); } logger.LogInfo(val3); NewsEngine.Push("MaskedSuspect", item.VictimId, item.VictimName, item.LocationName, DistrictName(item.Location)); MaskNotoriety.OnMaskedIncident(item, "enforcer", list.Count); } } } } if (!item.Resolved) { foreach (Human item4 in LivingOccupants(item)) { if (((Actor)item4).isEnforcer) { continue; } Witness witness = FindWitness(item, item4.humanID); if (witness != null) { if (!witness.SawKill && !witness.Counted && witness.MaskedAtSighting && !SyndicateState.MaskActive && SeesPlayer((Actor)(object)item4)) { witness.MaskedAtSighting = false; ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(74, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Actor(item4)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" has now seen your FACE at "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(item.VictimName, item.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s scene — their sighting can name you."); } logger2.LogInfo(val3); } } else { if (!SeesPlayer((Actor)(object)item4)) { continue; } item.Witnesses.Add(NewWitness(item4, sawKill: false, !item.Discovered)); if (item.Discovered) { ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(78, 4, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Actor(item4)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" saw you at "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(item.VictimName, item.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s body — heading to report ("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ReportMinH); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("-"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ReportMaxH); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("h). Silence them to stop it."); } logger3.LogInfo(val3); } else { ManualLogSource logger4 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(109, 4, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Actor(item4)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" saw you at "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(item.VictimName, item.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s scene — they'll come forward if the body is found ("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ReportMinH); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("-"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ReportMaxH); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("h after). Silence them to stop it."); } logger4.LogInfo(val3); } } } } } if (!item.Resolved) { ConfigEntry camerasIdentify = SyndicateConfig.CamerasIdentify; if ((camerasIdentify == null || camerasIdentify.Value) && PlayerAtSceneFloor(item) && (Object)(object)CameraSeeingPlayer(item) != (Object)null) { if (PlayerInsideScene(item) || SyndicateState.MaskActive) { OnCameraDetectedPlayer(item, CameraSee.AtScene); } else { OnCameraSawNearScene(item); } } } if (item.Resolved) { continue; } if (!item.Discovered && Due(item.WelfareExpires)) { ConfigEntry welfareRaidEnabled = SyndicateConfig.WelfareRaidEnabled; if ((welfareRaidEnabled != null && !welfareRaidEnabled.Value) || (Object)(object)item.Location == (Object)null) { Discover(item, null, "welfare"); } else if (!item.WelfareRaidDispatched) { DispatchWelfareRaid(item); } else { if (string.IsNullOrEmpty(item.WelfareRaidFallbackDue)) { try { TimeData val4 = Lib.Time.CurrentDateTime; val4 = ((TimeData)(ref val4)).AddHours((int)Math.Ceiling(3.0)); item.WelfareRaidFallbackDue = ((TimeData)(ref val4)).Serialize(); } catch { } } if (Due(item.WelfareRaidFallbackDue) && !WelfareRaidInFlight(item)) { ManualLogSource logger5 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(120, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] Welfare raid on "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Name(item.VictimName, item.VictimId)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" never found the body (call fizzled/parked or body moved) — falling back to synthetic discovery."); } logger5.LogInfo(val3); Discover(item, null, "welfare"); } } } if (item.Discovered && !item.Resolved && Due(item.ColdExpires)) { ResolveCold(item); } } catch (Exception ex) { ManualLogSource logger6 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(26, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Scene] monitor failed #"); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(item.VictimId); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger6.LogWarning(val5); } } } private static void DispatchWelfareRaid(CrimeScene s) { //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) s.WelfareRaidDispatched = true; float num = Mathf.Clamp(SyndicateConfig.WelfareRaidDelayHours?.Value ?? 0.25f, 0f, 168f); TimeData val; try { val = Lib.Time.CurrentDateTime; val = ((TimeData)(ref val)).AddMinutes((int)((num + 3f) * 60f)); s.WelfareRaidFallbackDue = ((TimeData)(ref val)).Serialize(); } catch { try { val = Lib.Time.CurrentDateTime; val = ((TimeData)(ref val)).AddHours((int)Math.Ceiling(3.0)); s.WelfareRaidFallbackDue = ((TimeData)(ref val)).Serialize(); } catch { s.WelfareRaidFallbackDue = ""; } } try { bool flag = false; try { GameplayController instance = GameplayController.Instance; NewAddress thisAsAddress = s.Location.thisAsAddress; bool flag2 = (Object)(object)thisAsAddress == (Object)null; int num2 = (((Object)(object)thisAsAddress != (Object)null) ? thisAsAddress.id : (((Object)(object)s.Location.thisAsStreet != (Object)null) ? s.Location.thisAsStreet.streetID : int.MinValue)); if ((Object)(object)instance != (Object)null && instance.enforcerCalls != null) { Enumerator enumerator = instance.enforcerCalls.Values.GetEnumerator(); while (enumerator.MoveNext()) { EnforcerCall current = enumerator.Current; if (current != null && current.isStreet == flag2 && current.id == num2) { flag = true; break; } } } } catch { } bool flag3 = SyndicateConfig.WelfareRaidForceCrimeScene?.Value ?? false; GameplayController.Instance.CallEnforcers(s.Location, flag3, false, num); Plugin.Logger.LogInfo((object)("[Scene] Welfare check called in on " + Redact.Name(s.VictimName, s.VictimId) + " — " + (flag ? ("a call is already live at " + Redact.Loc(s.LocationName, s.LocKey) + "; riding it.") : $"enforcers dispatched to {Redact.Loc(s.LocationName, s.LocKey)} (delay={num}h, forceScene={flag3}).") + " Fallback " + DueLabel(s.WelfareRaidFallbackDue) + ".")); if (!s.Tipped) { ManhuntController.DeferNotify("Word travels: someone's called in a welfare check on " + s.VictimName + ". Enforcers are heading over.", 4f); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag4 = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(72, 2, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] Welfare raid dispatch failed for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" — discovering synthetically."); } logger.LogWarning(val2); Discover(s, null, "welfare"); } } private static bool WelfareRaidInFlight(CrimeScene s) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between Unknown and I4 //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 try { if ((Object)(object)s.Location == (Object)null) { return false; } GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.enforcerCalls == null) { return false; } NewAddress thisAsAddress = s.Location.thisAsAddress; bool flag = (Object)(object)thisAsAddress == (Object)null; int num = (((Object)(object)thisAsAddress != (Object)null) ? thisAsAddress.id : (((Object)(object)s.Location.thisAsStreet != (Object)null) ? s.Location.thisAsStreet.streetID : int.MinValue)); Enumerator enumerator = instance.enforcerCalls.Values.GetEnumerator(); while (enumerator.MoveNext()) { EnforcerCall current = enumerator.Current; if (current != null && current.isStreet == flag && current.id == num) { return (int)current.state == 1 || (int)current.state == 2; } } return false; } catch { return false; } } public static void DebugForceWelfareRaid() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown CrimeScene crimeScene = null; foreach (CrimeScene item in Active) { if (!item.Resolved && !item.Discovered) { if ((Object)(object)item.Location == (Object)null && item.LocKey != 0L) { item.Location = StableIds.ResolveLocation(item.LocKey); } if (!((Object)(object)item.Location == (Object)null)) { crimeScene = item; break; } } } if (crimeScene == null) { Plugin.Logger.LogInfo((object)"[Scene] DEBUG: no undiscovered scene with a resolvable location to raid."); Notify("No undiscovered body to raid."); return; } ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] DEBUG: forcing a welfare raid on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(crimeScene.VictimName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(crimeScene.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogInfo(val); crimeScene.WelfareRaidDispatched = false; DispatchWelfareRaid(crimeScene); } public static bool TipOffScene(int victimId) { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown bool flag = default(bool); try { foreach (CrimeScene item in Active) { if (item.VictimId == victimId) { if (item.Resolved || item.Discovered) { return false; } item.WelfareExpires = HoursFromNow(0, 0); item.Tipped = true; ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(82, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Anonymous tip: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(item.VictimName, item.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") called in — welfare check dispatches on the next tick."); } logger.LogInfo(val); return true; } } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(31, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] TipOffScene(#"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } return false; } public static bool TipOldestUndiscovered() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown try { foreach (CrimeScene item in Active) { if (item != null && !item.Resolved && !item.Discovered && !item.Tipped && TipOffScene(item.VictimId)) { ManhuntController.DeferNotify("You called in an anonymous tip. They'll find " + item.VictimName + " soon enough — hope you left it clean.", 0.3f); return true; } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] TipOldestUndiscovered failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } return false; } public static bool SuppressSceneForBackstop(int victimId) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown try { bool flag = default(bool); for (int num = Active.Count - 1; num >= 0; num--) { CrimeScene crimeScene = Active[num]; if (crimeScene != null && crimeScene.VictimId == victimId) { crimeScene.Resolved = true; Active.RemoveAt(num); ResolvedVictims.Add(victimId); try { HomeVacateQueue.EnqueueForScene(crimeScene); } catch { } WeaponConsequences.OnCaseCold(victimId); ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(100, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Backstop-suppressed the unresolved scene for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(crimeScene.VictimName, crimeScene.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — the contract timeout settled it as cold."); } logger.LogWarning(val); return true; } } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(44, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] SuppressSceneForBackstop(#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger2.LogWarning(val); } return false; } public static void PruneResolvedMurderWeapons() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown try { List murderWeapons = SyndicateState.Data.MurderWeapons; if (murderWeapons != null && murderWeapons.Count != 0) { int count = murderWeapons.Count; murderWeapons.RemoveAll((TrackedWeaponDto e) => e != null && ResolvedVictims.Contains(e.VictimId)); int num = count - murderWeapons.Count; if (num > 0) { Plugin.LogVerbose($"[Weapons] warrant closed — pruned {num} resolved-murder weapon(s) from the registry."); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Weapons] PruneResolvedMurderWeapons failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void DebugDiscoverOldest() { CrimeScene crimeScene = null; foreach (CrimeScene item in Active) { if (!item.Discovered && !item.Resolved) { crimeScene = item; break; } } if (crimeScene == null) { Plugin.Logger.LogInfo((object)"[Scene] No undiscovered scenes."); return; } Human discoverer = null; List list = LivingOccupants(crimeScene); if (list.Count > 0) { discoverer = list[0]; } Discover(crimeScene, discoverer); } public static void DebugScanCurrentLocation() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown NewGameLocation loc = null; try { if ((Object)(object)Player.Instance != (Object)null) { loc = ((Actor)Player.Instance).currentGameLocation; } } catch { } long locationId = LocationKey(loc); int num = PlayerEvidence.CountPrintsInLocation(locationId); int num2 = PlayerEvidence.SumPrintHeatInLocation(locationId); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(69, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Location scan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(LocName(loc)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" of your print(s), "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" heat. "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Active.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" active scene(s)."); } logger.LogInfo(val); } public static void OnBodySeen(Human victim, Human seenBy) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown try { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BodyLOS-DIAG] OnBodySeen victim=#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)victim != (Object)null) ? victim.humanID : (-1)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" by=#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)seenBy != (Object)null) ? seenBy.humanID : (-1)); } logger.LogInfo(val); } catch { } if (!((Object)(object)victim == (Object)null) && !SyndicateState.IsWorldLoading) { CrimeScene crimeScene = FindUndiscovered(victim.humanID); if (crimeScene != null) { Discover(crimeScene, seenBy); } } } public static void OnBodyReported(Human victim, Human reporter) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; try { ManualLogSource logger = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(49, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BodyLOS-DIAG] OnBodyReported victim=#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)victim != (Object)null) ? victim.humanID : (-1)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" reporter=#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)reporter != (Object)null) ? reporter.humanID : (-1)); } logger.LogInfo(val); } catch { } if ((Object)(object)victim == (Object)null || SyndicateState.IsWorldLoading) { return; } CrimeScene crimeScene = FindActive(victim.humanID); if (crimeScene == null) { return; } if (!crimeScene.Discovered) { Discover(crimeScene, reporter); } crimeScene.NativeReported = true; string text = HoursFromNow(WitnessInterviewH, WitnessInterviewH); int num = 0; foreach (Witness witness in crimeScene.Witnesses) { if (!witness.Counted && IsLaterOrEmpty(witness.ReportDue, text)) { witness.ReportDue = text; num++; } } ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(94, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(crimeScene.VictimName, crimeScene.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s death was reported to the authorities by "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Actor(reporter)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" witness(es) to be interviewed within "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(WitnessInterviewH); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h."); } logger2.LogInfo(val); } private static CrimeScene FindUndiscovered(int victimId) { foreach (CrimeScene item in Active) { if (!item.Resolved && !item.Discovered && item.VictimId == victimId) { return item; } } return null; } private static CrimeScene FindActive(int victimId) { foreach (CrimeScene item in Active) { if (!item.Resolved && item.VictimId == victimId) { return item; } } return null; } internal static void ReanchorFallScene(int victimId, NewGameLocation newLoc) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown bool flag = default(bool); try { if ((Object)(object)newLoc == (Object)null) { return; } CrimeScene crimeScene = FindActive(victimId); if (crimeScene == null) { return; } long num = LocationKey(newLoc); if (num != 0L && num != crimeScene.LocKey) { long locKey = crimeScene.LocKey; crimeScene.Location = newLoc; crimeScene.LocKey = num; try { crimeScene.LocationName = LocName(newLoc); } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(61, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] re-anchored "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(crimeScene.VictimName, crimeScene.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s fall scene to the landing '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Loc(crimeScene.LocationName, crimeScene.LocKey)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (loc "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(locKey); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("->"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] ReanchorFallScene(#"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } public static void SetForgedWeaponPrint(int victimId, bool hadPrint) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown try { CrimeScene crimeScene = FindActive(victimId); if (crimeScene != null) { crimeScene.WeaponHadPlayerPrintAtKill = hadPrint; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(40, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] SetForgedWeaponPrint(#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void SetForgedOverdose(int victimId) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown try { CrimeScene crimeScene = FindActive(victimId); if (crimeScene != null) { crimeScene.ForgedOverdose = true; crimeScene.ForgeWasViolent = CleanKOTracker.WasViolent(victimId); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] SetForgedOverdose(#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void SetForgedFall(int victimId) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown try { CrimeScene crimeScene = FindActive(victimId); if (crimeScene != null) { crimeScene.ForgedFall = true; crimeScene.ForgeWasViolent = CleanKOTracker.WasViolent(victimId); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(33, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] SetForgedFall(#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static string DistrictName(NewGameLocation loc) { try { if ((Object)(object)loc != (Object)null && (Object)(object)loc.district != (Object)null) { string name = ((Object)loc.district).name; if (!string.IsNullOrEmpty(name)) { return name; } } } catch { } return ""; } public static void DebugDumpScenes() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown if (Active.Count == 0) { Plugin.Logger.LogInfo((object)"[Scene] No active scenes."); return; } ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] === "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Active.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" active scene(s) ==="); } logger.LogInfo(val); foreach (CrimeScene item in Active) { string text = (item.Discovered ? ("DISCOVERED, cold=" + DueLabel(item.ColdExpires)) : ("unreported, welfare=" + DueLabel(item.WelfareExpires))); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(41, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.VictimName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") @ "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.LocationName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" — "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", result="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.Result); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", weaponPrint="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.WeaponHadPlayerPrintAtKill); } logger2.LogInfo(val); if (item.Witnesses.Count == 0) { Plugin.Logger.LogInfo((object)"[Scene] (no witnesses yet)"); } foreach (Witness witness in item.Witnesses) { string text2 = (string.IsNullOrEmpty(witness.ReportDue) ? "on discovery" : DueLabel(witness.ReportDue)); ManualLogSource logger3 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(37, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] witness "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(witness.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(witness.HumanId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(witness.SawKill ? "saw the kill" : (witness.MaskedAtSighting ? "sighting (masked)" : "sighting")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", report="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(WitnessCanReport(witness.HumanId) ? "CAN report" : "silenced/KO/dead"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(witness.Counted ? ", counted" : ""); } logger3.LogInfo(val); } } } public static void DebugForceReportsOldest() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown CrimeScene crimeScene = null; foreach (CrimeScene item in Active) { bool flag = false; foreach (Witness witness in item.Witnesses) { if (!witness.Counted) { flag = true; break; } } if (flag) { crimeScene = item; break; } } if (crimeScene == null) { Plugin.Logger.LogInfo((object)"[Scene] No scene with a pending witness."); return; } TimeData currentDateTime = Lib.Time.CurrentDateTime; string reportDue = ((TimeData)(ref currentDateTime)).Serialize(); foreach (Witness witness2 in crimeScene.Witnesses) { if (!witness2.Counted) { witness2.ReportDue = reportDue; } } ProcessReports(crimeScene); if (!crimeScene.Resolved) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(79, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Forced reports for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(crimeScene.VictimName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": no surviving witness reported (all silenced/KO'd)."); } logger.LogInfo(val); } } public static void DebugForceColdOldest() { CrimeScene crimeScene = null; foreach (CrimeScene item in Active) { if (item.Discovered && !item.Resolved) { crimeScene = item; break; } } if (crimeScene == null) { Plugin.Logger.LogInfo((object)"[Scene] No discovered scene to resolve."); } else { ResolveCold(crimeScene); } } public static bool DebugResolveSceneForVictim(int victimId) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown bool flag2 = default(bool); try { CrimeScene crimeScene = FindActive(victimId); BepInExInfoLogInterpolatedStringHandler val; if (crimeScene == null) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); val = new BepInExInfoLogInterpolatedStringHandler(58, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] DebugResolveSceneForVictim: no active scene for #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger.LogInfo(val); return false; } if (!crimeScene.Discovered) { Discover(crimeScene, null); } ResolveCold(crimeScene); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(60, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] DebugResolveSceneForVictim: resolved scene for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(crimeScene.VictimName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger2.LogInfo(val); return true; } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(46, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] DebugResolveSceneForVictim(#"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger3.LogWarning(val2); return false; } } public static void DebugKoNearest() { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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) bool flag = default(bool); try { Player instance = Player.Instance; NewGameLocation val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentGameLocation : null); if ((Object)(object)val == (Object)null || (Object)(object)CityData.Instance == (Object)null || CityData.Instance.citizenDirectory == null) { Plugin.Logger.LogInfo((object)"[Debug] No location for KO."); return; } Vector3 position = ((Component)instance).transform.position; IntPtr pointer = ((Il2CppObjectBase)val).Pointer; Human val2 = null; float num = float.MaxValue; Enumerator enumerator = CityData.Instance.citizenDirectory.GetEnumerator(); while (enumerator.MoveNext()) { Citizen current = enumerator.Current; if ((Object)(object)current == (Object)null || ((Actor)current).isDead || ((Actor)current).isPlayer) { continue; } NewGameLocation currentGameLocation = ((Actor)current).currentGameLocation; if (!((Object)(object)currentGameLocation == (Object)null) && !(((Il2CppObjectBase)currentGameLocation).Pointer != pointer)) { Vector3 val3 = ((Component)current).transform.position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val2 = (Human)(object)current; } } } if ((Object)(object)val2 == (Object)null) { Plugin.Logger.LogInfo((object)"[Debug] No NPC in your location to KO."); return; } NewAIController ai = ((Actor)val2).ai; if ((Object)(object)ai != (Object)null) { ai.SetKO(true, ((Component)val2).transform.position, Vector3.up, true, 120f, false, 1f); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(28, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Debug] KO'd "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(SafeName(val2)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(val2.humanID); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(") for ~120s."); } logger.LogInfo(val4); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Debug] KO nearest failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex); } logger2.LogError(val5); } } public static string DebugSightSummary() { try { Player instance = Player.Instance; NewGameLocation val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentGameLocation : null); if ((Object)(object)val == (Object)null || (Object)(object)CityData.Instance == (Object)null || CityData.Instance.citizenDirectory == null) { return "(no location)"; } IntPtr pointer = ((Il2CppObjectBase)val).Pointer; List list = new List(); Enumerator enumerator = CityData.Instance.citizenDirectory.GetEnumerator(); while (enumerator.MoveNext()) { Citizen current = enumerator.Current; if ((Object)(object)current == (Object)null || ((Actor)current).isDead || ((Actor)current).isPlayer) { continue; } NewGameLocation currentGameLocation = ((Actor)current).currentGameLocation; if (!((Object)(object)currentGameLocation == (Object)null) && !(((Il2CppObjectBase)currentGameLocation).Pointer != pointer)) { list.Add(SafeName((Human)(object)current) + "=" + (SeesPlayer((Actor)(object)current) ? "SEES" : "no")); if (list.Count >= 6) { break; } } } return (list.Count == 0) ? "(nobody here)" : string.Join(", ", list); } catch { return "(err)"; } } public static string DebugRoomSummary() { try { NewRoom val = (((Object)(object)Player.Instance != (Object)null) ? ((Actor)Player.Instance).currentRoom : null); if ((Object)(object)val == (Object)null) { return "(no room)"; } string text = "?"; try { text = val.GetName(); } catch { } string text2 = "?"; try { if ((Object)(object)val.gameLocation != (Object)null) { text2 = LocName(val.gameLocation); } } catch { } return text + " -> " + text2; } catch { return "(err)"; } } public static void DebugDumpRooms() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown bool flag = default(bool); try { Player instance = Player.Instance; NewRoom val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentRoom : null); string text = "?"; try { if ((Object)(object)val != (Object)null) { text = val.GetName(); } } catch { } string text2 = "?"; try { if ((Object)(object)val != (Object)null && (Object)(object)val.gameLocation != (Object)null) { text2 = LocName(val.gameLocation); } } catch { } int num = -1; try { if ((Object)(object)val != (Object)null) { num = val.roomID; } } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(69, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] You are in room '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (id "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") owned by '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'. currentGameLocation='"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(LocName(((Object)(object)instance != (Object)null) ? ((Actor)instance).currentGameLocation : null)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } logger.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] DumpRooms failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } private static void LogSceneEntry(CrimeScene s) { //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown bool flag = default(bool); try { List list = LivingOccupants(s); int num = 0; List list2 = new List(); foreach (Human item in list) { if (((Actor)item).isEnforcer) { list2.Add(SafeName(item) + "=" + (SeesPlayer((Actor)(object)item) ? "SEES" : "no")); } else { num++; } } string text = ((list2.Count > 0) ? $"{list2.Count} enforcer(s) [{string.Join(", ", list2)}]" : "0 enforcers"); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(53, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] You stepped into "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s scene ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Loc(s.LocationName, s.LocKey)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" civilian(s)."); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] LogSceneEntry failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static void ProcessReports(CrimeScene s) { //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown List list = null; foreach (Witness witness in s.Witnesses) { if (!witness.Counted && s.Discovered && string.IsNullOrEmpty(witness.ReportDue)) { witness.ReportDue = HoursFromNow(ReportMinH, ReportMaxH); } if (!witness.Counted && Due(witness.ReportDue)) { (list ?? (list = new List())).Add(witness); } } if (list == null) { return; } foreach (Witness item in list) { if (!item.MaskedAtSighting && WitnessCanReport(item.HumanId)) { item.Counted = true; string value = (item.SawKill ? "witnessed the killing" : "saw you at the scene"); string playerMessage = $"You've been identified in the killing of {s.VictimName} — {item.Name} {value} and reported it. A warrant is being issued in your name — a positive ID follows you wherever you go."; ResolveIdentified(s, playerMessage, $"witness {item.Name} ({value}) reported it"); return; } } bool flag = default(bool); foreach (Witness item2 in list) { item2.Counted = true; if (!WitnessCanReport(item2.HumanId)) { ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(73, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Witness "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(item2.Name, item2.HumanId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" was silenced before reporting "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s death — testimony lost."); } logger.LogInfo(val); s.Witnesses.Remove(item2); } else { ReportMaskedSighting(s, item2); } } } private static void ProcessCameraNearHeat(CrimeScene s) { if (s != null && s.CameraNearRecorded && !s.CameraNearNoted) { if (s.Discovered && string.IsNullOrEmpty(s.CameraNearHeatDue)) { s.CameraNearHeatDue = HoursFromNow(ReportMinH, ReportMaxH); } if (Due(s.CameraNearHeatDue)) { ApplyCameraNearHeat(s, atColdResolve: false); } } } private static void ApplyCameraNearHeat(CrimeScene s, bool atColdResolve) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown s.CameraNearNoted = true; int num = Math.Max(0, SyndicateConfig.CameraNearSceneHeat?.Value ?? 15); SyndicateState.Data.PlayerHeatScore += num; if (!atColdResolve) { Notify("The investigation into " + s.VictimName + "'s death is pulling camera footage — one had you near the scene around the time of the killing. No name on you, but it's in the file now."); } ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(60, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Near-scene footage reviewed for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" — +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" heat ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(atColdResolve ? "force-applied at cold-resolve" : "review due"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), NO ID."); } logger.LogInfo(val); } private static void ReportMaskedSighting(CrimeScene s, Witness w) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown bool flag = !s.Discovered; if (flag) { Discover(s, ResolveHuman(w.HumanId)); } bool flag2 = default(bool); if (!s.MaskedDescriptionReported) { s.MaskedDescriptionReported = true; SyndicateState.Data.PlayerHeatScore += SyndicateConfig.MaskedDescriptionHeat?.Value ?? 12; string value = (w.SawKill ? "watched the killing" : "saw someone at the body"); string text = $"{w.Name} {value} of {s.VictimName} — but could only describe a MASKED figure. Enforcers are sweeping the scene; without a name, no warrant follows you."; if (flag) { ManhuntController.DeferNotify(text, 4f); } else { Notify(text); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(85, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Masked sighting reported by "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(w.Name, w.HumanId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" — description only; scene stays Suspicious."); } logger.LogInfo(val); NewsEngine.Push("MaskedSuspect", s.VictimId, s.VictimName, s.LocationName, DistrictName(s.Location)); MaskNotoriety.OnMaskedIncident(s, "witness", 0); } else { ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(86, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(w.Name, w.HumanId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" added another masked-figure description for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" — nothing new for the case file."); } logger2.LogInfo(val); } } private static void Discover(CrimeScene s, Human discoverer, string cause = "") { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown s.Discovered = true; s.Result = SuspicionState.Suspicious; s.ColdExpires = HoursFromNow(ColdH, ColdH); Escalate(SuspicionState.Suspicious); SyndicateState.Data.PlayerHeatScore += 8; int num = 0; foreach (Witness witness in s.Witnesses) { if (!witness.Counted && string.IsNullOrEmpty(witness.ReportDue)) { witness.ReportDue = HoursFromNow(ReportMinH, ReportMaxH); num++; } } bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (num > 0) { ManualLogSource logger = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(85, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" bystander sighting(s) will come forward within "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ReportMinH); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("-"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ReportMaxH); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h now that "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s body is found."); } logger.LogInfo(val); } if (s.CameraNearRecorded && !s.CameraNearNoted && string.IsNullOrEmpty(s.CameraNearHeatDue)) { s.CameraNearHeatDue = HoursFromNow(ReportMinH, ReportMaxH); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(94, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Camera footage of you near "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s scene will surface within "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ReportMinH); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("-"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ReportMaxH); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h now that the body is found."); } logger2.LogInfo(val); } string text = (((Object)(object)discoverer != (Object)null) ? SafeName(discoverer) : ((cause == "welfare") ? "A welfare check" : ((cause == "camera") ? "A security camera" : "An anonymous report"))); ManualLogSource logger3 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(75, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s body discovered at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Loc(s.LocationName, s.LocKey)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" by "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Investigation open for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ColdH); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h -> Suspicious."); } logger3.LogInfo(val); InvestigationTimer.OnSuspicious(s.VictimName, $"A body has been found at {s.LocationName} — {s.VictimName}. Enforcers are investigating; you haven't been identified."); NewsEngine.Push("BodyFound", s.VictimId, s.VictimName, s.LocationName, DistrictName(s.Location), (cause == "welfare") ? "welfare" : ""); } private static void ResolveCold(CrimeScene s) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown if (s.CameraNearRecorded && !s.CameraNearNoted) { ApplyCameraNearHeat(s, atColdResolve: true); } long num = ((s.LocKey != 0L) ? s.LocKey : LocationKey(s.Location)); List list = new List(); List list2 = new List(); bool flag = default(bool); try { foreach (PlayerEvidence.PrintInfo item in PlayerEvidence.GetRecordsInLocation(num)) { if (PresenceAtScene(item.Key, num, item.Name) != ScenePresence.Away) { list.Add(item); } else { list2.Add(item.Name); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(40, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] scene-print filter failed for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } ScenePresence scenePresence = ((s.WeaponId > 0) ? PresenceAtScene(s.WeaponId, num, s.WeaponName) : ScenePresence.Unknown); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(133, 10, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] Forensic review for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(s.VictimId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") @ loc "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" print(s) still at scene, "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(list2.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" dropped (moved/destroyed)"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted((list2.Count > 0) ? (": " + string.Join(", ", list2)) : ""); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Weapon '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(string.IsNullOrEmpty(s.WeaponName) ? "?" : s.WeaponName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (#"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(s.WeaponId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", printAtKill="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(s.WeaponHadPlayerPrintAtKill); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") presence="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(scenePresence); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } logger2.LogInfo(val2); List list3 = new List(); if (EvaluateForensics(s, num, list, list3, out var residualFraction)) { string value = ((list3.Count > 0) ? (" " + string.Join(" ", list3)) : ""); ResolveIdentified(s, $"Forensics have tied you to the killing of {s.VictimName}.{value} A warrant is being issued.", "forensic match at cold-case review"); return; } s.Resolved = true; Active.Remove(s); ResolvedVictims.Add(s.VictimId); try { HomeVacateQueue.EnqueueForScene(s); } catch { } int count = list.Count; List printExamples = FirstNames(list, 3); int num2 = PlayerEvidence.ClearLocation(s.LocKey); ManualLogSource logger3 = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(107, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s case went cold — no surviving witness, no forensic match. You got away. Cleared "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" scene print(s)."); } logger3.LogInfo(val2); bool flag2 = residualFraction > 0f; if (flag2) { HeatMeterState.Add(residualFraction, s.VictimId, s.VictimName); } Notify(flag2 ? ("The investigation into " + s.VictimName + "'s death has gone cold — but you left traces. The evidence quietly builds against you.") : ("The investigation into " + s.VictimName + "'s death has gone cold. You're in the clear.")); WeaponConsequences.OnCaseCold(s.VictimId); try { ContractManager.OnVictimCaseResolved(s.VictimId, identified: false); } catch { } NewsEngine.Push(s.ForgedFall ? "FallRuled" : (s.ForgedOverdose ? "SuicideRuled" : "CaseCold"), s.VictimId, s.VictimName, s.LocationName, DistrictName(s.Location), flag2 ? "traces" : ""); if (!flag2 && !s.CameraNearNoted && ((!s.ForgedFall && !s.ForgedOverdose) || !s.ForgeWasViolent)) { return; } try { MoleMail.SendForScene(s, count, printExamples); } catch { } } private static bool EvaluateForensics(CrimeScene s, long locId, List prints, List bd, out float residualFraction) { bool result = false; int num = prints?.Count ?? 0; int num2 = 0; if (prints != null) { foreach (PlayerEvidence.PrintInfo print in prints) { num2 += print.Heat; } } residualFraction = Mathf.Clamp01(Mathf.Max((FpIdHeat > 0) ? ((float)num2 / (float)FpIdHeat) : 0f, (FpIdCount > 0) ? ((float)num / (float)FpIdCount) : 0f)); if (num > 0) { SyndicateState.Data.PlayerHeatScore += num2; bool flag = num2 >= FpIdHeat || num >= FpIdCount; if (flag) { result = true; } List list = FirstNames(prints, 3); string value = ((list.Count > 0) ? (" (" + string.Join(", ", list) + ((num > list.Count) ? ", …" : "") + ")") : ""); bd.Add($"Your fingerprints were on {num} object(s) still at the scene{value}{(flag ? " — a match" : "")}."); } if (s.WeaponId > 0 && s.WeaponHadPlayerPrintAtKill && PresenceAtScene(s.WeaponId, locId, s.WeaponName) == ScenePresence.AtScene) { result = true; bd.Add(string.IsNullOrEmpty(s.WeaponName) ? "The murder weapon was still at the scene, carrying your prints." : ("The murder weapon (" + PlayerInteractionPrintPatch.Prettify(s.WeaponName) + ") was still at the scene, carrying your prints.")); } return result; } private static ScenePresence PresenceAtScene(long key, long sceneLocKey, string expectedName = null) { if (sceneLocKey == 0L) { return ScenePresence.Unknown; } if (PrintKeys.IsImmovable(key)) { return ScenePresence.AtScene; } if (key > int.MaxValue) { return ScenePresence.AtScene; } Interactable val; try { val = StableIds.ResolveInteractable((int)key); } catch { return ScenePresence.Unknown; } if (val == null) { return ScenePresence.Away; } try { if (!string.IsNullOrEmpty(expectedName)) { string text = null; try { text = (((SoCustomComparison)(object)val.preset != (SoCustomComparison)null) ? ((Object)val.preset).name : null); } catch { } if (!string.IsNullOrEmpty(text) && text != expectedName) { return ScenePresence.Away; } } NewNode node = val.node; if (node != null && (Object)(object)node.gameLocation != (Object)null) { long num = StableIds.LocationKey(node.gameLocation); return (num == 0L) ? ScenePresence.Unknown : ((num != sceneLocKey) ? ScenePresence.Away : ScenePresence.AtScene); } Human inInventory = val.inInventory; if ((Object)(object)inInventory != (Object)null) { if (((Actor)inInventory).isPlayer) { return ScenePresence.Away; } long num2 = StableIds.LocationKey(((Actor)inInventory).currentGameLocation); return (num2 == 0L) ? ScenePresence.Unknown : ((num2 != sceneLocKey) ? ScenePresence.Away : ScenePresence.AtScene); } return ScenePresence.Unknown; } catch { return ScenePresence.Unknown; } } private static List FirstNames(List prints, int max) { List list = new List(); if (prints == null) { return list; } foreach (PlayerEvidence.PrintInfo print in prints) { list.Add(print.Name); if (list.Count >= max) { break; } } return list; } private static void ResolveIdentified(CrimeScene s, string playerMessage, string logReason, bool immediate = false, float messageDelay = 0f) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown s.Resolved = true; s.Result = SuspicionState.Identified; Active.Remove(s); bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (ResolvedVictims.Contains(s.VictimId)) { ManualLogSource logger = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(55, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(logReason); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" — this murder is already resolved, ignoring."); } logger.LogInfo(val); return; } ResolvedVictims.Add(s.VictimId); try { HomeVacateQueue.EnqueueForScene(s); } catch { } MaskNotoriety.OnVictimIdentified(s.VictimId); NewsEngine.Push("Identified", s.VictimId, s.VictimName, s.LocationName, DistrictName(s.Location), logReason); SyndicateData data = SyndicateState.Data; Escalate(SuspicionState.Identified); data.PlayerHeatScore += 40; ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(40, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] IDENTIFIED for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(logReason); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". (total heat "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.PlayerHeatScore); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logger2.LogInfo(val); if (immediate || data.ActiveWarrant) { ManhuntController.StartHuntNow(s.VictimName, playerMessage, messageDelay); } else { InvestigationTimer.OnIdentified(s.VictimName, playerMessage); } ManhuntController.ApplySyndicatePenalty(s.VictimId); ManhuntController.RegisterIdentifiedMurder(s.LocKey); FineLedger.AddFine(s.VictimName, s.VictimId, SyndicateConfig.MurderFineAmount?.Value ?? 2000, logReason); try { ContractManager.OnVictimCaseResolved(s.VictimId, identified: true); } catch { } } internal static bool SeesPlayer(Actor observer) { //IL_0085: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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) try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (((Actor)instance).isHiding) { return false; } Interactable interactable = ((Actor)instance).interactable; if (interactable == null || (Object)(object)observer == (Object)null || observer.isDead) { return false; } if (!observer.CanISee(interactable)) { return false; } ConfigEntry pursuitRequireLineOfSight = SyndicateConfig.PursuitRequireLineOfSight; if (pursuitRequireLineOfSight != null && !pursuitRequireLineOfSight.Value) { return true; } try { RaycastHit val = default(RaycastHit); return observer.ActorRaycastCheck((Actor)(object)instance, SyndicateConfig.PursuitMaxDistanceMeters?.Value ?? 50f, ref val, false, default(Color), default(Color), default(Color), 0f); } catch { return true; } } catch { return false; } } private static bool PlayerHiddenFromCamera(SecuritySystem sys) { //IL_0080: 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) try { ConfigEntry camerasRespectDarkness = SyndicateConfig.CamerasRespectDarkness; if (camerasRespectDarkness != null && !camerasRespectDarkness.Value) { return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)sys == (Object)null) { return false; } float val = 16f; try { GameplayControls instance2 = GameplayControls.Instance; if ((Object)(object)instance2 != (Object)null) { val = instance2.securitySightRange; } } catch { } float stealthDistance; try { stealthDistance = ((Actor)instance).stealthDistance; } catch { return false; } if (!(stealthDistance > 0.5f)) { return false; } float num; try { num = Vector3.Distance(((Component)instance).transform.position, ((Component)sys).transform.position); } catch { return false; } return num > Math.Min(val, stealthDistance); } catch { return false; } } internal static void CameraLosProbe() { //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Expected O, but got Unknown //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Expected O, but got Unknown //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { Plugin.Logger.LogWarning((object)"[F3 Probe] no Player.Instance."); return; } NewGameLocation currentGameLocation = ((Actor)instance).currentGameLocation; ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[F3 Probe] ===== camera LOS at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)currentGameLocation != (Object)null) ? LocName(currentGameLocation) : "null"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ====="); } logger.LogInfo(val); float num = -1f; float num2 = -1f; try { num = ((Actor)instance).currentLightLevel; } catch { } try { num2 = ((Actor)instance).stealthDistance; } catch { } ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(75, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[F3 Probe] player lightLevel="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stealthDistance="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2, "F1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m (Cameras/RespectDarkness="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateConfig.CamerasRespectDarkness?.Value ?? true); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger2.LogInfo(val); HashSet hashSet = new HashSet(); List list = new List(); try { if ((Object)(object)currentGameLocation != (Object)null && currentGameLocation.securityCameras != null) { Enumerator enumerator = currentGameLocation.securityCameras.GetEnumerator(); while (enumerator.MoveNext()) { Interactable current = enumerator.Current; if (current != null && hashSet.Add(((Il2CppObjectBase)current).Pointer)) { list.Add(current); } } } } catch { } try { if ((Object)(object)currentGameLocation != (Object)null && (Object)(object)currentGameLocation.building != (Object)null && currentGameLocation.building.securityCameras != null) { Enumerator enumerator = currentGameLocation.building.securityCameras.GetEnumerator(); while (enumerator.MoveNext()) { Interactable current2 = enumerator.Current; if (current2 != null && hashSet.Add(((Il2CppObjectBase)current2).Pointer)) { list.Add(current2); } } } } catch { } int num3 = 0; int num4 = 0; foreach (Interactable item in list) { SecuritySystem val2 = null; try { val2 = (((Object)(object)item.controller != (Object)null) ? item.controller.securitySystem : null); } catch { } if (!((Object)(object)val2 == (Object)null) && (int)val2.system == 0) { bool isActive = val2.isActive; if (isActive) { num3++; } bool flag2 = isActive && SeesPlayer((Actor)(object)val2); bool flag3 = isActive && PlayerHiddenFromCamera(val2); bool flag4 = flag2 && !flag3; if (flag4) { num4++; } float num5 = -1f; try { num5 = Vector3.Distance(((Component)instance).transform.position, ((Component)val2).transform.position); } catch { } ManualLogSource logger3 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(81, 7, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[F3 Probe] cam #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.id); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" active="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(isActive); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" SEES-YOU="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (rawLOS="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" darkHidden="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") dist="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num5, "F1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m nativeAcquired="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(val2.acquiredTarget); } logger3.LogInfo(val); } } ManualLogSource logger4 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(129, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[F3 Probe] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" camera(s) in scope, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" active, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" currently SEE you. Step behind a wall/furniture and re-click to sanity-check occlusion."); } logger4.LogInfo(val); Plugin.Logger.LogInfo((object)"[F3 Probe] ===== end ====="); } catch (Exception ex) { ManualLogSource logger5 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[F3 Probe] failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } logger5.LogError(val3); } } private static bool IsPlayerOwnedLocation(NewGameLocation loc) { try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)loc == (Object)null) { return false; } NewAddress thisAsAddress = loc.thisAsAddress; if ((Object)(object)thisAsAddress == (Object)null) { return false; } if ((Object)(object)((Human)instance).home != (Object)null && ((Il2CppObjectBase)((Human)instance).home).Pointer == ((Il2CppObjectBase)thisAsAddress).Pointer) { return true; } if (instance.apartmentsOwned != null) { Enumerator enumerator = instance.apartmentsOwned.GetEnumerator(); while (enumerator.MoveNext()) { NewAddress current = enumerator.Current; if ((Object)(object)current != (Object)null && ((Il2CppObjectBase)current).Pointer == ((Il2CppObjectBase)thisAsAddress).Pointer) { return true; } } } } catch { } return false; } private static SecuritySystem CameraSeeingPlayer(CrimeScene s) { try { NewGameLocation location = s.Location; if ((Object)(object)location == (Object)null) { return null; } int restrictFloor = FloorNumber(location); HashSet seen = new HashSet(); SecuritySystem val = ScanCameras(location.securityCameras, seen, restrictFloor); if ((Object)(object)val == (Object)null && (Object)(object)location.building != (Object)null) { val = ScanCameras(location.building.securityCameras, seen, restrictFloor); } return val; } catch { return null; } } private static int FloorNumber(NewGameLocation loc) { try { NewFloor val = (((Object)(object)loc != (Object)null) ? loc.floor : null); return ((Object)(object)val != (Object)null) ? val.floor : int.MinValue; } catch { return int.MinValue; } } private static SecuritySystem ScanCameras(List list, HashSet seen, int restrictFloor = int.MinValue) { //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (list == null) { return null; } Enumerator enumerator = list.GetEnumerator(); bool flag = default(bool); while (enumerator.MoveNext()) { Interactable current = enumerator.Current; if (current == null || !seen.Add(((Il2CppObjectBase)current).Pointer)) { continue; } SecuritySystem val = null; try { val = (((Object)(object)current.controller != (Object)null) ? current.controller.securitySystem : null); } catch { } if ((Object)(object)val == (Object)null || (int)val.system != 0 || !val.isActive) { continue; } NewGameLocation val2 = null; try { val2 = ((current.node != null) ? current.node.gameLocation : null); } catch { } if (!IsPlayerOwnedLocation(val2) && (restrictFloor == int.MinValue || FloorNumber(val2) == restrictFloor) && !PlayerHiddenFromCamera(val) && SeesPlayer((Actor)(object)val)) { string text = "?"; int num = int.MinValue; try { text = (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "?"); num = FloorNumber(val2); } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(62, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Camera] a camera at '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' (floor "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") sees the player (scanFloor="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted((restrictFloor == int.MinValue) ? "any" : restrictFloor.ToString()); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")."); } logger.LogInfo(val3); return val; } } return null; } private static void OnCameraDetectedPlayer(CrimeScene s, CameraSee how, float messageDelay = 0f) { //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown if (s == null || s.Resolved) { return; } if (!SyndicateState.MaskActive) { s.Discovered = true; string playerMessage; string logReason; switch (how) { case CameraSee.Killing: playerMessage = "A security camera watched you kill " + s.VictimName + " — you're identified and a warrant is out. Cameras don't forget a face."; logReason = "identified by a security camera watching the murder"; break; case CameraSee.Unmask: playerMessage = "You pulled your mask off in view of a security camera at " + s.VictimName + "'s scene — it's got your face now. You're identified and a warrant is out."; logReason = "identified by a security camera when the player unmasked at the scene"; break; default: playerMessage = "A security camera placed you at " + s.VictimName + "'s crime scene — you're identified and a warrant is out."; logReason = "identified by a security camera at the scene"; break; } ResolveIdentified(s, playerMessage, logReason, immediate: true, messageDelay); TryCameraSweep("a camera identified you at " + s.LocationName); return; } bool flag = !s.Discovered; if (flag) { Discover(s, null, "camera"); } if (!s.MaskedDescriptionReported) { s.MaskedDescriptionReported = true; SyndicateState.Data.PlayerHeatScore += SyndicateConfig.MaskedDescriptionHeat?.Value ?? 12; string text = "A camera caught a MASKED figure — you — at " + s.VictimName + "'s scene. No name, but security's been alerted."; if (flag) { ManhuntController.DeferNotify(text, 4f); } else { Notify(text); } ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(75, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Camera saw the MASKED player at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s scene — description only, no ID."); } logger.LogInfo(val); NewsEngine.Push("MaskedSuspect", s.VictimId, s.VictimName, s.LocationName, DistrictName(s.Location)); MaskNotoriety.OnMaskedIncident(s, "camera", 0); } TryCameraSweep("a camera saw a masked figure at " + s.LocationName); } private static void OnCameraSawNearScene(CrimeScene s) { //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { if (s == null || s.Resolved || s.CameraNearNoted || s.CameraNearRecorded) { return; } int num = Math.Max(0, SyndicateConfig.CameraNearSceneFreshWindowHours?.Value ?? 2); double num2 = 0.0; if (num > 0 && !string.IsNullOrEmpty(s.KillAt)) { try { num2 = (Lib.Time.CurrentDateTime - TimeData.Deserialize(s.KillAt)).TotalHours; } catch { num2 = 0.0; } } if (num > 0 && num2 > (double)num) { if (!s.CameraNearStaleLogged) { s.CameraNearStaleLogged = true; Plugin.LogVerbose($"[Scene] Camera saw the player near {Redact.Name(s.VictimName, s.VictimId)}'s scene, but the kill is {num2:0.0}h old (> {num}h fresh window) — no suspicion added."); } return; } s.CameraNearRecorded = true; s.CameraNearHeatDue = (s.Discovered ? HoursFromNow(ReportMinH, ReportMaxH) : ""); Notify(s.Discovered ? ("A camera clocked you near " + s.VictimName + "'s place — and with a body found, someone's going to pull that footage.") : ("A camera clocked you near " + s.VictimName + "'s place. Just footage nobody knows to look at — for now.")); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(105, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Camera RECORDED the UNMASKED player in the COMMON AREA of "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s scene floor ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(s.Discovered ? $"review due in {ReportMinH}-{ReportMaxH}h" : "deferred until the body is found"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — NO heat yet, NO ID."); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] OnCameraSawNearScene failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } internal static void AddForgeViolenceHeat(int victimId) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown bool flag = default(bool); try { int num = Math.Max(0, SyndicateConfig.ForgeViolenceHeat?.Value ?? 10); if (num > 0) { SyndicateState.Data.PlayerHeatScore += num; Notify("The way you left them — a coroner won't rule that an accident. That'll draw eyes."); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(73, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Forged death of #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(victimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" shows signs of violence — +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" investigation heat."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] AddForgeViolenceHeat failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static void ClearSweep() { _cameraSweepLoc = null; _cameraSweepCall = null; _cameraSweepDeadline = ""; } private static bool CameraSweepInProgress() { if ((Object)(object)_cameraSweepLoc == (Object)null || _cameraSweepCall == null) { ClearSweep(); return false; } try { if (Due(_cameraSweepDeadline)) { ClearSweep(); return false; } GameplayController instance = GameplayController.Instance; EnforcerCall val = null; if ((Object)(object)instance != (Object)null && instance.enforcerCalls != null) { instance.enforcerCalls.TryGetValue(_cameraSweepLoc, ref val); } if (val == null || !(((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)_cameraSweepCall).Pointer) || val.isCrimeScene) { ClearSweep(); return false; } return true; } catch { ClearSweep(); return false; } } private static void TryCameraSweep(string reason) { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown bool flag = default(bool); try { ConfigEntry cameraSweepEnabled = SyndicateConfig.CameraSweepEnabled; if ((cameraSweepEnabled != null && !cameraSweepEnabled.Value) || CameraSweepInProgress()) { return; } Player instance = Player.Instance; NewGameLocation val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentGameLocation : null); GameplayController instance2 = GameplayController.Instance; if ((Object)(object)val == (Object)null || (Object)(object)instance2 == (Object)null || instance2.enforcerCalls == null || instance2.enforcerCalls.ContainsKey(val)) { return; } instance2.CallEnforcers(val, false, false, 0f); EnforcerCall val2 = null; instance2.enforcerCalls.TryGetValue(val, ref val2); if (val2 != null) { _cameraSweepLoc = val; _cameraSweepCall = val2; _cameraSweepDeadline = HoursFromNow(3, 3); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(80, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] Camera sweep dispatched to "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Place(LocName(val))); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("). Next sweep only after this one finishes."); } logger.LogInfo(val3); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Scene] camera sweep failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); } } private static bool CameraSeesPlayerNow() { try { Player instance = Player.Instance; NewGameLocation val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentGameLocation : null); if ((Object)(object)val == (Object)null) { return false; } HashSet seen = new HashSet(); SecuritySystem val2 = ScanCameras(val.securityCameras, seen); if ((Object)(object)val2 == (Object)null && (Object)(object)val.building != (Object)null) { val2 = ScanCameras(val.building.securityCameras, seen); } return (Object)(object)val2 != (Object)null; } catch { return false; } } internal static void CameraHuntTick() { try { if (SyndicateState.IsWorldLoading) { return; } ConfigEntry camerasIdentify = SyndicateConfig.CamerasIdentify; if (camerasIdentify == null || camerasIdentify.Value) { ConfigEntry cameraSweepEnabled = SyndicateConfig.CameraSweepEnabled; if ((cameraSweepEnabled == null || cameraSweepEnabled.Value) && SyndicateState.Data != null && SyndicateState.Data.ActiveWarrant && !CameraSweepInProgress() && CameraSeesPlayerNow()) { TryCameraSweep("a camera spotted the wanted player"); } } } catch { } } internal static void OnPlayerUnmasked() { //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown bool flag3 = default(bool); try { if (SyndicateState.IsWorldLoading) { return; } bool flag = SyndicateConfig.MaskUnmaskInViewIdentifies?.Value ?? true; ConfigEntry maskNotorietyEnabled = SyndicateConfig.MaskNotorietyEnabled; bool flag2 = (maskNotorietyEnabled == null || maskNotorietyEnabled.Value) && MaskNotoriety.HasUnmergedIncidents; if ((!flag && !flag2) || (Active.Count == 0 && !flag2)) { return; } if (flag) { foreach (CrimeScene item in new List(Active)) { if (item == null || item.Resolved) { continue; } foreach (Witness witness in item.Witnesses) { if (witness.Counted || !witness.MaskedAtSighting) { continue; } Human val = ResolveHuman(witness.HumanId); if ((Object)(object)val != (Object)null && SeesPlayer((Actor)(object)val)) { witness.MaskedAtSighting = false; ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(80, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Scene] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Redact.Name(witness.Name, witness.HumanId)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" saw you take the mask off at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Redact.Name(item.VictimName, item.VictimId)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s scene — their account can now name you."); } logger.LogInfo(val2); } } } } ConfigEntry camerasIdentify = SyndicateConfig.CamerasIdentify; if ((camerasIdentify != null && !camerasIdentify.Value) || !CameraSeesPlayerNow()) { return; } if (flag) { int num = 0; float num2 = SyndicateConfig.MessageGapSeconds?.Value ?? 4f; foreach (CrimeScene item2 in new List(Active)) { if (item2 != null && !item2.Resolved && SceneHasMaskedElement(item2)) { if (num == 0) { Plugin.Logger.LogInfo((object)"[Scene] a camera caught the player unmasking while a masked crime was open — connecting the face."); } OnCameraDetectedPlayer(item2, CameraSee.Unmask, (float)num * num2); num++; } } } if (flag2) { MaskNotoriety.MergeOnSlip("a camera caught you unmasking", viaBust: false); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Scene] OnPlayerUnmasked (F5) failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } internal static void MergeResolveMaskedScenes(string reason, bool viaBust) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown try { int num = 0; float num2 = SyndicateConfig.MessageGapSeconds?.Value ?? 4f; foreach (CrimeScene item in new List(Active)) { if (item != null && !item.Resolved && SceneHasMaskedElement(item)) { ResolveIdentified(item, viaBust ? ("The law pulled the mask off you — they've tied you to " + item.VictimName + "'s killing.") : ("The mask came off — you're identified in " + item.VictimName + "'s killing. A warrant is out."), "masked spree merged — " + reason, immediate: true, (float)num * num2); num++; } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] MergeResolveMaskedScenes failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static bool SceneHasMaskedElement(CrimeScene s) { try { if (s.MaskedDescriptionReported) { return true; } foreach (Witness witness in s.Witnesses) { if (witness != null && witness.MaskedAtSighting) { return true; } } } catch { } return false; } private static bool PlayerAtSceneFloor(CrimeScene s) { try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)s.Location == (Object)null) { return false; } NewGameLocation currentGameLocation = ((Actor)instance).currentGameLocation; NewBuilding building = s.Location.building; if ((Object)(object)building != (Object)null) { NewBuilding val = (((Object)(object)currentGameLocation != (Object)null) ? currentGameLocation.building : null); if ((Object)(object)val == (Object)null || ((Il2CppObjectBase)val).Pointer != ((Il2CppObjectBase)building).Pointer) { return false; } int num = FloorNumber(s.Location); return num != int.MinValue && num == FloorNumber(currentGameLocation); } return (Object)(object)currentGameLocation != (Object)null && ((Il2CppObjectBase)currentGameLocation).Pointer == ((Il2CppObjectBase)s.Location).Pointer; } catch { return false; } } private static bool PlayerInsideScene(CrimeScene s) { ConfigEntry requirePlayerInsideScene = SyndicateConfig.RequirePlayerInsideScene; if (requirePlayerInsideScene != null && !requirePlayerInsideScene.Value) { return true; } return IsInsideScene((Actor)(object)Player.Instance, s); } private static bool IsInsideScene(Actor a, CrimeScene s) { try { if ((Object)(object)a == (Object)null || (Object)(object)s.Location == (Object)null) { return false; } IntPtr pointer = ((Il2CppObjectBase)s.Location).Pointer; NewRoom currentRoom = a.currentRoom; if ((Object)(object)currentRoom != (Object)null && (Object)(object)currentRoom.gameLocation != (Object)null) { return ((Il2CppObjectBase)currentRoom.gameLocation).Pointer == pointer; } NewGameLocation currentGameLocation = a.currentGameLocation; return (Object)(object)currentGameLocation != (Object)null && ((Il2CppObjectBase)currentGameLocation).Pointer == pointer; } catch { return false; } } private static bool WitnessCanReport(int humanId) { try { Human val = ResolveHuman(humanId); if ((Object)(object)val == (Object)null || ((Actor)val).isDead) { return false; } NewAIController ai = ((Actor)val).ai; if ((Object)(object)ai != (Object)null && ai.ko) { return false; } return true; } catch { return false; } } private static Witness NewWitness(Human npc, bool sawKill, bool pendingDiscovery = false) { return new Witness { HumanId = npc.humanID, Name = SafeName(npc), SawKill = sawKill, ReportDue = (pendingDiscovery ? "" : HoursFromNow(ReportMinH, ReportMaxH)), MaskedAtSighting = SyndicateState.MaskActive }; } private static Witness FindWitness(CrimeScene s, int humanId) { foreach (Witness witness in s.Witnesses) { if (witness.HumanId == humanId) { return witness; } } return null; } private static List LivingOccupants(CrimeScene s) { List list = new List(); try { if ((Object)(object)s.Location == (Object)null || (Object)(object)CityData.Instance == (Object)null || CityData.Instance.citizenDirectory == null) { return list; } IntPtr pointer = ((Il2CppObjectBase)s.Location).Pointer; Enumerator enumerator = CityData.Instance.citizenDirectory.GetEnumerator(); while (enumerator.MoveNext()) { Citizen current = enumerator.Current; if ((Object)(object)current == (Object)null || ((Actor)current).isDead || ((Actor)current).isPlayer || ((Human)current).humanID == s.VictimId) { continue; } NewRoom currentRoom = ((Actor)current).currentRoom; if ((Object)(object)currentRoom != (Object)null && (Object)(object)currentRoom.gameLocation != (Object)null) { if (((Il2CppObjectBase)currentRoom.gameLocation).Pointer == pointer) { list.Add((Human)(object)current); } continue; } NewGameLocation currentGameLocation = ((Actor)current).currentGameLocation; if ((Object)(object)currentGameLocation != (Object)null && ((Il2CppObjectBase)currentGameLocation).Pointer == pointer) { list.Add((Human)(object)current); } } } catch { } return list; } private static long LocationKey(NewGameLocation loc) { return StableIds.LocationKey(loc); } private static Human ResolveHuman(int humanId) { try { Human result = null; if ((Object)(object)CityData.Instance != (Object)null && CityData.Instance.GetHuman(humanId, ref result, false)) { return result; } } catch { } return null; } private static void Escalate(SuspicionState s) { if (s > SyndicateState.Data.SuspicionState) { SyndicateState.Data.SuspicionState = s; } } private static string HoursFromNow(int minH, int maxH) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) int num = ((maxH > minH) ? (minH + Rng.Next(0, maxH - minH + 1)) : minH); TimeData val = Lib.Time.CurrentDateTime; val = ((TimeData)(ref val)).AddHours(num); return ((TimeData)(ref val)).Serialize(); } private static bool Due(string serialized) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(serialized)) { return false; } try { return Lib.Time.CurrentDateTime >= TimeData.Deserialize(serialized); } catch { return false; } } private static string DueLabel(string serialized) { if (string.IsNullOrEmpty(serialized)) { return "-"; } if (!Due(serialized)) { return "pending"; } return "DUE"; } private static bool IsLaterOrEmpty(string a, string b) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(a)) { return true; } if (string.IsNullOrEmpty(b)) { return false; } try { return TimeData.Deserialize(a) >= TimeData.Deserialize(b); } catch { return false; } } private static void Notify(string text) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { MessageQueue.Enqueue(text); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(23, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Scene] Notify failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static string LocName(NewGameLocation loc) { try { NewAddress val = (((Object)(object)loc != (Object)null) ? loc.thisAsAddress : null); if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name)) { return ((Object)val).name; } } catch { } return "the scene"; } private static string SafeName(Human h) { try { return ((Object)(object)h != (Object)null) ? h.GetCitizenName() : "unknown"; } catch { return "unknown"; } } } internal static class CruncherRaidCheck { public static void Run() { //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Expected O, but got Unknown //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; if (data.CruncherRaidCheckDone) { return; } data.CruncherRaidCheckDone = true; bool flag2 = default(bool); try { ConfigEntry cruncherRaidPenaltyEnabled = SyndicateConfig.CruncherRaidPenaltyEnabled; if (cruncherRaidPenaltyEnabled != null && !cruncherRaidPenaltyEnabled.Value) { return; } Player instance = Player.Instance; NewAddress val = (((Object)(object)instance != (Object)null) ? ((Human)instance).home : null); if ((Object)(object)val == (Object)null) { return; } IntPtr pointer = ((Il2CppObjectBase)val).Pointer; List val2 = (((Object)(object)CityData.Instance != (Object)null) ? CityData.Instance.interactableDirectory : null); if (val2 == null) { return; } bool flag = false; for (int i = 0; i < val2.Count; i++) { Interactable val3 = val2[i]; if (val3 == null) { continue; } try { InteractablePreset preset = val3.preset; if ((SoCustomComparison)(object)preset == (SoCustomComparison)null || !preset.isComputer) { continue; } NewNode node = val3.node; if (node != null && !((Object)(object)node.gameLocation == (Object)null) && !(((Il2CppObjectBase)node.gameLocation).Pointer != pointer) && val3.sw0 && !val3.locked) { int num = 0; try { num = (int)val3.GetExtraStateValue(); } catch { } if (num == ((Human)instance).humanID) { flag = true; break; } } } catch { } } if (!flag) { Plugin.LogVerbose("[Raid] cruncher check: nothing powered+logged-in at home."); return; } int num2 = Math.Max(0, SyndicateConfig.CruncherRaidSurchargePercent?.Value ?? 25); int num3 = (int)Math.Round((double)((SyndicateConfig.MurderFineAmount?.Value ?? 2000) * num2) / 100.0); if (num3 > 0) { if (!FineLedger.TryGetNewestUnpaid(out var victimName, out var victimId)) { victimName = "an open case"; victimId = -1; } FineLedger.Surcharge(victimName, victimId, num3, "home cruncher left logged in during raid"); } int num4 = Math.Max(0, SyndicateConfig.CruncherRaidRepLoss?.Value ?? 5); if (num4 > 0) { data.UnderworldRep = Math.Max(0, data.UnderworldRep - num4); } if (num3 > 0 || num4 > 0) { var (msg, text) = Copy(num3, num4); ManhuntController.DeferNotify(msg, 6f); if (!string.IsNullOrEmpty(text)) { ManhuntController.DeferNotify(text, 6f); } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(70, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Raid] cruncher exposed during home raid: +"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("cr surcharge, -"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(num4); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" rep (now "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(data.UnderworldRep); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")."); } logger.LogInfo(val4); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Raid] CruncherRaidCheck failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger2.LogWarning(val5); } } private static (string line1, string line2) Copy(int amount, int repLoss) { string item = ((amount > 0 && repLoss > 0) ? "The court added it to your fine, and the Syndicate heard their business was sitting open on your desk — your standing slipped." : ((amount <= 0) ? "The Syndicate heard their business was sitting open on your desk — your standing slipped." : "The court added it to your fine. Log out before you run next time.")); return (line1: "Your cruncher was on and logged in when they came through the door — everything on it went straight into the case file.", line2: item); } } internal static class EvidenceHeist { private const string TreeId = "syn_heist_tree"; private const string BlockId = "syn_heist_block"; private const string MsgId = "syn_heist_msg"; private const string Inst = "syn_heist_inst_1"; private const string BlockDict = "dds.blocks"; private static int _spawnMiss; private static int _stealMiss; private static int _probeSpawnIdx; private static SyndicateData Data => SyndicateState.Data; internal static string CaseTitle => "Loose Ends"; private static string LocateRef(int c) { return $"syn_heist{c}_locate"; } private static string StealRef(int c) { return $"syn_heist{c}_steal"; } private static string DumpRef(int c) { return $"syn_heist{c}_dump"; } internal static void Offer() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown SyndicateData data = Data; if (data != null) { int orphanFolderId = data.Heist?.OrphanFolderId ?? (-1); data.HeistCycleCounter++; data.Heist = new HeistDto { Stage = "Offered", OfferCycle = data.HeistCycleCounter, OrphanFolderId = orphanFolderId }; _spawnMiss = 0; _stealMiss = 0; ChooseTargetLocation(data.Heist); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist] OFFERED (cycle "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Heist.OfferCycle); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — target '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Place(data.Heist.TargetLocName)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Heist.TargetKind); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogInfo(val); } } internal static void ResetSession() { _spawnMiss = 0; _stealMiss = 0; } internal static void EnsureOfferVmail() { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown bool flag = default(bool); try { EnsureDdsRegistered(); SyndicateData data = Data; if (data?.Heist == null || data.Heist.VmailSent) { return; } Human val = Rewards.ResolveFixer(); Player instance = Player.Instance; if ((Object)(object)val == (Object)null || (Object)(object)instance == (Object)null) { return; } RemoveHeistThread(); float num = (((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.gameTime : 0f); MessageThreadSave val2 = Toolbox.Instance.NewVmailThread(val, (Human)(object)instance, (Human)null, (Human)null, (List)null, "syn_heist_tree", num, 1, (CustomDataSource)0, -1); if (val2 != null) { try { val2.time = num; } catch { } data.Heist.VmailSent = true; Lib.GameMessage.Broadcast("New v-mail from the Syndicate — check a cruncher.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Heist] tip v-mail sent (thread "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.threadID); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")."); } logger.LogInfo(val3); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Heist] EnsureOfferVmail failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); } } internal static void TrySpawnFolder() { //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Expected O, but got Unknown //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Expected O, but got Unknown //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Expected O, but got Unknown //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Expected O, but got Unknown //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029a: 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_0124: Expected O, but got Unknown bool flag3 = default(bool); try { SyndicateData data = Data; if (data?.Heist == null) { return; } if (data.Heist.TargetLocKey == 0L) { ChooseTargetLocation(data.Heist); if (data.Heist.TargetLocKey == 0L) { return; } } NewGameLocation val = StableIds.ResolveLocation(data.Heist.TargetLocKey); NewAddress val2 = (((Object)(object)val != (Object)null) ? val.thisAsAddress : null); if ((Object)(object)val2 == (Object)null) { return; } InteractablePreset val3 = ResolveFolderPreset(); if ((SoCustomComparison)(object)val3 == (SoCustomComparison)null) { Plugin.Logger.LogWarning((object)"[Heist] no folder preset resolvable."); return; } Human val4 = Rewards.ResolveFixer(); NewNode val5 = FindDeepNode(val2); int sec; NewRoom val6 = FindSecureBackroom(val2, out sec); int num = Mathf.Clamp(SyndicateConfig.HeistBackroomPercent?.Value ?? 80, 0, 100); bool flag = (Object)(object)val6 != (Object)null && Random.Range(0, 100) < num; NewNode val7 = val5; bool flag2 = false; int num2 = 0; if (flag) { NewNode val8 = RoomNode(val6); if (val8 != null) { val7 = val8; flag2 = true; num2 = sec; } else { flag = false; } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val9 = new BepInExInfoLogInterpolatedStringHandler(63, 4, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("[Heist] placement target: "); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(flag ? $"SECURE BACKROOM (security {sec})" : "deep office desk"); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" at '"); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(Redact.Place(data.Heist.TargetLocName)); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("' (backroomChance="); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("%, backroom "); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(((Object)(object)val6 != (Object)null) ? "found" : "NONE → desk fallback"); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(")."); } logger.LogInfo(val9); Interactable val10 = null; try { FurnitureLocation val11 = null; val10 = ((NewGameLocation)val2).PlaceObject(val3, val4, val4, (Human)null, ref val11, false, (PassedVarType)0, -1, flag2, num2, (OwnedPlacementRule)4, 0, (RetailItemPreset)null, false, (HashSet)null, (string)null, val7, "", true); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val12 = new BepInExWarningLogInterpolatedStringHandler(27, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val12).AppendLiteral("[Heist] PlaceObject threw: "); ((BepInExLogInterpolatedStringHandler)val12).AppendFormatted(ex.Message); } logger2.LogWarning(val12); } if (val10 == null) { Vector3 pos = Vector3.zero; Vector3 euler = Vector3.zero; if (val7 != null) { pos = val7.position; } else if (!ResolvePlacement(val2, out pos, out euler)) { return; } try { val10 = InteractableCreator.Instance.CreateWorldInteractable(val3, val4, val4, val4, pos, euler, (List)null, (Object)null, ""); } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val12 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val12).AppendLiteral("[Heist] folder spawn threw: "); ((BepInExLogInterpolatedStringHandler)val12).AppendFormatted(ex2.Message); } logger3.LogWarning(val12); } } if (val10 != null) { data.Heist.FolderId = val10.id; data.Heist.Stage = "Spawned"; _spawnMiss = 0; CompleteRow(data.Heist.CaseId, LocateRef(data.Heist.OfferCycle)); ManualLogSource logger4 = Plugin.Logger; val9 = new BepInExInfoLogInterpolatedStringHandler(64, 4, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("[Heist] folder spawned (id="); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(val10.id); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(", preset='"); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(PresetName(val3)); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("') at '"); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(Redact.Place(data.Heist.TargetLocName)); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("' → landed in room "); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(LandedRoom(val10)); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("."); } logger4.LogInfo(val9); } } catch (Exception ex3) { ManualLogSource logger5 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val12 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val12).AppendLiteral("[Heist] TrySpawnFolder failed: "); ((BepInExLogInterpolatedStringHandler)val12).AppendFormatted(ex3.Message); } logger5.LogWarning(val12); } } internal static void WatchSpawned() { SyndicateData data = Data; if (data?.Heist == null) { return; } Interactable val = StableIds.ResolveInteractable(data.Heist.FolderId); if (val == null) { if (++_spawnMiss < 5) { return; } try { Interactable obj = StableIds.ResolveInteractable(data.Heist.FolderId); if (obj != null) { obj.SafeDelete(true); } } catch { } data.Heist.FolderId = -1; data.Heist.Stage = "Offered"; _spawnMiss = 0; Plugin.Logger.LogInfo((object)"[Heist] folder lost before theft — respawning."); } else { _spawnMiss = 0; bool flag = false; try { flag = (Object)(object)val.inInventory != (Object)null && ((Actor)val.inInventory).isPlayer; } catch { } if (flag) { OnStolen(); } } } internal static void WatchStolen() { SyndicateData data = Data; if (data?.Heist == null) { return; } if (StableIds.ResolveInteractable(data.Heist.FolderId) == null) { if (++_stealMiss >= 5) { _stealMiss = 0; Plugin.Logger.LogInfo((object)"[Heist] stolen folder lost — re-offering."); CancelActive(); Offer(); Lib.GameMessage.Broadcast("Word is the evidence file resurfaced somewhere else. The job's back on.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } } else { _stealMiss = 0; } } internal static void OnStolen() { SyndicateData data = Data; if (data?.Heist != null && !(data.Heist.Stage == "Stolen")) { data.Heist.Stage = "Stolen"; _stealMiss = 0; CompleteRow(data.Heist.CaseId, StealRef(data.Heist.OfferCycle)); Lib.GameMessage.Broadcast("You've got the file. Now drown it — take it to open water and throw it in (right-click).", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } } internal static void Dispose() { //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown try { SyndicateData data = Data; if (data?.Heist != null && (!(data.Heist.Stage == "None") || data.Heist.FolderId >= 0)) { int offerCycle = data.Heist.OfferCycle; int caseId = data.Heist.CaseId; int pendingCloseCaseId = data.Heist.PendingCloseCaseId; string targetLocName = data.Heist.TargetLocName; CompleteRow(caseId, LocateRef(offerCycle)); CompleteRow(caseId, StealRef(offerCycle)); CompleteRow(caseId, DumpRef(offerCycle)); bool flag = CloseCase(caseId, archive: true); RemoveHeistThread(); data.Heist = new HeistDto { PendingCloseCaseId = (flag ? pendingCloseCaseId : caseId) }; Lib.GameMessage.Broadcast("The sea keeps its secrets. That trail just went cold for good.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); Plugin.Logger.LogInfo((object)"[Heist] folder disposed in the sea — meter cleared."); HeatMeterState.Clear(); NewsEngine.Push("RecordsStolen", -1, "", targetLocName); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist] Dispose failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static void Punish() { //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = Data; if (data == null) { return; } data.HeatPunishLatched = true; int num = SyndicateConfig.ResidualFinePerMurder?.Value ?? 1000; ResidualHeatContributionDto[] array = (data.ResidualHeatContributors ?? new List()).ToArray(); ResidualHeatContributionDto[] array2 = array; foreach (ResidualHeatContributionDto residualHeatContributionDto in array2) { if (residualHeatContributionDto != null) { try { FineLedger.Surcharge(residualHeatContributionDto.VictimName, residualHeatContributionDto.VictimId, num, "residual evidence exposed"); } catch { } } } ConfigEntry residualWarrantAt = SyndicateConfig.ResidualWarrantAt100; if (residualWarrantAt == null || residualWarrantAt.Value) { try { ManhuntController.StartHuntNow((array.Length != 0) ? array[0].VictimName : "your old cases", "Your old cases finally landed on the right desk — they've got enough. Enforcers are coming."); } catch { } } int num2 = num * Math.Max(0, array.Length); Lib.GameMessage.Broadcast($"The residual-evidence file got too thick. {array.Length} cold case(s) reopened — {num2}cr in fines.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(61, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist] 100% PUNISHMENT: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(array.Length); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" contributor(s), "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr fined, warrant="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateConfig.ResidualWarrantAt100?.Value ?? true); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger.LogInfo(val); NewsEngine.Push("ColdCasesReopened", -1, "", "", "", Math.Max(0, array.Length).ToString()); HeatMeterState.Clear(); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(23, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist] Punish failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } internal static void CancelActive() { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown try { SyndicateData data = Data; if (data == null) { return; } if (data.Heist == null) { data.Heist = new HeistDto(); } else { if (data.Heist.Stage == "None" && data.Heist.CaseId < 0 && data.Heist.FolderId < 0 && data.Heist.OrphanFolderId < 0) { return; } bool flag = CloseCase(data.Heist.CaseId, archive: false); RemoveHeistThread(); int num = -1; if (data.Heist.FolderId >= 0) { Interactable val = StableIds.ResolveInteractable(data.Heist.FolderId); if (val != null) { try { val.SafeDelete(true); } catch { } if (StableIds.ResolveInteractable(data.Heist.FolderId) != null) { num = data.Heist.FolderId; } } } if (num < 0) { num = data.Heist.OrphanFolderId; } int pendingCloseCaseId = (flag ? data.Heist.PendingCloseCaseId : data.Heist.CaseId); data.Heist = new HeistDto { OrphanFolderId = num, PendingCloseCaseId = pendingCloseCaseId }; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist] CancelActive failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } } internal static void CleanupOrphan(SyndicateData d) { try { if (d?.Heist == null) { return; } if (d.Heist.OrphanFolderId >= 0) { Interactable val = StableIds.ResolveInteractable(d.Heist.OrphanFolderId); if (val == null) { d.Heist.OrphanFolderId = -1; } else { try { val.SafeDelete(true); } catch { } if (StableIds.ResolveInteractable(d.Heist.OrphanFolderId) == null) { d.Heist.OrphanFolderId = -1; } } } if (d.Heist.PendingCloseCaseId >= 0 && CloseCase(d.Heist.PendingCloseCaseId, archive: false)) { d.Heist.PendingCloseCaseId = -1; } } catch { } } internal static void EnsureHeistCase() { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = Data; if (data?.Heist == null || SyndicateState.IsWorldLoading) { return; } CasePanelController instance = CasePanelController.Instance; if ((Object)(object)instance == (Object)null || (data.Heist.CaseId >= 0 && ResolveCase(instance, data.Heist.CaseId) != null)) { return; } Case activeCase = instance.activeCase; Case val = instance.CreateNewCase((CaseType)3, (CaseStatus)0, true, CaseTitle); if (val != null) { val.caseType = (CaseType)3; val.caseStatus = (CaseStatus)0; data.Heist.CaseId = val.id; instance.SetActiveCase(val); BuildRows(val, data.Heist); instance.SetActiveCase(activeCase); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(40, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist] pinboard case "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val.id); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" created (cycle "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(data.Heist.OfferCycle); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } logger.LogInfo(val2); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Heist] EnsureHeistCase failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } private static void BuildRows(Case kase, HeistDto h) { int offerCycle = h.OfferCycle; bool completed = h.Stage == "Spawned" || h.Stage == "Stolen"; bool completed2 = h.Stage == "Stolen"; AddRow(kase, LocateRef(offerCycle), "The evidence file is at " + h.TargetLocName + ", an Enforcer Division office — most likely locked in the secure back room behind the password door.", (Icon)0, completed); AddRow(kase, StealRef(offerCycle), "Steal the evidence folder.", (Icon)15, completed2); AddRow(kase, DumpRef(offerCycle), "Throw the folder into the sea (take it to open water and throw it in).", (Icon)22, completed: false); } private static void ChooseTargetLocation(HeistDto h) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown try { List list = new List(); CityData instance = CityData.Instance; if ((Object)(object)instance != (Object)null && instance.companyDirectory != null) { Enumerator enumerator = instance.companyDirectory.GetEnumerator(); while (enumerator.MoveNext()) { Company current = enumerator.Current; if (current != null && !((SoCustomComparison)(object)current.preset == (SoCustomComparison)null) && ((Object)current.preset).name == "EnforcerBranch" && (Object)(object)current.address != (Object)null && !ContainsAddr(list, current.address)) { list.Add(current.address); } } } if (list.Count == 0) { Plugin.Logger.LogWarning((object)"[Heist] no enforcer division offices found — will retry."); return; } NewAddress loc = list[Random.Range(0, list.Count)]; h.TargetLocKey = StableIds.LocationKey((NewGameLocation)(object)loc); h.TargetLocName = SafeName((NewGameLocation)(object)loc); h.TargetKind = "office"; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist] ChooseTargetLocation failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static NewRoom FindSecureBackroom(NewAddress addr, out int sec) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown sec = 0; NewRoom result = null; int num = 0; bool flag = default(bool); try { List val = (((Object)(object)addr != (Object)null) ? ((NewGameLocation)addr).rooms : null); if (val == null) { return null; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < val.Count; i++) { NewRoom val2 = val[i]; if ((Object)(object)val2 == (Object)null) { continue; } int num2 = 0; try { if ((SoCustomComparison)(object)val2.preset != (SoCustomComparison)null) { num2 = val2.preset.securityLevel; } } catch { } try { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(5, 2, stringBuilder2); handler.AppendLiteral("'"); handler.AppendFormatted(val2.name); handler.AppendLiteral("'="); handler.AppendFormatted(num2); handler.AppendLiteral(" "); stringBuilder2.Append(ref handler); } catch { } if (num2 > num) { num = num2; result = val2; } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Heist] office '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Redact.Place(SafeName((NewGameLocation)(object)addr))); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' rooms (name=security): "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(stringBuilder); } logger.LogInfo(val3); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Heist] FindSecureBackroom failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); } sec = num; if (num <= 0) { return null; } return result; } private static NewNode RoomNode(NewRoom room) { try { HashSet val = (((Object)(object)room != (Object)null) ? room.nodes : null); if (val != null) { Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { NewNode current = enumerator.Current; if (current != null) { return current; } } } } catch { } return null; } private static string LandedRoom(Interactable inter) { try { NewNode val = ((inter != null) ? inter.node : null); NewRoom val2 = ((val != null) ? val.room : null); if ((Object)(object)val2 == (Object)null) { return "?"; } int value = 0; try { if ((SoCustomComparison)(object)val2.preset != (SoCustomComparison)null) { value = val2.preset.securityLevel; } } catch { } return $"'{val2.name}' (security {value})"; } catch { return "?"; } } private static bool ResolvePlacement(NewAddress addr, out Vector3 pos, out Vector3 euler) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_0085: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) pos = default(Vector3); euler = Vector3.zero; try { NodeAccess mainEntrance = ((NewGameLocation)addr).GetMainEntrance(); if (mainEntrance != null) { NewDoor door = mainEntrance.door; if ((Object)(object)door != (Object)null && door.doorInteractable != null) { Interactable doorInteractable = door.doorInteractable; pos = doorInteractable.wPos + Quaternion.Euler(doorInteractable.wEuler) * new Vector3(0f, 0f, 0.4f); euler = doorInteractable.wEuler; return true; } Vector3 worldAccessPoint = mainEntrance.worldAccessPoint; if (worldAccessPoint != Vector3.zero) { pos = worldAccessPoint; euler = Vector3.zero; return true; } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist] ResolvePlacement failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } return false; } private static NewNode FindDeepNode(NewAddress addr) { //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_003f: 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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = Vector3.zero; NodeAccess mainEntrance = ((NewGameLocation)addr).GetMainEntrance(); if (mainEntrance != null) { val = ((!((Object)(object)mainEntrance.door != (Object)null) || mainEntrance.door.doorInteractable == null) ? mainEntrance.worldAccessPoint : mainEntrance.door.doorInteractable.wPos); } NewNode result = null; float num = -1f; List nodes = ((NewGameLocation)addr).nodes; if (nodes != null) { for (int i = 0; i < nodes.Count; i++) { NewNode val2 = nodes[i]; if (val2 != null) { float sqrMagnitude; try { Vector3 val3 = val2.position - val; sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; } catch { continue; } if (sqrMagnitude > num) { num = sqrMagnitude; result = val2; } } } } return result; } catch { return null; } } private static InteractablePreset ResolveFolderPreset() { try { string text = SyndicateConfig.HeistFolderPreset?.Value; if (!string.IsNullOrEmpty(text)) { InteractablePreset interactablePreset = Toolbox.Instance.GetInteractablePreset(text); if ((SoCustomComparison)(object)interactablePreset != (SoCustomComparison)null) { return interactablePreset; } } } catch { } List list = new List(); try { list.Add(Toolbox.Instance.GetInteractablePreset("SealedEnvelope")); } catch { } try { InteriorControls instance = InteriorControls.Instance; if ((Object)(object)instance != (Object)null) { list.Add(instance.homeFilePreset); list.Add(instance.document); list.Add(instance.residentsContract); } } catch { } string[] array = new string[7] { "Folder", "Documents", "Document", "Dossier", "CaseFile", "WrittenDocument", "Papers" }; foreach (string text2 in array) { try { list.Add(Toolbox.Instance.GetInteractablePreset(text2)); } catch { } } foreach (InteractablePreset item in list) { try { if ((SoCustomComparison)(object)item != (SoCustomComparison)null && (item.isInventoryItem || item.inventoryCarryItem)) { return item; } } catch { } } array = new string[3] { "BriefcaseDocuments", "BriefcaseCustom", "Briefcase" }; foreach (string text3 in array) { try { InteractablePreset interactablePreset2 = Toolbox.Instance.GetInteractablePreset(text3); if ((SoCustomComparison)(object)interactablePreset2 != (SoCustomComparison)null) { return interactablePreset2; } } catch { } } return null; } private static string PresetName(InteractablePreset p) { try { return ((SoCustomComparison)(object)p != (SoCustomComparison)null) ? ((Object)p).name : "?"; } catch { return "?"; } } private static bool ContainsAddr(List list, NewAddress a) { for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i] != (Object)null && (Object)(object)a != (Object)null && ((Il2CppObjectBase)list[i]).Pointer == ((Il2CppObjectBase)a).Pointer) { return true; } } return false; } private static string SafeName(NewGameLocation loc) { try { string name = ((Object)loc).name; return string.IsNullOrEmpty(name) ? "an enforcer location" : name; } catch { return "an enforcer location"; } } internal static bool IsFolderId(int id) { SyndicateData data = Data; if (data?.Heist == null || id < 0) { return false; } if (data.Heist.OrphanFolderId == id) { return true; } if (data.Heist.FolderId == id) { if (!(data.Heist.Stage == "Spawned")) { return data.Heist.Stage == "Stolen"; } return true; } return false; } internal static bool OnFolderInteracted(Interactable folder, Actor who) { //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown try { SyndicateData data = Data; if (data?.Heist != null && data.Heist.OrphanFolderId == folder.id && data.Heist.FolderId != folder.id) { return false; } if ((Object)(object)who == (Object)null || !who.isPlayer) { return false; } FirstPersonItemController instance = FirstPersonItemController.Instance; bool flag = false; try { flag = (Object)(object)folder.inInventory != (Object)null && ((Actor)folder.inInventory).isPlayer; } catch { } if (!flag && (Object)(object)instance != (Object)null) { bool flag2 = false; try { flag2 = instance.PickUpItem(folder, false, false, false, true, true); } catch { } try { flag = flag2 || ((Object)(object)folder.inInventory != (Object)null && ((Actor)folder.inInventory).isPlayer); } catch { flag = flag2; } if (!flag) { Lib.GameMessage.Broadcast("Your hands are full — free a slot to take the file.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } } if (flag && data?.Heist != null && data.Heist.Stage == "Spawned") { OnStolen(); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag3 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist] OnFolderInteracted failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } return false; } internal static void OnItemEnteredSea(int id) { SyndicateData data = Data; if (data?.Heist != null && !SyndicateState.IsWorldLoading && id >= 0 && data.Heist.FolderId == id && data.Heist.Stage == "Stolen") { Dispose(); } } internal static void EnsureDdsRegistered() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown try { Toolbox instance = Toolbox.Instance; if ((Object)(object)instance == (Object)null) { return; } bool flag = false; try { flag = instance.allDDSTrees.ContainsKey("syn_heist_tree"); } catch { } if (!flag) { RegisterHeistTree(instance); } try { Lib.DdsStrings.AddOrUpdate("dds.blocks", "syn_heist_block", BuildVmailText()); } catch { } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist] EnsureDdsRegistered failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void RegisterHeistTree(Toolbox tb) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown DDSBlockSave val = new DDSBlockSave { id = "syn_heist_block", name = "syn_heist_block" }; DDSMessageSave val2 = new DDSMessageSave { id = "syn_heist_msg", name = "syn_heist_msg" }; val2.AddBlock("syn_heist_block"); try { val2.blocks[0].alwaysDisplay = true; } catch { } DDSTreeSave val3 = new DDSTreeSave { id = "syn_heist_tree", name = "syn_heist_tree" }; val3.treeType = (TreeType)1; val3.triggerPoint = (TriggerPoint)5; val3.participantA = new DDSParticipant(); val3.participantB = new DDSParticipant(); val3.participantC = new DDSParticipant(); val3.participantD = new DDSParticipant(); val3.AddMessage("syn_heist_msg"); DDSMessageSettings val4 = val3.messages[0]; val4.instanceID = "syn_heist_inst_1"; try { val4.saidBy = 0; val4.saidTo = 1; } catch { } val3.startingMessage = "syn_heist_inst_1"; val3.messageRef = new Dictionary(); val3.messageRef.Add("syn_heist_inst_1", val4); tb.allDDSBlocks["syn_heist_block"] = val; tb.allDDSMessages["syn_heist_msg"] = val2; tb.allDDSTrees["syn_heist_tree"] = val3; Lib.DdsStrings.AddOrUpdate("dds.blocks", "syn_heist_block", BuildVmailText()); } private static string BuildVmailText() { string text = "an enforcer location"; try { string text2 = Data?.Heist?.TargetLocName; if (!string.IsNullOrEmpty(text2)) { text = text2; } } catch { } return "LOOSE ENDS.\n\nA friend inside the branch says the enforcers keep a residual-evidence file with your handiwork all over it — prints, casings, patterns. When it gets thick enough, they stop filing and start knocking.\n\nRight now it's sitting at " + text + " — a division office, most likely locked in the secure back room behind the password door. Get the folder and put it somewhere the divers don't go.\n\n— F"; } private static void RemoveHeistThread() { try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.messageThreads == null) { return; } List list = new List(); Enumerator enumerator = instance.messageThreads.Values.GetEnumerator(); while (enumerator.MoveNext()) { MessageThreadSave current = enumerator.Current; if (current != null) { string text = null; try { text = current.treeID; } catch { } if (text == "syn_heist_tree") { list.Add(current.threadID); } } } foreach (int item in list) { try { instance.messageThreads.Remove(item); } catch { } } } catch { } } private static Case ResolveCase(CasePanelController cpc, int caseId) { if (caseId < 0 || (Object)(object)cpc == (Object)null) { return null; } return FindCase(cpc.activeCases, caseId) ?? FindCase(cpc.archivedCases, caseId); } private static Case FindCase(List list, int caseId) { if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { if (list[i] != null && list[i].id == caseId) { return list[i]; } } return null; } private static void AddRow(Case kase, string entryRef, string name, Icon icon, bool completed) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown try { List val = new List(); Objective val2 = new Objective(new QueueElement(kase.id, entryRef, false, Vector3.zero, icon, val, (OnCompleteAction)4, 0f, false, "", false, false, (SideJob)null, false, false) { icon = icon, onComplete = (OnCompleteAction)4 }); val2.name = name; if (completed) { val2.SetProgress(1f); val2.Complete(); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(26, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Heist] AddRow '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(entryRef); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); } } private static void CompleteRow(int caseId, string entryRef) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown try { Case val = ResolveCase(CasePanelController.Instance, caseId); if (val != null) { Objective val2 = FindIn(val.currentActiveObjectives, entryRef) ?? FindIn(val.inactiveCurrentObjectives, entryRef) ?? FindIn(val.endedObjectives, entryRef); if (val2 != null && !val2.isComplete) { val2.SetProgress(1f); val2.Complete(); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(31, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Heist] CompleteRow '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(entryRef); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); } } private static Objective FindIn(List list, string entryRef) { if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { Objective val = list[i]; if (val != null && val.queueElement != null && val.queueElement.entryRef == entryRef) { return val; } } return null; } private static bool CloseCase(int caseId, bool archive) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown try { CasePanelController instance = CasePanelController.Instance; if ((Object)(object)instance == (Object)null) { return false; } Case val = ResolveCase(instance, caseId); if (val == null) { return true; } instance.CloseCase(val); if (archive && instance.archivedCases != null && FindCase(instance.archivedCases, val.id) == null) { instance.archivedCases.Add(val); } try { instance.UpdateCaseControls(); } catch { } return true; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist] CloseCase failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); return false; } } internal static string DebugStatus() { HeistDto heistDto = Data?.Heist; if (heistDto == null) { return "Heist: (null)"; } return $"Heist: {heistDto.Stage} cyc{heistDto.OfferCycle} folder={heistDto.FolderId} case={heistDto.CaseId} loc='{heistDto.TargetLocName}' vmail={heistDto.VmailSent}"; } public static void DebugDumpEnforcerOffices() { //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown bool flag = default(bool); try { CityData instance = CityData.Instance; if ((Object)(object)instance == (Object)null || instance.companyDirectory == null) { Plugin.Logger.LogWarning((object)"[Heist] no city/companyDirectory."); return; } int num = 0; Enumerator enumerator = instance.companyDirectory.GetEnumerator(); BepInExInfoLogInterpolatedStringHandler val2; while (enumerator.MoveNext()) { Company current = enumerator.Current; if (current != null && !((SoCustomComparison)(object)current.preset == (SoCustomComparison)null) && !(((Object)current.preset).name != "EnforcerBranch") && !((Object)(object)current.address == (Object)null)) { num++; int sec; NewRoom val = FindSecureBackroom(current.address, out sec); ManualLogSource logger = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist] → office '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Redact.Place(SafeName((NewGameLocation)(object)current.address))); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': backroom = "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)(object)val != (Object)null) ? $"'{val.name}' (security {sec})" : "NONE (no room with security>0 — folder would use a deep desk)"); } logger.LogInfo(val2); } } ManualLogSource logger2 = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(51, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist] === "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Enforcer Division office(s) dumped ==="); } logger2.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Heist] DebugDumpEnforcerOffices failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger3.LogWarning(val3); } } internal static void DebugForceOffer() { SyndicateData data = Data; if (data != null) { List residualHeatContributors = data.ResidualHeatContributors; if (residualHeatContributors == null || residualHeatContributors.Count == 0) { HeatMeterState.Add(0.5f, -1, "debug victim"); } data.ResidualHeat = Mathf.Max(data.ResidualHeat, Mathf.Clamp(SyndicateConfig.HeistOfferThreshold?.Value ?? 0.8f, 0.1f, 0.95f)); if (data.Heist == null || data.Heist.Stage == "None") { Offer(); } EnsureOfferVmail(); EnsureHeistCase(); TrySpawnFolder(); } } internal static void DebugForceSteal() { SyndicateData data = Data; if (data?.Heist == null) { return; } if (data.Heist.Stage == "None") { DebugForceOffer(); } Interactable val = StableIds.ResolveInteractable(data.Heist.FolderId); if (val == null) { Plugin.Logger.LogInfo((object)"[Heist] DebugForceSteal: no folder spawned yet — use Force Offer first."); return; } FirstPersonItemController instance = FirstPersonItemController.Instance; try { if (instance != null) { instance.PickUpItem(val, false, false, false, true, true); } } catch { } OnStolen(); } internal static void DebugDumpFolderPresets() { //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown bool flag = default(bool); try { Plugin.Logger.LogInfo((object)"[Heist Probe] ===== document/folder item presets ====="); InteriorControls instance = InteriorControls.Instance; if ((Object)(object)instance != (Object)null) { L("InteriorControls.homeFilePreset", instance.homeFilePreset); L("InteriorControls.document", instance.document); L("InteriorControls.residentsContract", instance.residentsContract); L("InteriorControls.letter", instance.letter); L("InteriorControls.note", instance.note); L("InteriorControls.receipt", instance.receipt); } string[] array = new string[11] { "Folder", "Documents", "Document", "Dossier", "CaseFile", "WrittenDocument", "Papers", "Report", "EvidenceFolder", "BriefcaseDocuments", "BriefcaseCustom" }; foreach (string text in array) { InteractablePreset p = null; try { p = Toolbox.Instance.GetInteractablePreset(text); } catch { } L("byName '" + text + "'", p); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(50, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist Probe] ResolveFolderPreset() would pick: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(PresetName(ResolveFolderPreset())); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); } logger.LogInfo(val); Plugin.Logger.LogInfo((object)"[Heist Probe] ===== end ====="); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist Probe] failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger2.LogError(val2); } static void L(string label, InteractablePreset val3) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown bool flag2 = default(bool); if ((SoCustomComparison)(object)val3 == (SoCustomComparison)null) { ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(24, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Heist Probe] "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(label.PadRight(34)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" -> (null)"); } logger3.LogInfo(val4); } else { bool flag3 = false; bool flag4 = false; try { flag3 = val3.isInventoryItem; flag4 = val3.inventoryCarryItem; } catch { } ManualLogSource logger4 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(58, 4, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Heist Probe] "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(label.PadRight(34)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" -> '"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(PresetName(val3)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("' isInventoryItem="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(flag3); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" inventoryCarryItem="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(flag4); } logger4.LogInfo(val4); } } } internal static void DebugFindDocLikePresets() { //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Expected O, but got Unknown //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown bool flag3 = default(bool); try { Dictionary objectPresetDictionary = Toolbox.Instance.objectPresetDictionary; if (objectPresetDictionary == null) { Plugin.Logger.LogWarning((object)"[Heist Probe] objectPresetDictionary null."); return; } string[] array = new string[14] { "envelope", "secret", "document", "dossier", "folder", "file", "papers", "confidential", "classified", "letter", "report", "photo", "microfilm", "tape" }; Plugin.Logger.LogInfo((object)"[Heist Probe] ===== item presets matching doc/envelope terms (name | presetName | display) ====="); int num = 0; Enumerator enumerator = objectPresetDictionary.GetEnumerator(); BepInExInfoLogInterpolatedStringHandler val; while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; InteractablePreset value = current.Value; if ((SoCustomComparison)(object)value == (SoCustomComparison)null) { continue; } string text = "?"; try { text = current.Key ?? "?"; } catch { } string text2 = "?"; try { text2 = ((SoCustomComparison)value).presetName ?? "?"; } catch { } string text3 = ""; try { text3 = Strings.Get("evidence.names", text2, (Casing)0, false, true, false, (Human)null) ?? ""; } catch { } string text4 = (text + " " + text2 + " " + text3).ToLowerInvariant(); bool flag = false; string[] array2 = array; foreach (string value2 in array2) { if (text4.Contains(value2)) { flag = true; break; } } if (flag) { bool flag2 = false; try { flag2 = value.isInventoryItem; } catch { } ManualLogSource logger = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(63, 4, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist Probe] name='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' presetName='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' display='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' isInventoryItem="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag2); } logger.LogInfo(val); num++; } } ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(103, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heist Probe] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" match(es). Put the 'name' of the one you want into [Heist] FolderPreset. ===== end ====="); } logger2.LogInfo(val); } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(46, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist Probe] DebugFindDocLikePresets failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger3.LogError(val2); } } internal static void DebugSpawnNextCandidate() { //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Expected O, but got Unknown //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Expected O, but got Unknown //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { List labels = new List(); List presets = new List(); InteriorControls instance = InteriorControls.Instance; if ((Object)(object)instance != (Object)null) { Add("homeFilePreset", instance.homeFilePreset); Add("document", instance.document); Add("residentsContract", instance.residentsContract); Add("letter", instance.letter); Add("note", instance.note); Add("receipt", instance.receipt); } string[] array = new string[11] { "Folder", "Documents", "Document", "Dossier", "CaseFile", "WrittenDocument", "Papers", "Report", "EvidenceFolder", "BriefcaseDocuments", "BriefcaseCustom" }; foreach (string text in array) { InteractablePreset pr = null; try { pr = Toolbox.Instance.GetInteractablePreset(text); } catch { } Add("'" + text + "'", pr); } if (presets.Count == 0) { Plugin.Logger.LogWarning((object)"[Heist Probe] no candidates."); return; } int num = (_probeSpawnIdx % presets.Count + presets.Count) % presets.Count; _probeSpawnIdx = num + 1; InteractablePreset val = presets[num]; string text2 = labels[num]; BepInExInfoLogInterpolatedStringHandler val2; if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { ManualLogSource logger = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(74, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist Probe] candidate ["); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" -> (null), skipping. Press again for the next."); } logger.LogInfo(val2); return; } Player instance2 = Player.Instance; if ((Object)(object)instance2 == (Object)null) { return; } Vector3 val3 = ((Component)instance2).transform.position + ((Component)instance2).transform.forward * 0.6f; Human val4 = Rewards.ResolveFixer(); Interactable val5 = null; try { val5 = InteractableCreator.Instance.CreateWorldInteractable(val, val4, val4, val4, val3, Vector3.zero, (List)null, (Object)null, ""); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val6 = new BepInExWarningLogInterpolatedStringHandler(32, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[Heist Probe] spawn threw for "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(ex.Message); } logger2.LogWarning(val6); } bool flag2 = false; try { flag2 = val.isInventoryItem; } catch { } ManualLogSource logger3 = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(131, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heist Probe] spawned ["); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("='"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(PresetName(val)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' isInventoryItem="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted((val5 == null) ? " (SPAWN FAILED)" : ""); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" at your feet — pick it up + right-click to throw. Press again for the next candidate."); } logger3.LogInfo(val2); void Add(string label, InteractablePreset item) { labels.Add(label); presets.Add(item); } } catch (Exception ex2) { ManualLogSource logger4 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val7 = new BepInExErrorLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("[Heist Probe] DebugSpawnNextCandidate failed: "); ((BepInExLogInterpolatedStringHandler)val7).AppendFormatted(ex2); } logger4.LogError(val7); } } } public static class HeatMeterState { public static float Value => Mathf.Clamp01(SyndicateState.Data?.ResidualHeat ?? 0f); public static int ContributorCount => (SyndicateState.Data?.ResidualHeatContributors?.Count).GetValueOrDefault(); public static void Add(float bandFraction, int victimId, string victimName) { //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown bool flag = default(bool); try { ConfigEntry residualHeatEnabled = SyndicateConfig.ResidualHeatEnabled; if (residualHeatEnabled != null && !residualHeatEnabled.Value) { return; } SyndicateData data = SyndicateState.Data; if (data == null) { return; } float num = Mathf.Clamp(SyndicateConfig.ResidualHeatPerMurderMax?.Value ?? 0.2f, 0.01f, 1f); float num2 = Mathf.Clamp01(bandFraction) * num; if (!(num2 <= 0.0001f)) { float residualHeat = data.ResidualHeat; data.ResidualHeat = Mathf.Clamp01(data.ResidualHeat + num2); SyndicateData syndicateData = data; if (syndicateData.ResidualHeatContributors == null) { List list = (syndicateData.ResidualHeatContributors = new List()); } data.ResidualHeatContributors.Add(new ResidualHeatContributionDto { VictimId = victimId, VictimName = (victimName ?? ""), Amount = data.ResidualHeat - residualHeat }); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(72, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] Residual +"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.ResidualHeat - residualHeat, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" from "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Name(victimName, victimId)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (cold, left traces) -> meter "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.ResidualHeat, "P0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.ResidualHeatContributors.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" contributor(s))."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Heat] HeatMeterState.Add failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } public static void Clear() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown try { SyndicateData data = SyndicateState.Data; if (data != null) { data.ResidualHeat = 0f; data.ResidualHeatContributors?.Clear(); data.HeatPunishLatched = false; try { EvidenceHeist.CancelActive(); } catch { } Plugin.Logger.LogInfo((object)"[Heat] Residual-evidence meter cleared."); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] HeatMeterState.Clear failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void Tick() { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown try { SyndicateData data = SyndicateState.Data; if (data == null || SyndicateState.IsWorldLoading) { return; } ConfigEntry residualHeatEnabled = SyndicateConfig.ResidualHeatEnabled; if (residualHeatEnabled != null && !residualHeatEnabled.Value) { return; } SyndicateData syndicateData = data; if (syndicateData.Heist == null) { HeistDto heistDto = (syndicateData.Heist = new HeistDto()); } EvidenceHeist.CleanupOrphan(data); if (data.HeatPunishLatched) { if (Value >= 0.999f) { Clear(); } else { data.HeatPunishLatched = false; } return; } if (Value >= 0.999f) { EvidenceHeist.Punish(); return; } ConfigEntry heistEnabled = SyndicateConfig.HeistEnabled; if (heistEnabled != null && !heistEnabled.Value) { return; } float num = Mathf.Clamp(SyndicateConfig.HeistOfferThreshold?.Value ?? 0.8f, 0.1f, 0.95f); switch (data.Heist.Stage) { case "None": if (Value >= num && ContributorCount > 0) { EvidenceHeist.Offer(); } break; case "Offered": EvidenceHeist.EnsureOfferVmail(); EvidenceHeist.EnsureHeistCase(); EvidenceHeist.TrySpawnFolder(); break; case "Spawned": EvidenceHeist.EnsureHeistCase(); EvidenceHeist.WatchSpawned(); break; case "Stolen": EvidenceHeist.EnsureHeistCase(); EvidenceHeist.WatchStolen(); break; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] Tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } internal static class HomeVacateQueue { private enum Result { Vacated, Retry, Drop } internal static void EnqueueForScene(CrimeScene s) { //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { ConfigEntry homeVacateEnabled = SyndicateConfig.HomeVacateEnabled; if ((homeVacateEnabled != null && !homeVacateEnabled.Value) || s == null) { return; } SyndicateData data = SyndicateState.Data; if (data == null || data.PendingHomeVacates == null) { return; } Human val = s.Victim ?? StableIds.ResolveHumanIncludingDead(s.VictimId); NewAddress val2 = (((Object)(object)val != (Object)null) ? val.home : null); if ((Object)(object)val2 == (Object)null) { return; } long num = StableIds.LocationKey((NewGameLocation)(object)val2); if (num == 0L) { return; } long num2 = ((s.LocKey != 0L) ? s.LocKey : StableIds.LocationKey(s.Location)); if (num == num2) { return; } foreach (HomeVacateDto pendingHomeVacate in data.PendingHomeVacates) { if (pendingHomeVacate != null && pendingHomeVacate.HomeLocKey == num && !pendingHomeVacate.Applied) { return; } } int num3 = Math.Max(0, SyndicateConfig.HomeVacateDelayHours?.Value ?? 24); string dueAt = ""; try { TimeData val3 = Lib.Time.CurrentDateTime; val3 = ((TimeData)(ref val3)).AddHours(num3); dueAt = ((TimeData)(ref val3)).Serialize(); } catch { } data.PendingHomeVacates.Add(new HomeVacateDto { VictimId = s.VictimId, HomeLocKey = num, HomeName = (s.VictimName ?? ""), DueAt = dueAt, Applied = false }); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(82, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Cleanup] queued home-vacate for "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(Redact.Name(s.VictimName, s.VictimId)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("'s residence in ~"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("h (killed away from home; loc "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")."); } logger.LogInfo(val4); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Cleanup] EnqueueForScene failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger2.LogWarning(val5); } } internal static void Tick() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) try { if (SyndicateState.IsWorldLoading) { return; } List list = SyndicateState.Data?.PendingHomeVacates; if (list == null || list.Count == 0) { return; } ConfigEntry homeVacateEnabled = SyndicateConfig.HomeVacateEnabled; if (homeVacateEnabled != null && !homeVacateEnabled.Value) { return; } TimeData currentDateTime = Lib.Time.CurrentDateTime; for (int num = list.Count - 1; num >= 0; num--) { HomeVacateDto homeVacateDto = list[num]; if (homeVacateDto == null) { list.RemoveAt(num); } else if (!homeVacateDto.Applied && !string.IsNullOrEmpty(homeVacateDto.DueAt)) { bool flag; try { flag = TimeData.Deserialize(homeVacateDto.DueAt) <= currentDateTime; } catch { flag = false; } if (flag) { switch (TryVacate(homeVacateDto, ignorePlayerPresence: false)) { case Result.Vacated: homeVacateDto.Applied = true; break; case Result.Drop: list.RemoveAt(num); break; } } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(23, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Cleanup] Tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static void ReapplyOnLoad() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown bool flag = default(bool); try { ConfigEntry homeVacateEnabled = SyndicateConfig.HomeVacateEnabled; if (homeVacateEnabled != null && !homeVacateEnabled.Value) { return; } List list = SyndicateState.Data?.PendingHomeVacates; if (list == null || list.Count == 0) { return; } int num = 0; for (int num2 = list.Count - 1; num2 >= 0; num2--) { HomeVacateDto homeVacateDto = list[num2]; if (homeVacateDto == null) { list.RemoveAt(num2); } else if (homeVacateDto.Applied) { switch (TryVacate(homeVacateDto, ignorePlayerPresence: true)) { case Result.Vacated: num++; break; case Result.Drop: list.RemoveAt(num2); break; } } } if (num > 0) { ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(93, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Cleanup] re-asserted "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" home-vacate(s) after load (dead owners re-added by the world rebuild)."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Cleanup] ReapplyOnLoad failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static Result TryVacate(HomeVacateDto e, bool ignorePlayerPresence) { //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown bool flag = default(bool); try { NewGameLocation val = StableIds.ResolveLocation(e.HomeLocKey); NewAddress val2 = (((Object)(object)val != (Object)null) ? val.thisAsAddress : null); if ((Object)(object)val2 == (Object)null) { return Result.Retry; } if ((Object)(object)val2.residence == (Object)null) { return Result.Drop; } if (val2.company != null && (!((SoCustomComparison)(object)val2.company.preset != (SoCustomComparison)null) || !val2.company.preset.isSelfEmployed)) { return Result.Drop; } if (val2.owners != null) { Enumerator enumerator = val2.owners.GetEnumerator(); while (enumerator.MoveNext()) { Human current = enumerator.Current; if ((Object)(object)current != (Object)null && !((Actor)current).isDead) { return Result.Drop; } } } if (val2.inhabitants != null) { Enumerator enumerator = val2.inhabitants.GetEnumerator(); while (enumerator.MoveNext()) { Human current2 = enumerator.Current; if ((Object)(object)current2 != (Object)null && !((Actor)current2).isDead) { return Result.Drop; } } } if (!ignorePlayerPresence && !PlayerAway(val2)) { return Result.Retry; } val.RemoveAllInhabitantFurniture(false, (RemoveInteractablesOption)1); if (val2.inhabitants != null) { val2.inhabitants.Clear(); } if (val2.owners != null) { val2.owners.Clear(); } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(78, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Cleanup] vacated "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(string.IsNullOrEmpty(e.HomeName) ? "a victim's" : (Redact.Name(e.HomeName, e.VictimId) + "'s")); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" home (loc "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(e.HomeLocKey); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") — away kill, case resolved, no living resident."); } logger.LogInfo(val3); return Result.Vacated; } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(32, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Cleanup] vacate failed (loc "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(e.HomeLocKey); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("): "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); return Result.Retry; } } private static bool PlayerAway(NewAddress addr) { try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return false; } int id = addr.id; NewGameLocation currentGameLocation = ((Actor)instance).currentGameLocation; if ((Object)(object)currentGameLocation != (Object)null && (Object)(object)currentGameLocation.thisAsAddress != (Object)null && currentGameLocation.thisAsAddress.id == id) { return false; } NewGameLocation previousGameLocation = ((Actor)instance).previousGameLocation; if ((Object)(object)previousGameLocation != (Object)null && (Object)(object)previousGameLocation.thisAsAddress != (Object)null && previousGameLocation.thisAsAddress.id == id) { return false; } NewBuilding building = ((NewGameLocation)addr).building; NewBuilding currentBuilding = ((Actor)instance).currentBuilding; if ((Object)(object)building != (Object)null && (Object)(object)currentBuilding != (Object)null && ((Il2CppObjectBase)building).Pointer == ((Il2CppObjectBase)currentBuilding).Pointer) { return false; } return true; } catch { return false; } } } internal static class InvestigationTimer { private static int ResolveDelayH => SyndicateConfig.WarrantResolveHours?.Value ?? 2; private static int WarrantH => SyndicateConfig.WarrantDurationHours?.Value ?? 72; public static void Hook() { Lib.Time.OnHourChanged += delegate { Tick(); }; } public static void OnIdentified(string victimName, string message) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] IDENTIFIED in the killing of "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Person(victimName)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger.LogInfo(val); Notify(message); if (!data.ActiveWarrant && !data.InvestigationActive) { data.InvestigationActive = true; TimeData val2 = Lib.Time.CurrentDateTime; val2 = ((TimeData)(ref val2)).AddHours(ResolveDelayH); data.InvestigationExpires = ((TimeData)(ref val2)).Serialize(); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(66, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] Warrant lands in "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ResolveDelayH); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h (positive ID — location doesn't matter)."); } logger2.LogInfo(val); } } public static void OnSuspicious(string victimName, string message) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(92, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] SUSPICIOUS: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Person(victimName)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s body was found, no positive ID. Enforcers are investigating the scene."); } logger.LogInfo(val); Notify(message); } public static void ResolveNow() { if (!SyndicateState.Data.InvestigationActive) { Plugin.Logger.LogInfo((object)"[Heat] No pending identification to resolve."); } else { IssueWarrant(); } } private static void Tick() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) SyndicateData data = SyndicateState.Data; if (!data.InvestigationActive) { return; } try { if (Lib.Time.CurrentDateTime >= TimeData.Deserialize(data.InvestigationExpires)) { IssueWarrant(); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] Investigation tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void IssueWarrant() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) SyndicateData data = SyndicateState.Data; data.InvestigationActive = false; data.ActiveWarrant = true; NewsEngine.RequestRegen(); TimeData val = Lib.Time.CurrentDateTime; val = ((TimeData)(ref val)).AddHours(WarrantH); data.WarrantExpires = ((TimeData)(ref val)).Serialize(); data.SuspicionState = SuspicionState.Identified; Plugin.Logger.LogInfo((object)"[Heat] Resolve window closed -> WARRANT issued. Enforcers are hunting the player (Phase 5)."); Notify("A warrant has been issued in your name. Enforcers are now hunting you — lie low until it expires."); ManhuntController.OnWarrantIssued(); } private static void Notify(string text) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { MessageQueue.Enqueue(text); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Heat] Notify failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } public enum HuntMode { EnforcerPursuit, GlobalIllegal } internal static class ManhuntController { private const string IllegalKey = "syndicate.warrant"; private const float RepersueCooldownSec = 5f; private static float _nextIllegalRefresh; private static bool _losWarned; private static int _raidHomeId = int.MinValue; private static int _raidLastLoggedState = -1; private const float GuardRepostCooldownSec = 30f; private const float GuardActivateGraceSec = 45f; private const float GuardArrivalGraceSec = 180f; private const float GuardAbsentGraceSec = 90f; private const float RaidArrivedFallbackSec = 150f; private static NewGameLocation _landing; private static NewNode _doorstep; private static float _lastGuardPostAt; private static float _guardAbsentSince = -1f; private static float _raidArrivedSince = -1f; private static readonly Dictionary _lastPersueAt = new Dictionary(); private static readonly Dictionary _recentHunters = new Dictionary(); private const float RecentHunterTtlSec = 15f; private static bool _wasInHome; private static float _lastHomeBreachAt = -999f; private const float HomeBreachDebounceSec = 4f; private static float RepMsgDelay => SyndicateConfig.RepMessageDelaySeconds?.Value ?? 10f; private static int WarrantH => SyndicateConfig.WarrantDurationHours?.Value ?? 48; private static float IllegalRefreshS => SyndicateConfig.IllegalRefreshSeconds?.Value ?? 30f; private static bool GlobalIllegalMode => (SyndicateConfig.HuntMode?.Value ?? HuntMode.EnforcerPursuit) == HuntMode.GlobalIllegal; public static void Tick() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (SyndicateState.IsWorldLoading) { return; } SyndicateData data = SyndicateState.Data; if (!data.ActiveWarrant) { return; } try { if (string.IsNullOrEmpty(data.WarrantExpires)) { data.WarrantExpires = SafeAddHours(WarrantH); } if (string.IsNullOrEmpty(data.WarrantExpires)) { ClearWarrant(busted: false); return; } if (Lib.Time.CurrentDateTime >= TimeData.Deserialize(data.WarrantExpires)) { ClearWarrant(busted: false); return; } } catch { data.WarrantExpires = SafeAddHours(WarrantH); } if (GlobalIllegalMode) { if (Time.time >= _nextIllegalRefresh) { ApplyIllegal(); _nextIllegalRefresh = Time.time + Math.Max(2f, IllegalRefreshS * 0.5f); } } else { PursuitTick(); } if (data.RaidLaunched) { TrackHomeRaid(); } if (data.ActiveWarrant && data.RaidLaunched && (!data.RaidWeaponSweepDone || !data.CruncherRaidCheckDone) && _raidHomeId == int.MinValue) { RunRaidSweeps(); } MaintainHomeGuard(); SafehouseTick(); } private static void PursuitTick() { //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) bool flag4 = default(bool); try { GameplayController instance = GameplayController.Instance; Player instance2 = Player.Instance; if ((Object)(object)instance == (Object)null || instance.enforcers == null || (Object)(object)instance2 == (Object)null || ((Actor)instance2).isHiding) { return; } Interactable interactable = ((Actor)instance2).interactable; if (interactable == null) { return; } Vector3 position = ((Component)instance2).transform.position; NewBuilding currentBuilding = ((Actor)instance2).currentBuilding; float num = SyndicateConfig.PursuitMaxDistanceMeters?.Value ?? 50f; float num2 = num * num; float num3 = SyndicateConfig.PursuitResponseRange?.Value ?? 5f; Enumerator enumerator = instance.enforcers.GetEnumerator(); RaycastHit val2 = default(RaycastHit); while (enumerator.MoveNext()) { Human current = enumerator.Current; if ((Object)(object)current == (Object)null || ((Actor)current).isDead) { continue; } NewAIController ai = ((Actor)current).ai; if ((Object)(object)ai == (Object)null || ai.ko) { continue; } try { if (ai.persuit && (Object)(object)ai.persuitTarget != (Object)null && ai.persuitTarget.isPlayer) { continue; } } catch { } bool flag = false; try { flag = (Object)(object)currentBuilding != (Object)null && (Object)(object)((Actor)current).currentBuilding != (Object)null && ((Il2CppObjectBase)((Actor)current).currentBuilding).Pointer == ((Il2CppObjectBase)currentBuilding).Pointer; } catch { } if (!flag) { float sqrMagnitude; try { Vector3 val = ((Component)current).transform.position - position; sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; } catch { continue; } if (sqrMagnitude > num2) { continue; } } bool flag2 = false; try { flag2 = ((Actor)current).CanISee(interactable); } catch { } if (!flag2) { continue; } ConfigEntry pursuitRequireLineOfSight = SyndicateConfig.PursuitRequireLineOfSight; if (pursuitRequireLineOfSight == null || pursuitRequireLineOfSight.Value) { bool flag3 = false; try { flag3 = ((Actor)current).ActorRaycastCheck((Actor)(object)instance2, num, ref val2, false, default(Color), default(Color), default(Color), 0f); } catch (Exception ex) { flag3 = true; if (!_losWarned) { _losWarned = true; ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(71, 1, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Manhunt] ActorRaycastCheck failed ("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") — LOS gate disabled this session."); } logger.LogWarning(val3); } } if (!flag3) { continue; } } int humanID = current.humanID; if (!_lastPersueAt.TryGetValue(humanID, out var value) || !(Time.time - value < 5f)) { _lastPersueAt[humanID] = Time.time; try { ai.SetPersue((Actor)(object)instance2, false, 2, true, num3); } catch { } ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Manhunt] Enforcer "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(Redact.Actor(current)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" spotted you — pursuing."); } logger2.LogInfo(val4); } } } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Manhunt] PursuitTick failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2.Message); } logger3.LogWarning(val3); } } public static void CancelAllPursuits() { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown bool flag = default(bool); try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.enforcers == null) { return; } int num = 0; Enumerator enumerator = instance.enforcers.GetEnumerator(); while (enumerator.MoveNext()) { Human current = enumerator.Current; if ((Object)(object)current == (Object)null) { continue; } NewAIController ai = ((Actor)current).ai; if ((Object)(object)ai == (Object)null) { continue; } try { if (ai.persuit && (Object)(object)ai.persuitTarget != (Object)null && ai.persuitTarget.isPlayer) { ai.CancelPersue(); num++; } } catch { } } if (num > 0) { ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] Called off "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" enforcer pursuit(s)."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Manhunt] CancelAllPursuits failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } public static int ActiveHunters() { int num = 0; try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.enforcers == null) { return 0; } Enumerator enumerator = instance.enforcers.GetEnumerator(); while (enumerator.MoveNext()) { Human current = enumerator.Current; if ((Object)(object)current == (Object)null) { continue; } NewAIController ai = ((Actor)current).ai; try { if ((Object)(object)ai != (Object)null && ai.persuit && (Object)(object)ai.persuitTarget != (Object)null && ai.persuitTarget.isPlayer) { num++; } } catch { } } } catch { } return num; } public static void StartHuntNow(string victimName, string playerMessage, float messageDelay = 0f) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; bool activeWarrant = data.ActiveWarrant; if (activeWarrant) { data.RaidWeaponSweepDone = false; data.CruncherRaidCheckDone = false; } data.InvestigationActive = false; data.InvestigationExpires = ""; data.ActiveWarrant = true; NewsEngine.RequestRegen(); data.WarrantExpires = SafeAddHours(WarrantH); data.SuspicionState = SuspicionState.Identified; if (GlobalIllegalMode) { ApplyIllegal(); _nextIllegalRefresh = Time.time + Math.Max(2f, IllegalRefreshS * 0.5f); } _wasInHome = PlayerInsideHome(Player.Instance); DispatchHomeRaid(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(59, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(activeWarrant ? "Hunt refreshed" : "Hunt started"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Redact.Person(victimName)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("). Warrant expires "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.WarrantExpires); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Enforcers hunting ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GlobalIllegalMode ? "global-illegal" : "enforcer-pursuit"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" mode)."); } logger.LogInfo(val); if (messageDelay > 0f) { DeferNotify(playerMessage, messageDelay); } else { Notify(playerMessage); } } public static void RegisterIdentifiedMurder(long locKey) { SyndicateData data = SyndicateState.Data; data.WarrantMurderCount++; if (locKey != 0L) { if (data.WarrantSceneLocKeys == null) { data.WarrantSceneLocKeys = new List(); } if (!data.WarrantSceneLocKeys.Contains(locKey)) { data.WarrantSceneLocKeys.Add(locKey); } } } public static void OnWarrantIssued() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (GlobalIllegalMode) { ApplyIllegal(); _nextIllegalRefresh = Time.time + Math.Max(2f, IllegalRefreshS * 0.5f); } _wasInHome = PlayerInsideHome(Player.Instance); DispatchHomeRaid(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] Warrant issued — hunt active ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GlobalIllegalMode ? "global-illegal" : "enforcer-pursuit"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" mode)."); } logger.LogInfo(val); } private static void DispatchHomeRaid() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; if (data.RaidLaunched) { return; } ConfigEntry stakeoutEnabled = SyndicateConfig.StakeoutEnabled; if (stakeoutEnabled != null && !stakeoutEnabled.Value) { return; } try { Player instance = Player.Instance; NewAddress val = (((Object)(object)instance != (Object)null) ? ((Human)instance).home : null); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogInfo((object)"[Manhunt] No home to raid (homeless play) — skipping home raid."); return; } data.RaidLaunched = true; float num = SyndicateConfig.HomeRaidDelayHours?.Value ?? 0.05f; bool flag = SyndicateConfig.StakeoutForceCrimeScene?.Value ?? false; _raidHomeId = SafeAddrId(val); _raidLastLoggedState = -1; int value = -1; try { value = ((GameplayController.Instance.enforcers != null) ? GameplayController.Instance.enforcers.Count : (-1)); } catch { } GameplayController.Instance.CallEnforcers((NewGameLocation)(object)val, flag, false, num); Plugin.LogVerbose($"[Raid] Home raid dispatched to '{Redact.Place(SafeLocName((NewGameLocation)(object)val))}' (addrId={_raidHomeId}, forceCrimeScene={flag}, delay={num}h). {value} enforcer(s) in the city."); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Manhunt] DispatchHomeRaid failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } } private static void RunRaidSweeps() { WeaponConsequences.RunHomeRaidSweep(); CruncherRaidCheck.Run(); } private static void TrackHomeRaid() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected I4, but got Unknown if (_raidHomeId == int.MinValue) { return; } try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.enforcerCalls == null) { return; } bool flag = false; Enumerator enumerator = instance.enforcerCalls.Values.GetEnumerator(); while (enumerator.MoveNext()) { EnforcerCall current = enumerator.Current; if (current == null || current.isStreet || current.id != _raidHomeId) { continue; } flag = true; int num = (int)current.state; if (num != _raidLastLoggedState) { _raidLastLoggedState = num; int value = 0; try { value = ((current.response != null) ? current.response.Count : 0); } catch { } Plugin.LogVerbose($"[Raid] Home call -> {StateName(num)} ({value} responder(s), arrival={current.arrivalTime:0.##}, guard={current.guard})."); if (num >= 2) { LogCallResponders(current); } if (num == 2) { _raidArrivedSince = Time.time; } } if (SyndicateState.Data.ActiveWarrant) { if (num >= 3) { PostHomeGuard(current); RunRaidSweeps(); } else if (num == 2 && _raidArrivedSince >= 0f && Time.time - _raidArrivedSince > 150f) { Plugin.LogVerbose("[Raid] Sweep stuck at 'arrived' — posting the landing guard anyway."); PostHomeGuard(current); RunRaidSweeps(); } } if (num >= 3) { _raidHomeId = int.MinValue; _raidArrivedSince = -1f; } return; } if (!flag && _raidLastLoggedState >= 0) { Plugin.LogVerbose("[Raid] Home call gone from the list — posting the landing guard now."); if (SyndicateState.Data.ActiveWarrant) { PostHomeGuard(null); RunRaidSweeps(); } _raidHomeId = int.MinValue; _raidArrivedSince = -1f; } } catch { } } private static void PostHomeGuard(EnforcerCall call) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; if (data.StakeoutPosted) { return; } ConfigEntry stakeoutEnabled = SyndicateConfig.StakeoutEnabled; if (stakeoutEnabled != null && !stakeoutEnabled.Value) { return; } try { Player instance = Player.Instance; NewAddress val = (((Object)(object)instance != (Object)null) ? ((Human)instance).home : null); if ((Object)(object)val == (Object)null) { return; } ResolveStakeoutSpot(val); if ((Object)(object)_landing == (Object)null) { Plugin.Logger.LogWarning((object)"[Raid] No common area found outside the home — can't post a guard."); return; } data.StakeoutPosted = true; _lastGuardPostAt = Time.time; Human val2 = PickGuard(call, -1); if ((Object)(object)val2 == (Object)null || (Object)(object)((Actor)val2).ai == (Object)null) { Plugin.LogVerbose("[Raid] Stakeout live, but no free enforcer to post yet — MaintainHomeGuard will retry."); } else if (AssignGuardGoal(val2)) { data.StakeoutGuardId = val2.humanID; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Raid] PostHomeGuard failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); } } private static void ResolveStakeoutSpot(NewAddress home) { if ((Object)(object)_landing != (Object)null) { return; } try { NodeAccess mainEntrance = ((NewGameLocation)home).GetMainEntrance(); if (mainEntrance != null) { try { _landing = mainEntrance.GetOtherGameLocation((NewGameLocation)(object)home); } catch { } try { NewGameLocation val = ((mainEntrance.fromNode != null) ? mainEntrance.fromNode.gameLocation : null); _doorstep = (((Object)(object)val != (Object)null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)home).Pointer) ? mainEntrance.toNode : mainEntrance.fromNode); } catch { } } if ((Object)(object)_landing == (Object)null) { try { if ((Object)(object)((NewGameLocation)home).floor != (Object)null) { _landing = (NewGameLocation)(object)((NewGameLocation)home).floor.GetLobbyAddress(); } } catch { } } if (_doorstep == null && (Object)(object)_landing != (Object)null) { try { _doorstep = _landing.anchorNode; return; } catch { return; } } } catch { } } private static bool AssignGuardGoal(Human guard) { //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown try { if (IsAlreadyCommitted(guard)) { Plugin.LogVerbose("[Raid] " + Redact.Actor(guard) + " is already committed to another guard/scene post — skipping."); return false; } RemoveOurGuardGoalFrom(guard); float num = SyndicateConfig.StakeoutGuardHours?.Value ?? 24f; NewAIGoal val = ((Actor)guard).ai.CreateNewGoal(RoutineControls.Instance.enforcerGuardDuty, 0f, num, _doorstep, (Interactable)null, _landing, (SocialGroup)null, (Murder)null, 0); try { ((Actor)guard).ai.AITick(true, true); } catch { } _lastGuardPostAt = Time.time; _guardAbsentSince = -1f; bool flag = val != null; bool value = false; try { value = val != null && val.isActive; } catch { } Plugin.LogVerbose($"[Raid] Posted {Redact.Actor(guard)} on guard at '{SafeLocName(_landing)}' (isLobby={SafeIsLobby(_landing)}, node={((_doorstep != null) ? "doorstep" : "none")}, dur={num}h, goal={(flag ? "created" : "NULL")}, active={value})."); return flag; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Raid] AssignGuardGoal failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); return false; } } private static void MaintainHomeGuard() { SyndicateData data = SyndicateState.Data; if (!data.StakeoutPosted) { return; } ConfigEntry stakeoutEnabled = SyndicateConfig.StakeoutEnabled; if (stakeoutEnabled != null && !stakeoutEnabled.Value) { return; } try { if ((Object)(object)_landing == (Object)null) { NewAddress val = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).home : null); if ((Object)(object)val == (Object)null) { return; } ResolveStakeoutSpot(val); if ((Object)(object)_landing == (Object)null) { return; } } Human val2 = null; try { if ((Object)(object)CityData.Instance != (Object)null && data.StakeoutGuardId >= 0) { CityData.Instance.GetHuman(data.StakeoutGuardId, ref val2, false); } } catch { } NewAIGoal val3 = (((Object)(object)val2 != (Object)null && !((Actor)val2).isDead && (Object)(object)((Actor)val2).ai != (Object)null && !((Actor)val2).ai.ko && SafeOnDuty(val2)) ? FindOurGuardGoal(val2) : null); string text; if (val3 != null) { bool flag = false; try { flag = val3.isActive; } catch { } if (flag) { bool flag2 = true; try { flag2 = (Object)(object)((Actor)val2).currentGameLocation != (Object)null && ((Il2CppObjectBase)((Actor)val2).currentGameLocation).Pointer == ((Il2CppObjectBase)_landing).Pointer; } catch { flag2 = true; } if (flag2) { _guardAbsentSince = -1f; return; } if (Time.time - _lastGuardPostAt < 180f) { return; } if (_guardAbsentSince < 0f) { _guardAbsentSince = Time.time; return; } if (Time.time - _guardAbsentSince < 90f) { return; } text = "active but absent (wandered / re-tasked)"; } else { if (Time.time - _lastGuardPostAt < 45f) { return; } text = "goal never went active (outranked)"; } } else { text = "guard lost (dead/off-duty/ko/goal gone)"; } if (!(Time.time - _lastGuardPostAt < 30f)) { if ((Object)(object)val2 != (Object)null) { RemoveOurGuardGoalFrom(val2); } data.StakeoutGuardId = -1; _guardAbsentSince = -1f; Human val4 = PickGuard(null, ((Object)(object)val2 != (Object)null) ? val2.humanID : (-1)); if ((Object)(object)val4 == (Object)null) { val4 = PickGuard(null, -1); } _lastGuardPostAt = Time.time; if ((Object)(object)val4 == (Object)null || (Object)(object)((Actor)val4).ai == (Object)null) { Plugin.LogVerbose("[Raid] Guard post empty (" + text + "); nobody free — will retry."); } else if (AssignGuardGoal(val4)) { data.StakeoutGuardId = val4.humanID; Plugin.LogVerbose("[Raid] Swapped home guard (" + text + ")."); } } } catch { } } private static NewAIGoal FindOurGuardGoal(Human g) { try { AIGoalPreset val = (((Object)(object)RoutineControls.Instance != (Object)null) ? RoutineControls.Instance.enforcerGuardDuty : null); if ((SoCustomComparison)(object)val == (SoCustomComparison)null || (Object)(object)((Actor)g).ai == (Object)null || ((Actor)g).ai.goals == null || (Object)(object)_landing == (Object)null) { return null; } IntPtr pointer = ((Il2CppObjectBase)_landing).Pointer; Enumerator enumerator = ((Actor)g).ai.goals.GetEnumerator(); while (enumerator.MoveNext()) { NewAIGoal current = enumerator.Current; if (current == null) { continue; } try { if ((SoCustomComparison)(object)current.preset == (SoCustomComparison)null || ((Il2CppObjectBase)current.preset).Pointer != ((Il2CppObjectBase)val).Pointer || !((Object)(object)current.gameLocation != (Object)null) || !(((Il2CppObjectBase)current.gameLocation).Pointer == pointer)) { continue; } return current; } catch { } } } catch { } return null; } private static bool IsAlreadyCommitted(Human h) { try { if ((Object)(object)h == (Object)null) { return false; } GameplayController instance = GameplayController.Instance; if ((Object)(object)instance != (Object)null && instance.enforcerCalls != null) { Enumerator enumerator = instance.enforcerCalls.Values.GetEnumerator(); while (enumerator.MoveNext()) { EnforcerCall current = enumerator.Current; try { if (current != null && h.humanID >= 0 && current.guard == h.humanID) { return true; } } catch { } } } AIGoalPreset val = (((Object)(object)RoutineControls.Instance != (Object)null) ? RoutineControls.Instance.enforcerGuardDuty : null); IntPtr intPtr = (((Object)(object)_landing != (Object)null) ? ((Il2CppObjectBase)_landing).Pointer : IntPtr.Zero); if ((SoCustomComparison)(object)val != (SoCustomComparison)null && (Object)(object)((Actor)h).ai != (Object)null && ((Actor)h).ai.goals != null) { Enumerator enumerator2 = ((Actor)h).ai.goals.GetEnumerator(); while (enumerator2.MoveNext()) { NewAIGoal current2 = enumerator2.Current; if (current2 == null) { continue; } try { if ((SoCustomComparison)(object)current2.preset == (SoCustomComparison)null || ((Il2CppObjectBase)current2.preset).Pointer != ((Il2CppObjectBase)val).Pointer || (intPtr != IntPtr.Zero && (Object)(object)current2.gameLocation != (Object)null && ((Il2CppObjectBase)current2.gameLocation).Pointer == intPtr)) { continue; } return true; } catch { } } } } catch { } return false; } private static void RemoveOurGuardGoalFrom(Human g) { try { AIGoalPreset val = (((Object)(object)RoutineControls.Instance != (Object)null) ? RoutineControls.Instance.enforcerGuardDuty : null); if ((SoCustomComparison)(object)val == (SoCustomComparison)null || (Object)(object)g == (Object)null || (Object)(object)((Actor)g).ai == (Object)null || ((Actor)g).ai.goals == null) { return; } IntPtr intPtr = (((Object)(object)_landing != (Object)null) ? ((Il2CppObjectBase)_landing).Pointer : IntPtr.Zero); bool flag = intPtr != IntPtr.Zero; List list = new List(); Enumerator enumerator = ((Actor)g).ai.goals.GetEnumerator(); while (enumerator.MoveNext()) { NewAIGoal current = enumerator.Current; if (current != null) { list.Add(current); } } bool flag2 = false; bool flag3 = false; foreach (NewAIGoal item in list) { try { if ((SoCustomComparison)(object)item.preset == (SoCustomComparison)null || ((Il2CppObjectBase)item.preset).Pointer != ((Il2CppObjectBase)val).Pointer) { continue; } if (flag) { if (!((Object)(object)item.gameLocation == (Object)null) && !(((Il2CppObjectBase)item.gameLocation).Pointer != intPtr)) { goto IL_0134; } continue; } if (!flag3) { flag3 = true; Plugin.Logger.LogWarning((object)"[Raid] Landing unresolved — removing guard goals by preset only."); } goto IL_0134; IL_0134: bool flag4 = false; try { flag4 = item.isActive; } catch { } if (flag4) { item.Complete(); } else { item.Remove(); } flag2 = true; } catch { } } if (!flag2) { return; } try { ((Actor)g).ai.AITick(true, true); } catch { } } catch { } } private static void CancelHomeGuard() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; if (data.StakeoutGuardId >= 0) { try { Human val = null; try { if ((Object)(object)CityData.Instance != (Object)null) { CityData.Instance.GetHuman(data.StakeoutGuardId, ref val, false); } } catch { } if ((Object)(object)val != (Object)null) { if ((Object)(object)_landing == (Object)null) { NewAddress val2 = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).home : null); if ((Object)(object)val2 != (Object)null) { ResolveStakeoutSpot(val2); } } RemoveOurGuardGoalFrom(val); Plugin.LogVerbose("[Raid] Stood down home guard " + Redact.Actor(val) + "."); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Raid] CancelHomeGuard failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); } } data.StakeoutPosted = false; data.StakeoutGuardId = -1; _guardAbsentSince = -1f; _landing = null; _doorstep = null; } private static Human PickGuard(EnforcerCall call, int excludeId) { try { if (call != null && call.response != null) { Enumerator enumerator = call.response.GetEnumerator(); while (enumerator.MoveNext()) { int current = enumerator.Current; if (current == excludeId) { continue; } Human val = null; try { if ((Object)(object)CityData.Instance != (Object)null) { CityData.Instance.GetHuman(current, ref val, false); } } catch { } if ((Object)(object)val != (Object)null && !((Actor)val).isDead && (Object)(object)((Actor)val).ai != (Object)null && !((Actor)val).ai.ko && !IsAlreadyCommitted(val)) { return val; } } } } catch { } try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance != (Object)null && instance.enforcers != null) { Enumerator enumerator2 = instance.enforcers.GetEnumerator(); while (enumerator2.MoveNext()) { Human current2 = enumerator2.Current; if (!((Object)(object)current2 == (Object)null) && !((Actor)current2).isDead && !((Object)(object)((Actor)current2).ai == (Object)null) && !((Actor)current2).ai.ko && current2.humanID != excludeId) { bool flag = true; try { flag = ((Actor)current2).isOnDuty; } catch { } if (flag && !IsAlreadyCommitted(current2)) { return current2; } } } } } catch { } return null; } private static float RemainingWarrantHours() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) try { SyndicateData data = SyndicateState.Data; if (!string.IsNullOrEmpty(data.WarrantExpires)) { double totalHours = (TimeData.Deserialize(data.WarrantExpires) - Lib.Time.CurrentDateTime).TotalHours; if (totalHours > 0.5) { return (float)totalHours; } } } catch { } return WarrantH; } public static void DebugDumpGuardGoals() { //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown bool flag = default(bool); try { SyndicateData data = SyndicateState.Data; Human val = null; try { if ((Object)(object)CityData.Instance != (Object)null && data.StakeoutGuardId >= 0) { CityData.Instance.GetHuman(data.StakeoutGuardId, ref val, false); } } catch { } BepInExInfoLogInterpolatedStringHandler val2; if ((Object)(object)val == (Object)null || (Object)(object)((Actor)val).ai == (Object)null) { ManualLogSource logger = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Probe] No stakeout guard resolved (id="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(data.StakeoutGuardId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } logger.LogInfo(val2); return; } float num = 0f; try { num = SessionData.Instance.gameTime; } catch { } NewAIGoal currentGoal = ((Actor)val).ai.currentGoal; bool flag2 = true; try { flag2 = ((Actor)val).isOnDuty; } catch { } string text = "-"; float num2 = -1f; try { if (currentGoal != null && (SoCustomComparison)(object)currentGoal.preset != (SoCustomComparison)null) { text = ((Object)currentGoal.preset).name; } } catch { } try { if (currentGoal != null) { num2 = currentGoal.priority; } } catch { } ManualLogSource logger2 = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(49, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Probe] t="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "0.###"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(SafeNameH(val)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" onDuty="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" landing='"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(SafeLocName(_landing)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' current='"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' curPri="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2, "0.##"); } logger2.LogInfo(val2); if (((Actor)val).ai.goals != null) { Enumerator enumerator = ((Actor)val).ai.goals.GetEnumerator(); while (enumerator.MoveNext()) { NewAIGoal current = enumerator.Current; if (current == null) { continue; } string text2 = "?"; float num3 = -1f; float num4 = 0f; float num5 = 0f; bool flag3 = false; string text3 = "-"; try { if ((SoCustomComparison)(object)current.preset != (SoCustomComparison)null) { text2 = ((Object)current.preset).name; } } catch { } try { num3 = current.priority; } catch { } try { flag3 = current.isActive; } catch { } try { num4 = current.triggerTime; } catch { } try { num5 = current.duration; } catch { } try { if ((Object)(object)current.gameLocation != (Object)null) { text3 = ((Object)current.gameLocation).name; } } catch { } ManualLogSource logger3 = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(57, 7, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Probe] goal='"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' pri="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num3, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" active="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag3); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loc='"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text3); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' trig="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num4, "0.###"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" dur="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num5, "0.###"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" lateBy="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num - num4, "0.###"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("h"); } logger3.LogInfo(val2); } } else { Plugin.Logger.LogInfo((object)"[Probe] (goals list null)"); } } catch (Exception ex) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Probe] DumpGuardGoals failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger4.LogWarning(val3); } } public static void DumpEnforcerCalls() { //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected I4, but got Unknown bool flag = default(bool); try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null || instance.enforcerCalls == null) { Plugin.Logger.LogInfo((object)"[Raid] No enforcerCalls."); return; } int num = -1; try { num = ((instance.enforcers != null) ? instance.enforcers.Count : (-1)); } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(79, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Raid] === enforcer calls dump ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" enforcer(s) in city; tracked home addrId="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_raidHomeId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") ==="); } logger.LogInfo(val); int num2 = 0; Enumerator enumerator = instance.enforcerCalls.Values.GetEnumerator(); while (enumerator.MoveNext()) { EnforcerCall current = enumerator.Current; if (current != null) { num2++; int num3 = 0; try { num3 = ((current.response != null) ? current.response.Count : 0); } catch { } ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(73, 8, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Raid] id="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(current.id); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" street="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(current.isStreet); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" state="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(StateName((int)current.state)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" crimeScene="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(current.isCrimeScene); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" guard="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(current.guard); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" arrival="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(current.arrivalTime, "0.##"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" delay="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(current.delay, "0.##"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" responders="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num3); } logger2.LogInfo(val); LogCallResponders(current); } } if (num2 == 0) { Plugin.Logger.LogInfo((object)"[Raid] (no active calls)"); } } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Raid] DumpEnforcerCalls failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger3.LogWarning(val2); } } private static void LogCallResponders(EnforcerCall call) { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) try { if (call.response == null || call.response.Count == 0) { Plugin.Logger.LogInfo((object)"[Raid] (no responders)"); return; } Player instance = Player.Instance; Vector3 val = (((Object)(object)instance != (Object)null) ? ((Component)instance).transform.position : Vector3.zero); List list = new List(); Enumerator enumerator = call.response.GetEnumerator(); while (enumerator.MoveNext()) { int current = enumerator.Current; Human val2 = null; try { if ((Object)(object)CityData.Instance != (Object)null) { CityData.Instance.GetHuman(current, ref val2, false); } } catch { } if ((Object)(object)val2 == (Object)null) { list.Add($"#{current}?"); if (list.Count >= 8) { break; } continue; } string value = "?"; try { value = val2.GetCitizenName(); } catch { } float value2 = -1f; try { Vector3 val3 = ((Component)val2).transform.position - val; value2 = ((Vector3)(ref val3)).magnitude; } catch { } string value3 = "-"; try { if ((Object)(object)((Actor)val2).ai != (Object)null && ((Actor)val2).ai.currentGoal != null && (SoCustomComparison)(object)((Actor)val2).ai.currentGoal.preset != (SoCustomComparison)null) { value3 = ((Object)((Actor)val2).ai.currentGoal.preset).name; } } catch { } list.Add($"{value}@{value2:0}m/{value3}"); if (list.Count >= 8) { break; } } ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Raid] responders: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(string.Join(", ", list)); } logger.LogInfo(val4); } catch { } } private static string StateName(int s) { return s switch { 0 => "logged", 1 => "responding", 2 => "arrived", 3 => "completed", _ => s.ToString(), }; } public static void DebugForceHomeRaid() { SyndicateState.Data.RaidLaunched = false; SyndicateState.Data.RaidWeaponSweepDone = false; SyndicateState.Data.CruncherRaidCheckDone = false; DispatchHomeRaid(); } public static void ClearWarrant(bool busted) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; bool activeWarrant = data.ActiveWarrant; RemoveIllegal(); CancelAllPursuits(); CancelHomeGuard(); int num = 0; if (data.WarrantSceneLocKeys != null) { foreach (long warrantSceneLocKey in data.WarrantSceneLocKeys) { num += PlayerEvidence.ClearLocation(warrantSceneLocKey); } } bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (num > 0) { ManualLogSource logger = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(77, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] Case closed — cleared "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" scene fingerprint(s); they no longer matter."); } logger.LogInfo(val); } data.ActiveWarrant = false; data.WarrantExpires = ""; data.InvestigationActive = false; data.InvestigationExpires = ""; data.SuspicionState = SuspicionState.Clean; data.BustedPending = false; data.RaidLaunched = false; _raidHomeId = int.MinValue; data.RaidWeaponSweepDone = false; data.CruncherRaidCheckDone = false; data.StakeoutPosted = false; data.StakeoutGuardId = -1; data.WarrantMurderCount = 0; data.WarrantSceneLocKeys?.Clear(); _lastPersueAt.Clear(); _recentHunters.Clear(); _wasInHome = false; CrimeSceneManager.PruneResolvedMurderWeapons(); Notify(busted ? "The enforcers got their suspect — your warrant is closed." : "The heat is off — your warrant has expired. You're in the clear."); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] Warrant cleared ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(busted ? "busted" : "evaded"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger2.LogInfo(val); if (activeWarrant) { NewsEngine.Push(busted ? "Busted" : "WarrantExpired"); } } public static void OnBusted() { ClearWarrant(busted: true); } public static void ApplySyndicatePenalty(int victimId) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown bool flag = ContractManager.WasContractTarget(victimId); int num = ((!flag) ? (SyndicateConfig.RepPenaltyOnIdentifiedRandom?.Value ?? 10) : (SyndicateConfig.RepPenaltyOnIdentifiedContract?.Value ?? 25)); if (num > 0) { SyndicateData data = SyndicateState.Data; data.UnderworldRep = Math.Max(0, data.UnderworldRep - num); ManualLogSource logger = Plugin.Logger; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(73, 4, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] Syndicate penalty for being Identified ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag ? "contract" : "freelance"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): -"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" rep (now "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.UnderworldRep); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Tier "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateState.Tier); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger.LogInfo(val); DeferNotify(flag ? "The Syndicate doesn't tolerate sloppiness on their jobs — your standing has taken a hit." : "Freelancing sloppy work draws heat on all of us — the Syndicate noted it. Your standing slipped.", RepMsgDelay); } } public static void DeferNotify(string msg, float delaySeconds) { MessageQueue.Enqueue(msg, delaySeconds); } public static void FlushDeferredToasts() { MessageQueue.Tick(); } public static void DebugForceBusted() { WeaponConsequences.RunCarryCheckAtBust(); FineLedger.CollectOnBust(); OnBusted(); } private static void SafehouseTick() { //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown try { GameplayController instance = GameplayController.Instance; Player instance2 = Player.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null) { return; } float time = Time.time; if (instance.enforcers != null) { Enumerator enumerator = instance.enforcers.GetEnumerator(); while (enumerator.MoveNext()) { Human current = enumerator.Current; if ((Object)(object)current == (Object)null) { continue; } NewAIController ai = ((Actor)current).ai; try { if ((Object)(object)ai != (Object)null && ai.persuit && (Object)(object)ai.persuitTarget != (Object)null && ai.persuitTarget.isPlayer) { _recentHunters[current.humanID] = time; } } catch { } } } if (_recentHunters.Count > 0) { List list = new List(); foreach (KeyValuePair recentHunter in _recentHunters) { if (time - recentHunter.Value > 15f) { list.Add(recentHunter.Key); } } foreach (int item in list) { _recentHunters.Remove(item); } } bool num = PlayerInsideHome(instance2); if (num && !_wasInHome && _recentHunters.Count > 0) { OnHomeEntryDuringChase(instance2, time); } _wasInHome = num; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Safehouse] tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static bool PlayerInsideHome(Player p) { try { NewAddress val = (((Object)(object)p != (Object)null) ? ((Human)p).home : null); if ((Object)(object)val == (Object)null) { return false; } IntPtr pointer = ((Il2CppObjectBase)val).Pointer; NewRoom currentRoom = ((Actor)p).currentRoom; if ((Object)(object)currentRoom != (Object)null && (Object)(object)currentRoom.gameLocation != (Object)null) { return ((Il2CppObjectBase)currentRoom.gameLocation).Pointer == pointer; } NewGameLocation currentGameLocation = ((Actor)p).currentGameLocation; return (Object)(object)currentGameLocation != (Object)null && ((Il2CppObjectBase)currentGameLocation).Pointer == pointer; } catch { return false; } } private static void OnHomeEntryDuringChase(Player p, float now) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown ConfigEntry safehouseBreachEnabled = SyndicateConfig.SafehouseBreachEnabled; if ((safehouseBreachEnabled != null && !safehouseBreachEnabled.Value) || now - _lastHomeBreachAt < 4f) { return; } _lastHomeBreachAt = now; try { NewAddress home = ((Human)p).home; if ((Object)(object)home != (Object)null) { GameplayController.Instance.CallEnforcers((NewGameLocation)(object)home, false, false, 0f); Plugin.Logger.LogInfo((object)"[Safehouse] Breach dispatched — hunters saw you flee home; sweeping once (crimeScene=false, no tape)."); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Safehouse] Breach dispatch failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void ApplyIllegal() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown try { Lib.PlayerStatus.SetIllegalStatusModifier("syndicate.warrant", (TimeSpan?)TimeSpan.FromSeconds(Math.Max(5f, IllegalRefreshS)), true); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] SetIllegalStatusModifier failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void RemoveIllegal() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown try { Lib.PlayerStatus.RemoveIllegalStatusModifier("syndicate.warrant"); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] RemoveIllegalStatusModifier failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static string SafeAddHours(int h) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) try { TimeData val = Lib.Time.CurrentDateTime; val = ((TimeData)(ref val)).AddHours(h); return ((TimeData)(ref val)).Serialize(); } catch { return ""; } } private static string SafeNameH(Human h) { try { return ((Object)(object)h != (Object)null) ? h.GetCitizenName() : "enforcer"; } catch { return "enforcer"; } } private static bool SafeOnDuty(Human h) { try { return ((Actor)h).isOnDuty; } catch { return true; } } private static string SafeLocName(NewGameLocation loc) { try { return ((Object)(object)loc != (Object)null) ? ((Object)loc).name : "?"; } catch { return "?"; } } private static string SafeIsLobby(NewGameLocation loc) { try { return ((Object)(object)loc != (Object)null) ? loc.isLobby.ToString() : "?"; } catch { return "?"; } } private static int SafeAddrId(NewAddress a) { try { return ((Object)(object)a != (Object)null) ? a.id : int.MinValue; } catch { return int.MinValue; } } private static void Notify(string text) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { MessageQueue.Enqueue(text); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Manhunt] Notify failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } } internal static class MoleMail { private const string BlockDict = "dds.blocks"; private const int MaxMoleMails = 30; private static readonly string[] Codenames = new string[5] { "a friend in Records", "your ear in Dispatch", "the clerk in Evidence", "someone downtown who owes us", "a friend on the inside" }; private static string TreeId(int v) { return $"syn_mole_tree_{v}"; } private static string BlockId(int v) { return $"syn_mole_block_{v}"; } private static string MsgId(int v) { return $"syn_mole_msg_{v}"; } private static string InstId(int v) { return $"syn_mole_inst_{v}"; } public static void SendForScene(CrimeScene s, int printCount, List printExamples) { //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown bool flag = default(bool); try { if (s == null) { return; } ConfigEntry moleEmailEnabled = SyndicateConfig.MoleEmailEnabled; if (moleEmailEnabled != null && !moleEmailEnabled.Value) { return; } List list = new List(); if (printCount > 0) { string text = ((printExamples != null && printExamples.Count > 0) ? string.Join(", ", printExamples) : "things you handled"); string text2 = ((printExamples != null && printCount > printExamples.Count) ? ", and more" : ""); list.Add("- Your prints — lifted from " + text + text2 + "."); } if ((s.ForgedFall || s.ForgedOverdose) && s.ForgeWasViolent) { list.Add(s.ForgedFall ? "- The body was worked over first. Nobody falls with bruises like that." : "- The body was worked over first. Nobody overdoses with bruises like that."); } if (s.CameraNearNoted) { list.Add("- A camera caught you nearby. No name on it — yet."); } if (list.Count == 0) { return; } string body = "The file on " + SafeVictim(s) + " didn't close clean. It's cold now — no name pinned to you — but you left them something to chew on:\n\n" + string.Join("\n", list) + "\n\nTidy up next time. Cold is fine. A trail is not.\n\n— " + Codename(s.VictimId); List list2 = SyndicateState.Data?.MoleMails; if (list2 == null) { return; } list2.RemoveAll((MoleMailDto m) => m != null && m.VictimId == s.VictimId); MoleMailDto moleMailDto = new MoleMailDto { VictimId = s.VictimId, Body = body }; list2.Add(moleMailDto); while (list2.Count > 30) { list2.RemoveAt(0); } Toolbox instance = Toolbox.Instance; if (!((Object)(object)instance == (Object)null)) { RegisterOne(instance, moleMailDto); SendThread(moleMailDto); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(66, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Mole] tip-off v-mail sent for cold case #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(s.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" contributor line(s))."); } logger.LogInfo(val); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Mole] SendForScene failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } private static void SendThread(MoleMailDto dto) { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown bool flag = default(bool); try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } Human val = Rewards.ResolveFixer(); if ((Object)(object)val == (Object)null) { return; } float num = (((Object)(object)SessionData.Instance != (Object)null) ? SessionData.Instance.gameTime : 0f); string text = TreeId(dto.VictimId); MessageThreadSave val2 = Rewards.FindThreadByTree(text); if (val2 == null) { val2 = Toolbox.Instance.NewVmailThread(val, (Human)(object)instance, (Human)null, (Human)null, (List)null, text, num, 1, (CustomDataSource)0, -1); } if (val2 == null) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Mole] could not create thread for #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(dto.VictimId); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); } logger.LogWarning(val3); } else { try { val2.time = num; } catch { } MessageQueue.Enqueue("A v-mail from inside — read it.", 6f); } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Mole] SendThread failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } public static void EnsureDdsRegistered() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown try { Toolbox instance = Toolbox.Instance; if ((Object)(object)instance == (Object)null || instance.allDDSTrees == null) { return; } List list = SyndicateState.Data?.MoleMails; if (list == null) { return; } foreach (MoleMailDto item in list) { if (item != null && item.VictimId >= 0 && !instance.allDDSTrees.ContainsKey(TreeId(item.VictimId))) { RegisterOne(instance, item); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Mole] EnsureDdsRegistered failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static void RegisterOne(Toolbox tb, MoleMailDto dto) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown string text = BlockId(dto.VictimId); string text2 = MsgId(dto.VictimId); string text3 = TreeId(dto.VictimId); string text4 = InstId(dto.VictimId); DDSBlockSave val = new DDSBlockSave { id = text, name = text }; DDSMessageSave val2 = new DDSMessageSave { id = text2, name = text2 }; val2.AddBlock(text); try { val2.blocks[0].alwaysDisplay = true; } catch { } DDSTreeSave val3 = new DDSTreeSave { id = text3, name = text3 }; val3.treeType = (TreeType)1; val3.triggerPoint = (TriggerPoint)5; val3.participantA = new DDSParticipant(); val3.participantB = new DDSParticipant(); val3.participantC = new DDSParticipant(); val3.participantD = new DDSParticipant(); val3.AddMessage(text2); DDSMessageSettings val4 = val3.messages[0]; val4.instanceID = text4; try { val4.saidBy = 0; val4.saidTo = 1; } catch { } val3.startingMessage = text4; val3.messageRef = new Dictionary(); val3.messageRef.Add(text4, val4); tb.allDDSBlocks[text] = val; tb.allDDSMessages[text2] = val2; tb.allDDSTrees[text3] = val3; Lib.DdsStrings.AddOrUpdate("dds.blocks", text, dto.Body); } private static string Codename(int seed) { try { return Codenames[Math.Abs(seed) % Codenames.Length]; } catch { return "a friend on the inside"; } } private static string SafeVictim(CrimeScene s) { try { return string.IsNullOrEmpty(s.VictimName) ? "your last job" : (s.VictimName + "'s death"); } catch { return "your last job"; } } } internal static class RoomForensics { public static bool PrintsMatterHere(NewRoom room) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00bb: Expected I4, but got Unknown try { if ((Object)(object)room == (Object)null) { return true; } NewGameLocation gameLocation = room.gameLocation; if ((Object)(object)gameLocation == (Object)null) { return true; } if ((Object)(object)gameLocation.thisAsStreet != (Object)null) { return false; } if (gameLocation.isOutside) { return false; } if (gameLocation.isLobby) { return false; } NewAddress thisAsAddress = gameLocation.thisAsAddress; if ((Object)(object)thisAsAddress != (Object)null && (Object)(object)thisAsAddress.residence != (Object)null) { return true; } RoomConfiguration preset = room.preset; if ((SoCustomComparison)(object)preset == (SoCustomComparison)null) { return true; } if (preset.securityLevel > 0) { return true; } Forbidden forbidden = preset.forbidden; switch ((int)forbidden) { case 1: return true; case 0: case 2: return false; default: return true; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RoomForensics] PrintsMatterHere failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); return true; } } public static bool IsPublicPrintSpace(NewRoom room) { return !PrintsMatterHere(room); } } internal static class WeaponConsequences { private static List Reg => SyndicateState.Data.MurderWeapons; private static int SurchargeAmount(int pct) { return (int)Math.Round((double)((SyndicateConfig.MurderFineAmount?.Value ?? 2000) * Math.Max(0, pct)) / 100.0); } public static void Register(CrimeScene s) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown try { if (s == null || s.Weapon == null || s.WeaponId < 0) { return; } string text = "weapon"; try { InteractablePreset preset = s.Weapon.preset; if ((SoCustomComparison)(object)preset != (SoCustomComparison)null && !string.IsNullOrEmpty(((Object)preset).name)) { text = ((Object)preset).name; } } catch { } Reg.Add(new TrackedWeaponDto { WeaponId = s.WeaponId, VictimId = s.VictimId, VictimName = s.VictimName, WeaponName = text, HadPlayerPrintAtKill = s.WeaponHadPlayerPrintAtKill }); Plugin.LogVerbose($"[Weapons] tracked murder weapon '{text}' (id {s.WeaponId}) for {Redact.Name(s.VictimName, s.VictimId)}."); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Weapons] Register failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void OnCaseCold(int victimId) { try { Reg.RemoveAll((TrackedWeaponDto e) => e != null && e.VictimId == victimId); } catch { } } public static void RunHomeRaidSweep() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown SyndicateData data = SyndicateState.Data; if (data.RaidWeaponSweepDone) { return; } data.RaidWeaponSweepDone = true; try { ConfigEntry raidWeaponSeizureEnabled = SyndicateConfig.RaidWeaponSeizureEnabled; if (raidWeaponSeizureEnabled != null && !raidWeaponSeizureEnabled.Value) { return; } NewAddress val = (((Object)(object)Player.Instance != (Object)null) ? ((Human)Player.Instance).home : null); if (!((Object)(object)val == (Object)null)) { IntPtr homePtr = ((Il2CppObjectBase)val).Pointer; SeizeAll(Match(delegate(Interactable live) { NewNode node = live.node; return node != null && (Object)(object)node.gameLocation != (Object)null && ((Il2CppObjectBase)node.gameLocation).Pointer == homePtr; }), SurchargeAmount(SyndicateConfig.RaidWeaponSurchargePercent?.Value ?? 50), "murder weapon seized in home raid", raid: true); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Weapons] RunHomeRaidSweep failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } } public static void RunCarryCheckAtBust() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown try { ConfigEntry carryWeaponSeizureEnabled = SyndicateConfig.CarryWeaponSeizureEnabled; if (carryWeaponSeizureEnabled == null || carryWeaponSeizureEnabled.Value) { SeizeAll(Match(delegate(Interactable live) { Human inInventory = live.inInventory; return (Object)(object)inInventory != (Object)null && ((Actor)inInventory).isPlayer; }), SurchargeAmount(SyndicateConfig.CarryWeaponSurchargePercent?.Value ?? 50), "caught carrying the murder weapon", raid: false); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Weapons] RunCarryCheckAtBust failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } private static List<(TrackedWeaponDto e, Interactable live)> Match(Func test) { List<(TrackedWeaponDto, Interactable)> list = new List<(TrackedWeaponDto, Interactable)>(); List list2 = new List(); for (int i = 0; i < Reg.Count; i++) { TrackedWeaponDto trackedWeaponDto = Reg[i]; if (trackedWeaponDto == null) { continue; } Interactable val = null; try { val = StableIds.ResolveInteractable(trackedWeaponDto.WeaponId); } catch { } if (val == null) { list2.Add(trackedWeaponDto); continue; } bool flag = false; try { flag = test(val); } catch { } if (flag) { list.Add((trackedWeaponDto, val)); } } foreach (TrackedWeaponDto item in list2) { Reg.Remove(item); } return list; } private static void SeizeAll(List<(TrackedWeaponDto e, Interactable live)> hits, int perVictimAmount, string reason, bool raid) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown if (hits == null || hits.Count == 0) { return; } bool flag = default(bool); try { HashSet hashSet = new HashSet(); HashSet hashSet2 = new HashSet(); foreach (var (trackedWeaponDto, val) in hits) { if (!hashSet2.Add(trackedWeaponDto.WeaponId)) { continue; } BepInExWarningLogInterpolatedStringHandler val2; try { val.SafeDelete(true); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; val2 = new BepInExWarningLogInterpolatedStringHandler(33, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Weapons] SafeDelete(id "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(trackedWeaponDto.WeaponId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } bool flag2 = false; try { flag2 = StableIds.ResolveInteractable(trackedWeaponDto.WeaponId) == null; } catch { flag2 = false; } if (flag2) { hashSet.Add(trackedWeaponDto.WeaponId); continue; } ManualLogSource logger2 = Plugin.Logger; val2 = new BepInExWarningLogInterpolatedStringHandler(114, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Weapons] weapon id "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(trackedWeaponDto.WeaponId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ('"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(trackedWeaponDto.WeaponName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("') could not be seized (pinned as evidence / being looked at?) — left tracked, not charged."); } logger2.LogWarning(val2); } if (hashSet.Count == 0) { return; } int num = 0; List list = new List(); foreach (var hit in hits) { TrackedWeaponDto item = hit.e; if (hashSet.Contains(item.WeaponId)) { FineLedger.Surcharge(item.VictimName, item.VictimId, perVictimAmount, reason); num += perVictimAmount; Reg.Remove(item); list.Add(item); } } ManhuntController.DeferNotify(Copy(list, hashSet.Count, num, raid), raid ? 5f : 6f); ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(66, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Weapons] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(raid ? "Raid" : "Bust"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" seized "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(hashSet.Count); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" weapon(s) across "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" record(s); +"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("cr in surcharges."); } logger3.LogInfo(val3); } catch (Exception ex2) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Weapons] SeizeAll failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.Message); } logger4.LogWarning(val2); } } private static string Copy(List charged, int weaponCount, int total, bool raid) { if (weaponCount <= 1 && charged.Count > 0) { TrackedWeaponDto trackedWeaponDto = charged[0]; if (raid) { return $"Enforcers turned your place over and found the {trackedWeaponDto.WeaponName} that did {trackedWeaponDto.VictimName}. It's in an evidence locker now — the court added {total}cr to your fines."; } return $"They took the {trackedWeaponDto.WeaponName} off you at intake — the one that did {trackedWeaponDto.VictimName}. That's evidence now, and it cost you another {total}cr."; } if (raid) { return $"Enforcers turned your place over and bagged the tools from {weaponCount} of your jobs. The court piled {total}cr onto your fines."; } return $"They emptied your pockets at intake — {weaponCount} murder weapons, straight to evidence. Another {total}cr on your bill."; } public static string DebugPrintHeldItem() { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown bool flag = default(bool); try { BioScreenController instance = BioScreenController.Instance; InventorySlot val = (((Object)(object)instance != (Object)null) ? instance.selectedSlot : null); Interactable val2 = ((val != null) ? val.GetInteractable() : null); if (val2 == null) { Plugin.Logger.LogInfo((object)"[Debug] Held item: nothing in the selected slot — equip/select an item first."); try { Lib.GameMessage.Broadcast("Nothing held.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } return null; } string text = "?"; try { text = (((SoCustomComparison)(object)val2.preset != (SoCustomComparison)null) ? ((Object)val2.preset).name : "(no preset)"); } catch { } string text2 = "?"; try { text2 = val2.name; } catch { } int num = 0; try { num = val2.id; } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(53, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Debug] Held item -> preset='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', interactable='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', id="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); } logger.LogInfo(val3); try { Lib.GameMessage.Broadcast("Held item: " + text, (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } return text; } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Debug] DebugPrintHeldItem failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); return null; } } public static string DebugTrackHeldItem() { //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown bool flag = default(bool); try { BioScreenController instance = BioScreenController.Instance; InventorySlot val = (((Object)(object)instance != (Object)null) ? instance.selectedSlot : null); Interactable val2 = ((val != null) ? val.GetInteractable() : null); if (val2 == null) { Plugin.Logger.LogInfo((object)"[Weapons] DebugTrackHeldItem: nothing in the selected slot — equip an item first."); return null; } string text = "weapon"; try { InteractablePreset preset = val2.preset; if ((SoCustomComparison)(object)preset != (SoCustomComparison)null && !string.IsNullOrEmpty(((Object)preset).name)) { text = ((Object)preset).name; } } catch { } int num = -1000 - Reg.Count; Reg.Add(new TrackedWeaponDto { WeaponId = val2.id, VictimId = num, VictimName = $"Test Victim {Reg.Count + 1}", WeaponName = text, HadPlayerPrintAtKill = true }); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(67, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Weapons] DebugTrackHeldItem: tracking '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' (id "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.id); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") under fake victim "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); } logger.LogInfo(val3); return text; } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Weapons] DebugTrackHeldItem failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger2.LogWarning(val4); return null; } } public static void DebugDump() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown if (Reg.Count == 0) { Plugin.Logger.LogInfo((object)"[Weapons] No tracked murder weapons."); return; } ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Weapons] === "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Reg.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" tracked murder weapon(s) ==="); } logger.LogInfo(val); foreach (TrackedWeaponDto item in Reg) { if (item == null) { continue; } Interactable val2 = null; try { val2 = StableIds.ResolveInteractable(item.WeaponId); } catch { } bool flag2 = false; string text = "gone"; if (val2 != null) { try { Human inInventory = val2.inInventory; flag2 = (Object)(object)inInventory != (Object)null && ((Actor)inInventory).isPlayer; } catch { } try { NewNode node = val2.node; text = (flag2 ? "carried" : ((node != null && (Object)(object)node.gameLocation != (Object)null) ? ((Object)node.gameLocation).name : "placed (no node)")); } catch { } } ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(31, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Weapons] '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.WeaponName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (id "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.WeaponId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.VictimName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.VictimId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") — "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((val2 == null) ? "UNRESOLVABLE" : text); } logger2.LogInfo(val); } } } } namespace TheSyndicate.Firearms { internal static class FirearmsAmmo { private const int DefaultMagCap = 8; private const int DefaultBoxSize = 12; internal const string Buckshot = "buckshot"; internal const string Slug = "slug"; private static readonly Dictionary AmmoCaliber = new Dictionary(StringComparer.OrdinalIgnoreCase) { ["21AmmoSmall"] = "pistol", ["21AmmoLarge"] = "pistol", ["309Ammo"] = "rifle", ["BuckshotAmmo"] = "buckshot", ["HuntingAmmo"] = "slug" }; private static Dictionary _caps; private static Dictionary _boxSizes; private static string _capsRaw; private static string _boxRaw; private static bool _reloading; private static float _reloadDoneAt; private static int _reloadingGunId = -1; private static string _reloadingCaliber; internal static bool IsReloading => _reloading; internal static void ResetSession() { _reloading = false; _reloadingGunId = -1; _reloadingCaliber = null; } private static void EnsureParsed() { string text = SyndicateConfig.FirearmsMagazineSizes?.Value ?? "SemiAutomaticPistol:12,SemiAutomaticPistolSilenced:12,Revolver:6,Shotgun:6,BattleRifle:30,SniperRifle:5"; string text2 = SyndicateConfig.FirearmsAmmoBoxSizes?.Value ?? "21AmmoSmall:12,21AmmoLarge:50,309Ammo:20,BuckshotAmmo:6,HuntingAmmo:6"; if (_caps == null || text != _capsRaw) { _caps = ParseIntMap(text); _capsRaw = text; } if (_boxSizes == null || text2 != _boxRaw) { _boxSizes = ParseIntMap(text2); _boxRaw = text2; } } private static Dictionary ParseIntMap(string raw) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); try { if (string.IsNullOrWhiteSpace(raw)) { return dictionary; } string[] array = raw.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0) { continue; } int num = text.LastIndexOf(':'); if (num > 0 && num < text.Length - 1) { string text2 = text.Substring(0, num).Trim(); if (int.TryParse(text.Substring(num + 1).Trim(), out var result) && text2.Length > 0) { dictionary[text2] = Math.Max(0, result); } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Firearms] ammo-size parse failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } return dictionary; } internal static int CapacityFor(Interactable gun) { try { EnsureParsed(); if ((SoCustomComparison)(object)((gun != null) ? gun.preset : null) != (SoCustomComparison)null && _caps.TryGetValue(((Object)gun.preset).name, out var value)) { return Math.Max(1, value); } } catch { } return 8; } private static string CaliberOf(string ammoPresetName) { if (ammoPresetName == null || !AmmoCaliber.TryGetValue(ammoPresetName, out var value)) { return "misc"; } return value; } private static List CalibersFor(Interactable gun) { List list = new List(); try { string[] array = FirearmsController.AmmoNamesFor(gun); if (array == null) { return list; } string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string item = CaliberOf(array2[i]); if (!list.Contains(item)) { list.Add(item); } } } catch { } return list; } internal static bool IsMultiCaliber(Interactable gun) { return CalibersFor(gun).Count > 1; } internal static int GetMag(int gunId, int cap) { if (!SyndicateState.Data.GunMagazines.TryGetValue(gunId, out var value)) { return cap; } return Math.Min(value, cap); } internal static void SetMag(int gunId, int n) { SyndicateState.Data.GunMagazines[gunId] = Math.Max(0, n); } internal static string LoadedCaliber(Interactable gun) { try { if (gun != null && SyndicateState.Data.GunLoadedAmmo != null && SyndicateState.Data.GunLoadedAmmo.TryGetValue(gun.id, out var value) && !string.IsNullOrEmpty(value)) { return value; } List list = CalibersFor(gun); if (list.Count == 1) { return list[0]; } return "buckshot"; } catch { return "buckshot"; } } private static void SetLoadedCaliber(int gunId, string cal) { try { if (!string.IsNullOrEmpty(cal)) { SyndicateState.Data.GunLoadedAmmo[gunId] = cal; } } catch { } } internal static bool LoadedIsSlug(Interactable gun) { return LoadedCaliber(gun) == "slug"; } internal static string LoadedLabel(Interactable gun) { return LoadedLabel(gun, IsMultiCaliber(gun)); } internal static string LoadedLabel(Interactable gun, bool multiCaliber) { if (!multiCaliber) { return ""; } if (!LoadedIsSlug(gun)) { return "BUCKSHOT"; } return "SLUG"; } internal static void ToggleShotgunAmmo(Interactable gun) { if (gun != null && !_reloading && IsMultiCaliber(gun)) { string cal = ((LoadedCaliber(gun) == "slug") ? "buckshot" : "slug"); int cap = CapacityFor(gun); if (GetMag(gun.id, cap) > 0) { SetMag(gun.id, 0); } SetLoadedCaliber(gun.id, cal); } } internal static bool IsAmmoBox(Interactable inter) { try { return (SoCustomComparison)(object)((inter != null) ? inter.preset : null) != (SoCustomComparison)null && AmmoCaliber.ContainsKey(((Object)inter.preset).name); } catch { return false; } } internal static int BoxCapacity(Interactable box) { try { object boxName; if (box == null) { boxName = null; } else { InteractablePreset preset = box.preset; boxName = ((preset != null) ? ((Object)preset).name : null); } return BoxSize((string)boxName); } catch { return 12; } } internal static int BoxRoundsOf(Interactable box) { try { if (box == null) { return 0; } if (SyndicateState.Data.BoxRounds.TryGetValue(box.id, out var value)) { return Math.Max(0, value); } InteractablePreset preset = box.preset; return BoxSize((preset != null) ? ((Object)preset).name : null); } catch { return 0; } } private static void BoxRoundsSet(int boxId, int n) { SyndicateState.Data.BoxRounds[boxId] = Math.Max(0, n); } private static int BoxSize(string boxName) { EnsureParsed(); if (boxName == null || !_boxSizes.TryGetValue(boxName, out var value)) { return 12; } return Math.Max(1, value); } internal static int ReserveFor(Interactable gun) { return CountBoxRounds(gun, null); } private static int ReserveForCaliber(Interactable gun, string cal) { return CountBoxRounds(gun, cal); } private static int CountBoxRounds(Interactable gun, string cal) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown int num = 0; try { FirstPersonItemController instance = FirstPersonItemController.Instance; string[] array = FirearmsController.AmmoNamesFor(gun); if (((instance != null) ? instance.slots : null) == null || array == null) { return 0; } Enumerator enumerator = instance.slots.GetEnumerator(); while (enumerator.MoveNext()) { InventorySlot current = enumerator.Current; if (current == null) { continue; } Interactable interactable = current.GetInteractable(); if ((SoCustomComparison)(object)((interactable != null) ? interactable.preset : null) == (SoCustomComparison)null || (gun != null && ((Il2CppObjectBase)interactable).Pointer == ((Il2CppObjectBase)gun).Pointer)) { continue; } string name = ((Object)interactable.preset).name; for (int i = 0; i < array.Length; i++) { if (array[i] == name) { if (cal == null || CaliberOf(name) == cal) { num += BoxRoundsOf(interactable); } break; } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Firearms] reserve count failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } return num; } internal static void TryStartReload(Interactable held) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown try { if (_reloading || held == null) { return; } ConfigEntry firearmsConsumeAmmo = SyndicateConfig.FirearmsConsumeAmmo; if (firearmsConsumeAmmo != null && !firearmsConsumeAmmo.Value) { Toast("Ammo consumption is disabled."); return; } int num = CapacityFor(held); int mag = GetMag(held.id, num); string text = PlanReloadCaliber(held); if (text == null) { if (mag >= num) { Toast("Magazine full."); } else if (ReserveFor(held) <= 0) { Toast("No ammunition to reload."); } else { Toast("No matching ammunition — switch shell type to load the other kind."); } } else if (mag >= num) { Toast("Magazine full."); } else { _reloading = true; _reloadingGunId = held.id; _reloadingCaliber = text; _reloadDoneAt = Time.time + Mathf.Max(0.2f, SyndicateConfig.FirearmsReloadSeconds?.Value ?? 2.5f); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Firearms] reload start failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } internal static void Tick() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if (!_reloading) { return; } try { if (!FirearmsController.IsHoldingFirearm(out var held, out var _) || held == null || held.id != _reloadingGunId) { _reloading = false; } else if (!(Time.time < _reloadDoneAt)) { _reloading = false; CompleteReload(held); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Firearms] reload tick failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); _reloading = false; } } private static string PlanReloadCaliber(Interactable held) { List list = CalibersFor(held); if (list.Count == 0) { return null; } if (list.Count == 1) { if (ReserveForCaliber(held, list[0]) <= 0) { return null; } return list[0]; } string text = LoadedCaliber(held); if (list.Contains(text) && ReserveForCaliber(held, text) > 0) { return text; } return null; } private static void CompleteReload(Interactable held) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown try { string reloadingCaliber = _reloadingCaliber; if (string.IsNullOrEmpty(reloadingCaliber)) { return; } int num = CapacityFor(held); int num2 = GetMag(held.id, num); int num3 = num - num2; string text = LoadedCaliber(held); if (num2 > 0 && text != reloadingCaliber) { num2 = 0; num3 = num; } if (num3 <= 0) { SetMag(held.id, num2); SetLoadedCaliber(held.id, reloadingCaliber); return; } int num4 = 0; while (num3 > 0 && num4++ < 128) { InventorySlot val = FindAmmoSlotForCaliber(held, reloadingCaliber); if (val == null) { break; } Interactable interactable = val.GetInteractable(); if (interactable == null) { break; } int num5 = BoxRoundsOf(interactable); if (num5 <= 0) { FirstPersonItemController.Instance.EmptySlot(val, false, true, true, false); SyndicateState.Data.BoxRounds.Remove(interactable.id); continue; } int num6 = Math.Min(num3, num5); num2 += num6; num3 -= num6; int num7 = num5 - num6; if (num7 <= 0) { FirstPersonItemController.Instance.EmptySlot(val, false, true, true, false); SyndicateState.Data.BoxRounds.Remove(interactable.id); } else { BoxRoundsSet(interactable.id, num7); } } SetMag(held.id, num2); SetLoadedCaliber(held.id, reloadingCaliber); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Firearms] reload complete failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } } private static InventorySlot FindAmmoSlotForCaliber(Interactable gun, string cal) { try { string[] array = FirearmsController.AmmoNamesFor(gun); if (array == null) { return null; } List list = new List(); string[] array2 = array; foreach (string text in array2) { if (CaliberOf(text) == cal) { list.Add(text); } } if (list.Count == 0) { return null; } return FirearmsController.FindAmmoSlot(gun, list.ToArray()); } catch { return null; } } private static void Toast(string msg) { try { Lib.GameMessage.Broadcast(msg, (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } } internal static class FirearmsAssetTuner { private static readonly string[] GunNames = new string[6] { "SemiAutomaticPistol", "SemiAutomaticPistolSilenced", "Revolver", "Shotgun", "BattleRifle", "SniperRifle" }; private static bool _hooked; public static void Init() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown if (_hooked) { return; } _hooked = true; try { Lib.SaveGame.OnAfterNewGame += delegate { Apply(); }; Lib.SaveGame.OnAfterLoad += delegate { Apply(); }; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FirearmsTuner] hook failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void Apply() { //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Invalid comparison between Unknown and I4 try { FirearmsAmmo.ResetSession(); Toolbox instance = Toolbox.Instance; if ((Object)(object)instance == (Object)null) { return; } bool flag = SyndicateConfig.FirearmsGunshotsAlarm?.Value ?? true; float num = Mathf.Max(0f, SyndicateConfig.FirearmsGunshotSpook?.Value ?? 0.2f); HashSet hashSet = ParseCsvSet(SyndicateConfig.FirearmsAlarmExemptGuns?.Value ?? "SemiAutomaticPistolSilenced"); int num2 = 0; string[] gunNames = GunNames; foreach (string text in gunNames) { InteractablePreset val = null; try { val = instance.GetInteractablePreset(text); } catch { } if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { Plugin.LogVerbose("[FirearmsTuner] " + text + ": preset not found."); continue; } MurderWeaponPreset weapon = val.weapon; AudioEvent val2 = (((SoCustomComparison)(object)weapon != (SoCustomComparison)null) ? weapon.fireEvent : null); if ((SoCustomComparison)(object)val2 != (SoCustomComparison)null) { Plugin.LogVerbose($"[FirearmsTuner] {text}: shots={SafeShots(weapon)} fireEvent='{((Object)val2).name}' canBeSuspicious={val2.canBeSuspicious} alwaysSuspicious={val2.alwaysSuspicious} onlyEmptyAddr={val2.onlySuspiciousIfEmptyAddress} urgent={val2.urgentResponse} memTag={val2.citizenMemoryTag} spook={val2.spookValue}"); if (flag && !hashSet.Contains(text)) { bool flag2 = false; if (!val2.canBeSuspicious) { val2.canBeSuspicious = true; flag2 = true; } if (!val2.alwaysSuspicious) { val2.alwaysSuspicious = true; flag2 = true; } if (val2.onlySuspiciousIfEmptyAddress) { val2.onlySuspiciousIfEmptyAddress = false; flag2 = true; } if (!val2.urgentResponse) { val2.urgentResponse = true; flag2 = true; } if ((int)val2.citizenMemoryTag != 1) { val2.citizenMemoryTag = (MemoryTag)1; flag2 = true; } if (val2.spookValue < num) { val2.spookValue = num; flag2 = true; } if (flag2) { num2++; Plugin.LogVerbose("[FirearmsTuner] -> " + text + " fireEvent flagged suspicious (gunshot)."); } } } else { Plugin.LogVerbose("[FirearmsTuner] " + text + ": no weapon.fireEvent."); } FirstPersonItem fpsItem = val.fpsItem; if ((SoCustomComparison)(object)fpsItem != (SoCustomComparison)null) { Plugin.LogVerbose($"[FirearmsTuner] {text}: fpsItem='{((Object)fpsItem).name}' ptr={((Il2CppObjectBase)fpsItem).Pointer.ToString("X")} drawnNerve={fpsItem.drawnNerveModifier} barkChance={fpsItem.barkTriggerChance}"); } } Plugin.Logger.LogInfo((object)($"[FirearmsTuner] applied — gunshot-alarm flagged on {num2} fireEvent(s) (alarm={flag}). " + "Drawn-gun dread is a proximity tick (FirearmsHotkey), not an asset flip. NOTE: a gun's fireEvent may be shared with other weapons using the same fire sound (see verbose log).")); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag3 = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[FirearmsTuner] apply failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger.LogWarning(val3); } } public static void Probe() { //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Expected O, but got Unknown bool flag = default(bool); try { Toolbox instance = Toolbox.Instance; if ((Object)(object)instance == (Object)null) { Plugin.Logger.LogWarning((object)"[FirearmsProbe] Toolbox not ready."); return; } float num = -1f; try { num = (((Object)(object)CitizenControls.Instance != (Object)null) ? CitizenControls.Instance.nerveWeaponDrawMultiplier : (-1f)); } catch { } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(70, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FirearmsProbe] === firearms asset dump === nerveWeaponDrawMultiplier="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); } logger.LogInfo(val); string[] gunNames = GunNames; foreach (string text in gunNames) { InteractablePreset val2 = null; try { val2 = instance.GetInteractablePreset(text); } catch { } if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null) { ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FirearmsProbe] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": preset NOT FOUND."); } logger2.LogInfo(val); continue; } MurderWeaponPreset weapon = val2.weapon; string text2 = "no weapon"; if ((SoCustomComparison)(object)weapon != (SoCustomComparison)null) { float value = -1f; try { value = weapon.GetAttackValue((AttackValue)1, (Human)(object)Player.Instance); } catch { } string value2 = "fireEvent=null"; AudioEvent fireEvent = weapon.fireEvent; if ((SoCustomComparison)(object)fireEvent != (SoCustomComparison)null) { value2 = $"fireEvent='{((Object)fireEvent).name}'[canSusp={fireEvent.canBeSuspicious},always={fireEvent.alwaysSuspicious},onlyEmpty={fireEvent.onlySuspiciousIfEmptyAddress},urgent={fireEvent.urgentResponse},mem={fireEvent.citizenMemoryTag},spook={fireEvent.spookValue}]"; } text2 = $"type={weapon.type} shots={SafeShots(weapon)} fireDelay={value} eject={weapon.ejectBrassSetting} {value2}"; } FirstPersonItem fpsItem = val2.fpsItem; string text3 = (((SoCustomComparison)(object)fpsItem != (SoCustomComparison)null) ? $"fpsItem='{((Object)fpsItem).name}' ptr={((Il2CppObjectBase)fpsItem).Pointer.ToString("X")} drawnNerve={fpsItem.drawnNerveModifier} barkChance={fpsItem.barkTriggerChance}" : "fpsItem=null"); ManualLogSource logger3 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(21, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FirearmsProbe] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" | "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text3); } logger3.LogInfo(val); } Plugin.Logger.LogInfo((object)"[FirearmsProbe] === end (identical fpsItem ptr across guns => they share a held pose; a flip affects all sharers) ==="); } catch (Exception ex) { ManualLogSource logger4 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[FirearmsProbe] failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } logger4.LogError(val3); } } private static int SafeShots(MurderWeaponPreset weapon) { try { return weapon.shots; } catch { return -1; } } private static HashSet ParseCsvSet(string raw) { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); try { if (string.IsNullOrWhiteSpace(raw)) { return hashSet; } string[] array = raw.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { hashSet.Add(text); } } } catch { } return hashSet; } } internal static class FirearmsController { internal enum Outcome { Fired, NoAmmo, NotFirearm, Disabled, OnCooldown, Reloading, WorldInteractable } private sealed class VictimGroup { public Citizen Victim; public int Count; public bool Head; public Vector3 FirstHit; public Vector3 FirstDir; public bool Lethal; } private static bool _firing; private static bool _blastActive; private static readonly HashSet _blastProtect = new HashSet(); private static float _nextAllowedFireTime; private static float _lastEmptyMsgTime = -999f; private static readonly Dictionary AmmoMap = new Dictionary { ["SemiAutomaticPistol"] = new string[2] { "21AmmoSmall", "21AmmoLarge" }, ["SemiAutomaticPistolSilenced"] = new string[2] { "21AmmoSmall", "21AmmoLarge" }, ["Revolver"] = new string[2] { "21AmmoSmall", "21AmmoLarge" }, ["Shotgun"] = new string[2] { "BuckshotAmmo", "HuntingAmmo" }, ["BattleRifle"] = new string[1] { "309Ammo" }, ["SniperRifle"] = new string[1] { "309Ammo" } }; private static bool Enabled => SyndicateConfig.FirearmsEnabled?.Value ?? true; private static bool HeadshotLethal => SyndicateConfig.FirearmsHeadshotLethal?.Value ?? true; private static bool ConsumeAmmo => SyndicateConfig.FirearmsConsumeAmmo?.Value ?? true; private static bool SpawnCasings => SyndicateConfig.FirearmsSpawnCasings?.Value ?? true; private static float FireAccuracy => Mathf.Clamp01(SyndicateConfig.FirearmsAccuracy?.Value ?? 1f); private static float MinCooldown => Mathf.Max(0.05f, SyndicateConfig.FirearmsMinCooldownSeconds?.Value ?? 0.4f); internal static bool IsBlastProtected(Citizen c) { try { return _blastActive && (Object)(object)c != (Object)null && _blastProtect.Contains(((Il2CppObjectBase)c).Pointer); } catch { return false; } } internal static bool IsHoldingFirearm(out Interactable held, out MurderWeaponPreset weapon) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) //IL_0046: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 held = null; weapon = null; try { Interactable equippedInteractableCached = KillSwitchPatch.GetEquippedInteractableCached(); if (equippedInteractableCached == null || (SoCustomComparison)(object)equippedInteractableCached.preset == (SoCustomComparison)null) { return false; } MurderWeaponPreset weapon2 = equippedInteractableCached.preset.weapon; if ((SoCustomComparison)(object)weapon2 == (SoCustomComparison)null) { return false; } WeaponType type = weapon2.type; if ((int)type != 0 && (int)type != 1 && (int)type != 2) { return false; } held = equippedInteractableCached; weapon = weapon2; return true; } catch { return false; } } internal static Outcome Fire() { //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Expected O, but got Unknown //IL_067f: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Expected O, but got Unknown //IL_076f: Unknown result type (might be due to invalid IL or missing references) //IL_0776: Expected O, but got Unknown //IL_087e: Unknown result type (might be due to invalid IL or missing references) //IL_0885: Expected O, but got Unknown //IL_08c7: Unknown result type (might be due to invalid IL or missing references) //IL_08ce: Expected O, but got Unknown //IL_0950: Unknown result type (might be due to invalid IL or missing references) //IL_0957: Expected O, but got Unknown //IL_0a89: Unknown result type (might be due to invalid IL or missing references) //IL_0a90: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0643: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_0753: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_085a: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Invalid comparison between Unknown and I4 if (!Enabled) { return Outcome.Disabled; } if (_firing) { return Outcome.OnCooldown; } if (!IsHoldingFirearm(out var held, out var weapon)) { return Outcome.NotFirearm; } CameraController instance = CameraController.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.cam == (Object)null) { return Outcome.NotFirearm; } if (ShouldYieldToWorldInteraction()) { return Outcome.WorldInteractable; } if (FirearmsAmmo.IsReloading) { return Outcome.Reloading; } int id = held.id; int cap = FirearmsAmmo.CapacityFor(held); int num = (ConsumeAmmo ? FirearmsAmmo.GetMag(id, cap) : int.MaxValue); if (ConsumeAmmo && num <= 0) { EmptyClick(FirearmsAmmo.ReserveFor(held) > 0); return Outcome.NoAmmo; } if (Time.time < _nextAllowedFireTime) { return Outcome.OnCooldown; } _firing = true; bool flag3 = default(bool); try { Transform transform = ((Component)instance.cam).transform; Vector3 position = transform.position; Vector3 forward = transform.forward; float maximumBulletRange = weapon.maximumBulletRange; bool flag = false; try { flag = (int)weapon.type == 2; } catch { } bool num2 = flag && !FirearmsAmmo.LoadedIsSlug(held); int num3 = 1; float num4 = 0f; if (num2) { int num5 = SyndicateConfig.FirearmsShotgunPellets?.Value ?? 6; int num6 = 1; try { num6 = Mathf.Max(1, weapon.shots); } catch { } num3 = Mathf.Max(1, Mathf.Max(num6, num5)); if (num3 > 1) { num4 = Mathf.Max(0f, SyndicateConfig.FirearmsShotgunSpread?.Value ?? 0.06f); } } float num7 = ((num3 > 1) ? 1f : FireAccuracy); float num8 = 0.1f; try { num8 = weapon.GetAttackValue((AttackValue)3, (Human)(object)Player.Instance); } catch { } Vector3[] array = (Vector3[])(object)new Vector3[num3]; Dictionary dictionary = new Dictionary(); RaycastHit hit = default(RaycastHit); for (int i = 0; i < num3; i++) { Vector3 val = forward; if (i > 0 && num4 > 0f) { Vector3 val2 = forward + new Vector3(Toolbox.Instance.Rand(0f - num4, num4, false), Toolbox.Instance.Rand(0f - num4, num4, false), Toolbox.Instance.Rand(0f - num4, num4, false)); val = ((Vector3)(ref val2)).normalized; } array[i] = val; try { if (!Physics.Raycast(position, val, ref hit, maximumBulletRange, Toolbox.Instance.physicalObjectsLayerMask)) { continue; } Actor val3 = ((Component)((RaycastHit)(ref hit)).transform).gameObject.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)((RaycastHit)(ref hit)).transform).gameObject.GetComponentInParent(); } if (!((Object)(object)val3 != (Object)null) || val3.isPlayer) { continue; } Citizen val4 = ((Il2CppObjectBase)val3).TryCast(); if ((Object)(object)val4 != (Object)null) { bool flag2 = IsHeadHit(hit, val4); IntPtr pointer = ((Il2CppObjectBase)val4).Pointer; if (!dictionary.TryGetValue(pointer, out var value)) { value = (dictionary[pointer] = new VictimGroup { Victim = val4, FirstHit = ((RaycastHit)(ref hit)).point, FirstDir = val }); } value.Count++; value.Head |= flag2; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(35, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Firearms] pellet "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(i); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" raycast failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger.LogWarning(val5); } } int num9 = Mathf.Max(1, SyndicateConfig.FirearmsShotgunLethalPellets?.Value ?? 3); foreach (VictimGroup value2 in dictionary.Values) { if (!((Object)(object)value2.Victim != (Object)null) || !((Object)(object)((Actor)value2.Victim).ai != (Object)null) || ((Actor)value2.Victim).isDead) { value2.Lethal = false; continue; } value2.Lethal = ((num3 > 1) ? ((HeadshotLethal && value2.Head) || value2.Count >= num9) : (IsOneShot(held) || (HeadshotLethal && value2.Head))); ConfigEntry verboseLogging = SyndicateConfig.VerboseLogging; if (verboseLogging == null || !verboseLogging.Value) { continue; } try { ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(75, 7, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[Firearms] hit "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(Redact.Actor((Human)(object)value2.Victim)); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" — pellets="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(value2.Count); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" head="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(value2.Head); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("=> lethal="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(value2.Lethal); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" (oneShot="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(IsOneShot(held)); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(", headLethalCfg="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted(HeadshotLethal); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(", ai="); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted((Object)(object)((Actor)value2.Victim).ai != (Object)null); ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(")"); } logger2.LogInfo(val6); } catch { } } foreach (VictimGroup value3 in dictionary.Values) { if ((Object)(object)value3.Victim != (Object)null && !((Actor)value3.Victim).isDead) { TryRegisterAssault(value3.Victim); } } _blastProtect.Clear(); foreach (VictimGroup value4 in dictionary.Values) { Citizen victim = value4.Victim; if ((Object)(object)victim != (Object)null && !((Actor)victim).isDead && (Object)(object)((Actor)victim).ai != (Object)null && !((Actor)victim).ai.ko) { try { _blastProtect.Add(((Il2CppObjectBase)victim).Pointer); } catch { } } } _blastActive = true; for (int j = 0; j < num3; j++) { try { Toolbox.Instance.Shoot((Actor)(object)Player.Instance, position, position + array[j] * maximumBulletRange, maximumBulletRange, num7, num8, weapon, false, position, false, j == 0); } catch (Exception ex2) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(33, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Firearms] Shoot pellet "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(j); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex2.Message); } logger3.LogWarning(val5); } } _blastActive = false; float num10 = SyndicateConfig.FirearmsRecoil?.Value ?? 15f; if (IsAutoWeapon(held)) { num10 *= Mathf.Max(0f, SyndicateConfig.FirearmsAutoRecoilScale?.Value ?? 0.4f); } if (num10 > 0f) { try { Vector3 val7 = default(Vector3); ((Vector3)(ref val7))..ctor(-1f, Toolbox.Instance.Rand(-0.15f, 0.15f, false), 0f); Player.Instance.fps.JoltCamera(val7, num10, 1.1f); } catch (Exception ex3) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Firearms] recoil failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex3.Message); } logger4.LogWarning(val5); } } bool flag4 = SyndicateConfig.FirearmsRoomTurnOnHit?.Value ?? true; float num11 = SyndicateConfig.FirearmsRoomTurnRange?.Value ?? 10f; VictimGroup victimGroup2 = null; foreach (VictimGroup value5 in dictionary.Values) { if (victimGroup2 == null || value5.Count > victimGroup2.Count) { victimGroup2 = value5; } Citizen victim2 = value5.Victim; if ((Object)(object)victim2 == (Object)null) { continue; } if (value5.Lethal && !((Actor)victim2).isDead) { if ((Object)(object)((Actor)victim2).ai != (Object)null && !((Actor)victim2).ai.ko) { try { ((Actor)victim2).ai.SetKO(true, value5.FirstHit, value5.FirstDir, false, 0f, true, 1f); } catch (Exception ex4) { ManualLogSource logger5 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Firearms] SetKO prep failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex4.Message); } logger5.LogWarning(val5); } } try { KillSwitchPatch.ApplyLethal(victim2, (Human)(object)Player.Instance); } catch (Exception ex5) { ManualLogSource logger6 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Firearms] lethal kill failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex5.Message); } logger6.LogWarning(val5); } } if (!flag4 || !((Object)(object)((Actor)victim2).ai != (Object)null) || ((Actor)victim2).isDead) { continue; } try { bool flag5 = false; try { flag5 = (Object)(object)((Actor)victim2).currentRoom != (Object)null; } catch { } ((Actor)victim2).ai.SetPersue((Actor)(object)Player.Instance, flag5, 2, true, num11); } catch (Exception ex6) { ManualLogSource logger7 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Firearms] room-turn failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex6.Message); } logger7.LogWarning(val5); } } if (SpawnCasings) { Citizen val8 = victimGroup2?.Victim; bool atScene = (Object)(object)val8 != (Object)null && (Object)(object)((Actor)val8).currentGameLocation != (Object)null && (Object)(object)((Actor)Player.Instance).currentGameLocation != (Object)null && ((Il2CppObjectBase)((Actor)val8).currentGameLocation).Pointer == ((Il2CppObjectBase)((Actor)Player.Instance).currentGameLocation).Pointer; TrySpawnCasing(weapon, transform, atScene); } if (ConsumeAmmo) { FirearmsAmmo.SetMag(id, num - 1); } float num12; if (IsAutoWeapon(held)) { num12 = Mathf.Max(0.05f, SyndicateConfig.FirearmsAutoFireInterval?.Value ?? 0.12f); } else { num12 = MinCooldown; try { num12 = Mathf.Max(weapon.GetAttackValue((AttackValue)1, (Human)(object)Player.Instance), MinCooldown); } catch { } } _nextAllowedFireTime = Time.time + num12; return Outcome.Fired; } catch (Exception ex7) { ManualLogSource logger8 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val9 = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("[Firearms] Fire failed: "); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(ex7); } logger8.LogError(val9); _nextAllowedFireTime = Time.time + MinCooldown; return Outcome.Fired; } finally { _firing = false; _blastActive = false; _blastProtect.Clear(); } } internal static string[] AmmoNamesFor(Interactable gun) { try { string[] value; return (gun != null && (SoCustomComparison)(object)gun.preset != (SoCustomComparison)null && AmmoMap.TryGetValue(((Object)gun.preset).name, out value)) ? value : null; } catch { return null; } } internal static InventorySlot FindAmmoSlot(Interactable gun, string[] ammoNames) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown try { FirstPersonItemController instance = FirstPersonItemController.Instance; if ((Object)(object)instance == (Object)null || instance.slots == null || ammoNames == null) { return null; } Enumerator enumerator = instance.slots.GetEnumerator(); while (enumerator.MoveNext()) { InventorySlot current = enumerator.Current; if (current == null) { continue; } Interactable interactable = current.GetInteractable(); if (interactable == null || (SoCustomComparison)(object)interactable.preset == (SoCustomComparison)null || (gun != null && ((Il2CppObjectBase)interactable).Pointer == ((Il2CppObjectBase)gun).Pointer)) { continue; } string name = ((Object)interactable.preset).name; for (int i = 0; i < ammoNames.Length; i++) { if (ammoNames[i] == name) { return current; } } } return null; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Firearms] ammo search failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); return null; } } private static void TrySpawnCasing(MurderWeaponPreset weapon, Transform cam, bool atScene) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_003e: 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) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_015f: 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) bool flag = default(bool); try { EjectBrass ejectBrassSetting = weapon.ejectBrassSetting; if ((int)ejectBrassSetting != 1 && (int)ejectBrassSetting != 2) { return; } InteractablePreset shellCasing = weapon.shellCasing; if ((SoCustomComparison)(object)shellCasing == (SoCustomComparison)null) { return; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } Vector3 val = cam.position + cam.right * 0.35f - cam.up * 0.5f; Interactable val2 = InteractableCreator.Instance.CreateWorldInteractable(shellCasing, (Human)(object)instance, (Human)(object)instance, (Human)null, val, Vector3.zero, (List)null, (Object)null, ""); if (val2 == null) { return; } try { Vector3 val3 = cam.right * Toolbox.Instance.Rand(2.5f, 3.5f, false) + cam.up * Toolbox.Instance.Rand(0.6f, 1.2f, false) + new Vector3(Toolbox.Instance.Rand(-0.2f, 0.2f, false), 0f, Toolbox.Instance.Rand(-0.2f, 0.2f, false)); if ((Object)(object)val2.controller != (Object)null) { val2.controller.DropThis(false); if ((Object)(object)val2.controller.rb != (Object)null) { val2.controller.rb.AddForce(val3, (ForceMode)2); } } else { val2.ForcePhysicsActive(false, true, val3, (ForceMode)2, false); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Firearms] casing physics failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger.LogWarning(val4); } PlayerInteractionPrintPatch.EnsurePlayerPrint(val2, atScene); if (atScene) { return; } try { val2.MarkAsTrash(true, false, 0f); } catch { } } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Firearms] casing spawn failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex2.Message); } logger2.LogWarning(val4); } } private static void TryRegisterAssault(Citizen victim) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown bool flag = default(bool); try { NewGameLocation currentGameLocation = ((Actor)victim).currentGameLocation; NewAddress val = (((Object)(object)currentGameLocation != (Object)null) ? currentGameLocation.thisAsAddress : null); StatusController.Instance.AddFineRecord(val, ((Actor)victim).interactable, (CrimeType)0, true, -1, false); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Firearms] assault record failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger.LogWarning(val2); } try { NewGameLocation currentGameLocation2 = ((Actor)Player.Instance).currentGameLocation; if (!((Object)(object)currentGameLocation2 != (Object)null)) { return; } currentGameLocation2.AddEscalation((Actor)(object)Player.Instance); try { if (currentGameLocation2.escalation != null && currentGameLocation2.escalation.ContainsKey((Actor)(object)Player.Instance)) { currentGameLocation2.escalation[(Actor)(object)Player.Instance].timeEscalation = 1f; } } catch { } } catch (Exception ex2) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Firearms] escalation failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.Message); } logger2.LogWarning(val2); } } internal static bool ShouldYieldToWorldInteraction(float citizenRange = 12f) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) try { InteractionController instance = InteractionController.Instance; if ((Object)(object)instance == (Object)null) { return false; } if ((Object)(object)instance.carryingObject != (Object)null || instance.interactionMode) { return false; } if ((Object)(object)instance.currentLookingAtInteractable == (Object)null) { return false; } float num = Mathf.Max(0.5f, SyndicateConfig.FirearmsInteractYieldDistance?.Value ?? 2f); RaycastHit playerCurrentRaycastHit = instance.playerCurrentRaycastHit; if (((RaycastHit)(ref playerCurrentRaycastHit)).distance > num) { return false; } Camera val = (((Object)(object)CameraController.Instance != (Object)null) ? CameraController.Instance.cam : null); if ((Object)(object)val == (Object)null) { return true; } Transform transform = ((Component)val).transform; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(transform.position, transform.forward, ref val2, Mathf.Max(0.5f, citizenRange), Toolbox.Instance.physicalObjectsLayerMask)) { Actor val3 = ((Component)((RaycastHit)(ref val2)).transform).gameObject.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)((RaycastHit)(ref val2)).transform).gameObject.GetComponentInParent(); } if ((Object)(object)val3 != (Object)null && !val3.isPlayer) { return false; } } return true; } catch { return false; } } private static bool IsHeadHit(RaycastHit hit, Citizen victim) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)((Human)victim).outfitController == (Object)null || (Object)(object)((RaycastHit)(ref hit)).transform == (Object)null) { return false; } Transform bodyAnchor = ((Human)victim).outfitController.GetBodyAnchor((CharacterAnchor)2); if ((Object)(object)bodyAnchor == (Object)null) { return false; } bool flag = false; Transform val = ((RaycastHit)(ref hit)).transform; int num = 0; while ((Object)(object)val != (Object)null && num < 8) { if (((Il2CppObjectBase)((Component)val).gameObject).Pointer == ((Il2CppObjectBase)((Component)bodyAnchor).gameObject).Pointer) { flag = true; break; } val = val.parent; num++; } float num2 = Mathf.Max(0.05f, SyndicateConfig.FirearmsHeadshotRadius?.Value ?? 0.35f); Vector3 val2 = ((RaycastHit)(ref hit)).point - bodyAnchor.position; bool flag2 = ((Vector3)(ref val2)).sqrMagnitude <= num2 * num2 && val2.y >= 0f; bool flag3 = flag || flag2; ConfigEntry firearmsHeadshotDebug = SyndicateConfig.FirearmsHeadshotDebug; if (firearmsHeadshotDebug != null && firearmsHeadshotDebug.Value) { try { ManualLogSource logger = Plugin.Logger; bool flag4 = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(76, 9, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Firearms] headcheck coll='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)((RaycastHit)(ref hit)).transform).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' anchor='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)bodyAnchor).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("dist="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Vector3)(ref val2)).magnitude, "0.00"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" dx="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.x, "0.00"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" dy="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.y, "0.00"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" dz="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.z, "0.00"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ancestor="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(flag); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" near="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" => "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(flag3); } logger.LogInfo(val3); } catch { } } return flag3; } catch { return false; } } private static bool IsOneShot(Interactable gun) { return MatchesCsv(gun, SyndicateConfig.FirearmsOneShotWeapons?.Value ?? "Shotgun,SniperRifle"); } internal static bool IsAutoWeapon(Interactable gun) { return MatchesCsv(gun, SyndicateConfig.FirearmsAutoFireWeapons?.Value ?? "BattleRifle"); } private static bool MatchesCsv(Interactable gun, string raw) { try { if (gun == null || (SoCustomComparison)(object)gun.preset == (SoCustomComparison)null || string.IsNullOrEmpty(raw)) { return false; } string name = ((Object)gun.preset).name; string[] array = raw.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && string.Equals(text, name, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } catch { return false; } } private static void EmptyClick(bool reserveExists) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) if (Time.time - _lastEmptyMsgTime < 2.5f) { return; } _lastEmptyMsgTime = Time.time; ConfigEntry firearmsReloadKey = SyndicateConfig.FirearmsReloadKey; KeyCode value = (KeyCode)((firearmsReloadKey == null) ? 114 : ((int)firearmsReloadKey.Value)); try { Lib.GameMessage.Broadcast(reserveExists ? $"Click — magazine empty. [{value}] to reload." : "Click — out of ammunition.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } } public class FirearmsHotkey : MonoBehaviour { private const float MeleeCooldown = 0.6f; private static float _nextMeleeTime; private int _lastHeldGunId = int.MinValue; private bool _lastInPlay; private bool _autoArmed; private bool _fireKeyArmed; private const float DreadInterval = 0.5f; private static float _nextDreadTime; public FirearmsHotkey(IntPtr ptr) : base(ptr) { } private void Update() { //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) try { FirearmsAmmo.Tick(); PoisonScheduler.TickBeats(); bool flag = InPlay(); if (flag && !_lastInPlay) { _autoArmed = false; _fireKeyArmed = false; } _lastInPlay = flag; if (!flag) { return; } Interactable held; MurderWeaponPreset weapon; bool flag2 = FirearmsController.IsHoldingFirearm(out held, out weapon); int num = (flag2 ? held.id : int.MinValue); if (num != _lastHeldGunId) { _autoArmed = false; _fireKeyArmed = false; _lastHeldGunId = num; } ConfigEntry firearmsReloadKey = SyndicateConfig.FirearmsReloadKey; KeyCode val = (KeyCode)((firearmsReloadKey == null) ? 114 : ((int)firearmsReloadKey.Value)); if (flag2 && (int)val != 0 && Input.GetKeyDown(val)) { FirearmsAmmo.TryStartReload(held); } ConfigEntry firearmsShotgunAmmoKey = SyndicateConfig.FirearmsShotgunAmmoKey; KeyCode val2 = (KeyCode)((firearmsShotgunAmmoKey != null) ? ((int)firearmsShotgunAmmoKey.Value) : 0); if (flag2 && (int)val2 != 0 && val2 != val && Input.GetKeyDown(val2)) { FirearmsAmmo.ToggleShotgunAmmo(held); } InputController instance = InputController.Instance; if (flag2 && (Object)(object)instance != (Object)null && instance.player != null) { bool num2 = FirearmsController.IsAutoWeapon(held); bool buttonDown = instance.player.GetButtonDown("Primary"); bool button = instance.player.GetButton("Primary"); if (buttonDown) { _autoArmed = true; } if (!button) { _autoArmed = false; } if (num2) { if (buttonDown || _autoArmed) { FirearmsController.Fire(); } } else if (buttonDown) { FirearmsController.Fire(); } } if (!flag2 && (Object)(object)instance != (Object)null && instance.player != null && instance.player.GetButtonDown("Primary")) { if (PoisonController.IsHoldingPoison(out var _, out var _)) { PoisonController.Use(); } else if (ChloroformController.IsHolding()) { ChloroformController.Use(); } else if (FingerprintRemoverController.IsHolding()) { FingerprintRemoverController.Use(); } } ConfigEntry firearmsFireKey = SyndicateConfig.FirearmsFireKey; KeyCode val3 = (KeyCode)((firearmsFireKey != null) ? ((int)firearmsFireKey.Value) : 0); if (flag2 && (int)val3 != 0) { bool num3 = FirearmsController.IsAutoWeapon(held); bool keyDown = Input.GetKeyDown(val3); bool key = Input.GetKey(val3); if (keyDown) { _fireKeyArmed = true; } if (!key) { _fireKeyArmed = false; } if (num3) { if (keyDown || _fireKeyArmed) { FirearmsController.Fire(); } } else if (keyDown) { FirearmsController.Fire(); } } ConfigEntry firearmsMeleeKey = SyndicateConfig.FirearmsMeleeKey; KeyCode val4 = (KeyCode)((firearmsMeleeKey != null) ? ((int)firearmsMeleeKey.Value) : 0); if (flag2 && (int)val4 != 0 && val4 != val3 && Input.GetKeyDown(val4) && Time.time >= _nextMeleeTime) { try { FirstPersonItemController.Instance.MeleeAttack(); _nextMeleeTime = Time.time + 0.6f; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag3 = default(bool); BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[Firearms] pistol-whip failed: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } logger.LogWarning(val5); } } if (flag2) { ConfigEntry firearmsDrawnDread = SyndicateConfig.FirearmsDrawnDread; if ((firearmsDrawnDread == null || firearmsDrawnDread.Value) && Time.time >= _nextDreadTime) { _nextDreadTime = Time.time + 0.5f; ApplyDrawnDread(); } } } catch { } } private static void ApplyDrawnDread() { //IL_00ea: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } float num = SyndicateConfig.FirearmsDrawnNerve?.Value ?? (-0.05f); if (num >= 0f) { return; } float num2 = Mathf.Max(0.5f, SyndicateConfig.FirearmsDrawnRange?.Value ?? 8f); NewRoom currentRoom = ((Actor)instance).currentRoom; HashSet val = (((Object)(object)currentRoom != (Object)null) ? currentRoom.currentOccupants : null); if (val == null) { return; } float num3 = num2 * num2; Vector3 position = ((Component)instance).transform.position; List list = new List(); Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Actor current = enumerator.Current; if ((Object)(object)current == (Object)null || current.isPlayer || current.isDead) { continue; } try { Human val2 = ((Il2CppObjectBase)current).TryCast(); if (!((Object)(object)val2 != (Object)null) || !((Actor)val2).isEnforcer) { Vector3 val3 = ((Component)current).transform.position - position; if (((Vector3)(ref val3)).sqrMagnitude <= num3) { list.Add(current); } } } catch { } } foreach (Actor item in list) { try { item.AddNerve(num, (Actor)(object)instance); } catch { } } } catch { } } private static bool InPlay() { try { if ((Object)(object)SessionData.Instance == (Object)null || !SessionData.Instance.play) { return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || ((Actor)instance).isDead) { return false; } if (instance.computerInteractable != null) { return false; } return true; } catch { return false; } } } public class FirearmsHud : MonoBehaviour { private float _reserveCacheAt = -999f; private int _reserveCache; public FirearmsHud(IntPtr ptr) : base(ptr) { } private void OnGUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) try { if ((int)Event.current.type != 7) { return; } ConfigEntry firearmsAmmoHud = SyndicateConfig.FirearmsAmmoHud; if ((firearmsAmmoHud != null && !firearmsAmmoHud.Value) || !InPlay()) { return; } bool flag = SyndicateConfig.FirearmsConsumeAmmo?.Value ?? true; string text = null; Interactable val = null; if (FirearmsController.IsHoldingFirearm(out var held, out var _) && held != null) { bool flag2 = FirearmsAmmo.IsMultiCaliber(held); if (flag2) { val = held; } if (FirearmsAmmo.IsReloading) { text = "RELOADING…"; } else if (!flag) { text = "∞"; } else { string value = "·"; int num = FirearmsAmmo.CapacityFor(held); int mag = FirearmsAmmo.GetMag(held.id, num); string text2 = FirearmsAmmo.LoadedLabel(held, flag2); string value2 = $"{CachedReserve(held)} rounds"; text = ((text2.Length > 0) ? $"{mag} / {num} {value} {text2} {value} {value2}" : $"{mag} / {num} {value} {value2}"); } } else if (flag) { Interactable equippedInteractableCached = KillSwitchPatch.GetEquippedInteractableCached(); if (FirearmsAmmo.IsAmmoBox(equippedInteractableCached)) { text = $"{FirearmsAmmo.BoxRoundsOf(equippedInteractableCached)} / {FirearmsAmmo.BoxCapacity(equippedInteractableCached)} rounds"; } } if (string.IsNullOrEmpty(text) && PoisonController.IsHoldingPoison(out var held2, out var kind) && kind == PoisonController.Kind.Syringe) { text = $"{PoisonDoses.Get(held2)} / {PoisonDoses.CapacityFor(held2)} doses"; } if (string.IsNullOrEmpty(text)) { ConfigEntry chloroformEnabled = SyndicateConfig.ChloroformEnabled; if ((chloroformEnabled == null || chloroformEnabled.Value) && ChloroformController.IsHolding(out var held3) && held3 != null) { text = $"{SedativeDoses.Get(held3)} / {SedativeDoses.Capacity} doses"; } } if (string.IsNullOrEmpty(text) && FingerprintRemoverController.IsHolding(out var held4) && held4 != null) { text = $"{PrintRemoverCharges.Get(held4)} / {PrintRemoverCharges.Capacity} charges"; } if (string.IsNullOrEmpty(text)) { return; } Rect r = default(Rect); ((Rect)(ref r))..ctor((float)Screen.width - 340f - 24f, (float)Screen.height - 34f - 28f, 340f, 34f); SynUI.Label(r, text, SynUI.TextPrimary, 20, (FontStyle)1, (TextAnchor)5); if (val != null) { ConfigEntry firearmsShotgunAmmoKey = SyndicateConfig.FirearmsShotgunAmmoKey; KeyCode val2 = (KeyCode)((firearmsShotgunAmmoKey != null) ? ((int)firearmsShotgunAmmoKey.Value) : 0); if ((int)val2 != 0) { SynUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y - 19f, 340f, 16f), $"[{val2}] SWITCH SHELL", SynUI.TextDim, 12, (FontStyle)0, (TextAnchor)5); } } } catch { } } private int CachedReserve(Interactable held) { if (Time.unscaledTime - _reserveCacheAt >= 0.25f) { _reserveCache = FirearmsAmmo.ReserveFor(held); _reserveCacheAt = Time.unscaledTime; } return _reserveCache; } private static bool InPlay() { try { if ((Object)(object)SessionData.Instance == (Object)null || !SessionData.Instance.play) { return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || ((Actor)instance).isDead) { return false; } if (instance.computerInteractable != null) { return false; } return true; } catch { return false; } } } internal static class FirearmsPose { private struct Pose { public Vector3 Offset; public Vector3 Rot; } private static readonly Dictionary Baked = new Dictionary { ["SemiAutomaticPistol"] = new Pose { Offset = new Vector3(-176f, 107f, -34f), Rot = new Vector3(349.4f, 275.3f, 358.8f) }, ["SemiAutomaticPistolSilenced"] = new Pose { Offset = new Vector3(-176f, 107f, -34f), Rot = new Vector3(349.4f, 275.3f, 358.8f) }, ["Revolver"] = new Pose { Offset = new Vector3(-301f, 12f, -34f), Rot = new Vector3(354.4f, 275.3f, 353.8f) }, ["Shotgun"] = new Pose { Offset = new Vector3(-827f, 181f, 26f), Rot = new Vector3(7.7f, 357.6f, 351.6f) }, ["BattleRifle"] = new Pose { Offset = new Vector3(-777f, 71f, -34f), Rot = new Vector3(7.3f, 7.6f, 1.6f) }, ["SniperRifle"] = new Pose { Offset = new Vector3(-1022f, 101f, 216f), Rot = new Vector3(277.3f, 352.6f, 16.6f) }, ["Syringe"] = new Pose { Offset = new Vector3(-202.13f, 436.16f, -324.74f), Rot = new Vector3(336.8f, 238.2f, 245.4f) } }; private static bool _hooked; public static void Init() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown if (_hooked) { return; } _hooked = true; try { Lib.SaveGame.OnAfterNewGame += delegate { Apply(); }; Lib.SaveGame.OnAfterLoad += delegate { Apply(); }; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FirearmsPose] hook failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void Apply() { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown bool flag = default(bool); try { Toolbox instance = Toolbox.Instance; if ((Object)(object)instance == (Object)null) { return; } int num = 0; foreach (KeyValuePair item in Baked) { InteractablePreset val = null; try { val = instance.GetInteractablePreset(item.Key); } catch { } if (!((SoCustomComparison)(object)val == (SoCustomComparison)null)) { val.fpsItemOffset = item.Value.Offset; val.fpsItemRotation = item.Value.Rot; num++; } } ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(143, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[FirearmsPose] applied "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" gun hold pose(s). (Ammo pairing is a private map in FirearmsController — the shared weapon presets are left untouched.)"); } logger.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[FirearmsPose] apply failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } } public class PoseLab : MonoBehaviour { private static readonly string[] Donors = new string[6] { "camera", "Briefcase", "fingerptintScanner", "newspaper", "handcuffs", "coin" }; private static int _donorIdx = -1; private static bool _rotateMode; private static bool _raised; private bool _announced; private static readonly Dictionary _original = new Dictionary(); private static readonly Dictionary _clone = new Dictionary(); private static FirstPersonItem[] _fpiCache; private static readonly string[] ExtraTargets = new string[1] { "Syringe" }; private static readonly string[] PoseTargetNames = new string[7] { "SemiAutomaticPistol", "SemiAutomaticPistolSilenced", "Revolver", "Shotgun", "BattleRifle", "SniperRifle", "Syringe" }; public PoseLab(IntPtr ptr) : base(ptr) { } public static bool Active() { try { ConfigEntry firearmsPoseLab = SyndicateConfig.FirearmsPoseLab; if (firearmsPoseLab == null || !firearmsPoseLab.Value) { return false; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || ((Actor)instance).isDead || instance.computerInteractable != null) { return false; } return IsPoseTarget(TargetPreset()); } catch { return false; } } private static bool IsPoseTarget(InteractablePreset p) { if ((SoCustomComparison)(object)p == (SoCustomComparison)null) { return false; } try { if (FirearmsController.IsHoldingFirearm(out var _, out var _)) { return true; } } catch { } string text = null; try { text = ((Object)p).name; } catch { } if (text != null) { for (int i = 0; i < ExtraTargets.Length; i++) { if (text == ExtraTargets[i]) { return true; } } } return false; } public static string StatusLine() { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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) try { ConfigEntry firearmsPoseLab = SyndicateConfig.FirearmsPoseLab; if (firearmsPoseLab == null || !firearmsPoseLab.Value) { return "Pose Lab: OFF (set Firearms/PoseLab=true, restart)"; } InteractablePreset val = TargetPreset(); if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { return "Pose Lab: ON — equip a gun or syringe"; } string value = ((_donorIdx == -1) ? "ORIGINAL" : Donors[Mathf.Clamp(_donorIdx, 0, Donors.Length - 1)]); return $"{((Object)val).name} donor={value} raised={_raised} [{(_rotateMode ? "ROT" : "POS")}]\n offset=({val.fpsItemOffset.x:0.#}, {val.fpsItemOffset.y:0.#}, {val.fpsItemOffset.z:0.#}) rot=({val.fpsItemRotation.x:0.#}, {val.fpsItemRotation.y:0.#}, {val.fpsItemRotation.z:0.#})"; } catch { return "Pose Lab: (status error)"; } } private void Update() { try { if (Active()) { if (!_announced) { Plugin.Logger.LogInfo((object)"[PoseLab] ON. Equip a gun or syringe. [ ] cycle donor pose, H aim, G pos/rot, arrows XY, ,/. Z (Shift=coarse Ctrl=fine), P log, Backspace zero. Or use the F6 buttons."); _announced = true; } if (Input.GetKeyDown((KeyCode)91)) { CycleDonor(-1); } if (Input.GetKeyDown((KeyCode)93)) { CycleDonor(1); } if (Input.GetKeyDown((KeyCode)104)) { ToggleRaised(); } if (Input.GetKeyDown((KeyCode)103)) { ToggleMode(); } if (Input.GetKeyDown((KeyCode)112)) { LogCurrent(); } if (Input.GetKeyDown((KeyCode)8)) { ZeroOffset(); } float posStep = 5f; float rotStep = 5f; if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { posStep = 25f; rotStep = 15f; } else if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) { posStep = 1f; rotStep = 1f; } if (Input.GetKeyDown((KeyCode)276)) { Nudge(-1, 0, 0, posStep, rotStep); } if (Input.GetKeyDown((KeyCode)275)) { Nudge(1, 0, 0, posStep, rotStep); } if (Input.GetKeyDown((KeyCode)273)) { Nudge(0, 1, 0, posStep, rotStep); } if (Input.GetKeyDown((KeyCode)274)) { Nudge(0, -1, 0, posStep, rotStep); } if (Input.GetKeyDown((KeyCode)44)) { Nudge(0, 0, -1, posStep, rotStep); } if (Input.GetKeyDown((KeyCode)46)) { Nudge(0, 0, 1, posStep, rotStep); } } } catch { } } private static InteractablePreset TargetPreset() { try { Interactable equippedInteractableCached = KillSwitchPatch.GetEquippedInteractableCached(); return (equippedInteractableCached != null) ? equippedInteractableCached.preset : null; } catch { return null; } } private static Transform Model() { try { FirstPersonItemController instance = FirstPersonItemController.Instance; Transform val = (((Object)(object)instance != (Object)null) ? instance.rightHandObjectParent : null); if ((Object)(object)val == (Object)null || val.childCount == 0) { return null; } return val.GetChild(0); } catch { return null; } } private static FirstPersonItem FindFpi(string name) { try { if (_fpiCache == null) { _fpiCache = Il2CppArrayBase.op_Implicit(Resources.FindObjectsOfTypeAll()); } if (_fpiCache == null) { return null; } for (int i = 0; i < _fpiCache.Length; i++) { if ((SoCustomComparison)(object)_fpiCache[i] != (SoCustomComparison)null && ((Object)_fpiCache[i]).name == name) { return _fpiCache[i]; } } return null; } catch { return null; } } private static void ReDraw() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown try { BioScreenController instance = BioScreenController.Instance; if ((Object)(object)instance != (Object)null && instance.selectedSlot != null) { instance.SelectSlot(instance.selectedSlot, false, true, true); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PoseLab] re-draw failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } } public static void CycleDonor(int delta) { //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown if (!Active()) { return; } FirstPersonItemController instance = FirstPersonItemController.Instance; if ((Object)(object)instance == (Object)null || !instance.finishedDrawingItem) { Plugin.Logger.LogInfo((object)"[PoseLab] wait for the draw to finish, then cycle again."); return; } InteractablePreset val = TargetPreset(); if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { Plugin.Logger.LogInfo((object)"[PoseLab] equip a gun or syringe first."); return; } bool flag = default(bool); try { string name = ((Object)val).name; if (!_original.ContainsKey(name)) { _original[name] = val.fpsItem; } int num = Donors.Length; _donorIdx += delta; if (_donorIdx < -1) { _donorIdx = num - 1; } if (_donorIdx >= num) { _donorIdx = -1; } BepInExInfoLogInterpolatedStringHandler val2; if (_donorIdx == -1) { val.fpsItem = _original[name]; ReDraw(); ManualLogSource logger = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PoseLab] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ORIGINAL pose (item_Bar_melee)."); } logger.LogInfo(val2); return; } FirstPersonItem val3 = FindFpi(Donors[_donorIdx]); if ((SoCustomComparison)(object)val3 == (SoCustomComparison)null) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PoseLab] donor '"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(Donors[_donorIdx]); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("' not found."); } logger2.LogWarning(val4); return; } if (!_clone.TryGetValue(name, out var value) || (SoCustomComparison)(object)value == (SoCustomComparison)null) { value = Object.Instantiate(_original[name]); _clone[name] = value; } value.slotPriority = val3.slotPriority; value.idleClip = val3.idleClip; val.fpsItem = value; ReDraw(); ManualLogSource logger3 = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(90, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PoseLab] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": donor '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)val3).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (slot "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val3.slotPriority); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", idle "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)(object)val3.idleClip != (Object)null) ? ((Object)val3.idleClip).name : "-"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("). Press H to try its aim pose; arrows to place the gun."); } logger3.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger4 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PoseLab] cycle failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger4.LogWarning(val4); } } public static void ToggleRaised() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (!Active()) { return; } bool flag = default(bool); try { _raised = !_raised; FirstPersonItemController.Instance.SetRaised(_raised); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PoseLab] Raised = "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_raised); } logger.LogInfo(val); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PoseLab] raise failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger2.LogWarning(val2); } } public static void ToggleMode() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (Active()) { _rotateMode = !_rotateMode; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PoseLab] tune mode = "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_rotateMode ? "ROTATION" : "POSITION"); } logger.LogInfo(val); } } public static void Nudge(int x, int y, int z, float posStep, float rotStep) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (!Active()) { return; } InteractablePreset val = TargetPreset(); Transform val2 = Model(); try { if (_rotateMode) { Vector3 val3 = (((Object)(object)val2 != (Object)null) ? val2.localEulerAngles : (((SoCustomComparison)(object)val != (SoCustomComparison)null) ? val.fpsItemRotation : Vector3.zero)); ((Vector3)(ref val3))..ctor(val3.x + (float)x * rotStep, val3.y + (float)y * rotStep, val3.z + (float)z * rotStep); if ((Object)(object)val2 != (Object)null) { val2.localEulerAngles = val3; } if ((SoCustomComparison)(object)val != (SoCustomComparison)null) { val.fpsItemRotation = val3; } } else { Vector3 val4 = (((Object)(object)val2 != (Object)null) ? val2.localPosition : (((SoCustomComparison)(object)val != (SoCustomComparison)null) ? val.fpsItemOffset : Vector3.zero)); ((Vector3)(ref val4))..ctor(val4.x + (float)x * posStep, val4.y + (float)y * posStep, val4.z + (float)z * posStep); if ((Object)(object)val2 != (Object)null) { val2.localPosition = val4; } if ((SoCustomComparison)(object)val != (SoCustomComparison)null) { val.fpsItemOffset = val4; } } } catch { } } public static void LogCurrent() { //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown if (!Active()) { return; } bool flag = default(bool); try { InteractablePreset val = TargetPreset(); string text = ((_donorIdx == -1) ? "ORIGINAL" : Donors[Mathf.Clamp(_donorIdx, 0, Donors.Length - 1)]); string text2 = (((SoCustomComparison)(object)val != (SoCustomComparison)null) ? $"{val.fpsItemOffset.x:0.##}, {val.fpsItemOffset.y:0.##}, {val.fpsItemOffset.z:0.##}" : "?"); string text3 = (((SoCustomComparison)(object)val != (SoCustomComparison)null) ? $"{val.fpsItemRotation.x:0.#}, {val.fpsItemRotation.y:0.#}, {val.fpsItemRotation.z:0.#}" : "?"); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(69, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PoseLab] >>> "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((SoCustomComparison)(object)val != (SoCustomComparison)null) ? ((Object)val).name : "?"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" donor="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Raised="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_raised); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" fpsItemOffset=("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") fpsItemRotation=("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text3); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } logger.LogInfo(val2); try { Lib.GameMessage.Broadcast($"Logged {(((SoCustomComparison)(object)val != (SoCustomComparison)null) ? ((Object)val).name : "gun")} / {text}.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[PoseLab] log failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger2.LogWarning(val3); } } public static void ZeroOffset() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!Active()) { return; } InteractablePreset val = TargetPreset(); Transform val2 = Model(); try { if ((SoCustomComparison)(object)val != (SoCustomComparison)null) { val.fpsItemOffset = Vector3.zero; val.fpsItemRotation = Vector3.zero; } if ((Object)(object)val2 != (Object)null) { val2.localPosition = Vector3.zero; val2.localEulerAngles = Vector3.zero; } Plugin.Logger.LogInfo((object)"[PoseLab] offset zeroed."); } catch { } } public static void Dump() { Log("========== FIREARMS POSE LAB DUMP =========="); DumpFpsItems(); DumpGunFpsItems(); DumpClipPool(); DumpRig(); Log("========== POSE LAB DUMP end =========="); try { Lib.GameMessage.Broadcast("Pose Lab dump -> see BepInEx log.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } private static void DumpFpsItems() { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) Log("--- FIRST-PERSON ITEMS (name / slotPriority / idleClip / useFoodSlotItem / actions) ---"); try { Il2CppArrayBase val = Resources.FindObjectsOfTypeAll(); if (val == null) { Log(" (none)"); return; } for (int i = 0; i < val.Length; i++) { FirstPersonItem f = val[i]; if ((SoCustomComparison)(object)f == (SoCustomComparison)null) { continue; } string value = "-"; try { value = (((Object)(object)f.idleClip != (Object)null) ? ((Object)f.idleClip).name : "-"); } catch { } StringBuilder stringBuilder = new StringBuilder(); try { if (f.actions != null) { for (int j = 0; j < f.actions.Count; j++) { if (j > 0) { stringBuilder.Append('|'); } stringBuilder.Append((f.actions[j] != null) ? ((object)f.actions[j].mainSpecialAction/*cast due to .constrained prefix*/).ToString() : "null"); } } } catch { } Log($" {((Object)f).name,-24} slot={SafeInt(() => f.slotPriority),-3} idle={value,-22} food={SafeBool(() => f.useFoodSlotItem)} actions=[{stringBuilder}]"); } Log($" [{val.Length} fps items]"); } catch (Exception ex) { Log(" [fps item dump failed: " + ex.Message + "]"); } } private static void DumpGunFpsItems() { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) Log("--- ITEM -> fpsItem (which pose each pose-target currently uses) ---"); try { Toolbox instance = Toolbox.Instance; string[] poseTargetNames = PoseTargetNames; foreach (string text in poseTargetNames) { InteractablePreset val = null; try { val = instance.GetInteractablePreset(text); } catch { } if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { Log($" {text,-28} (no preset)"); continue; } string value = "-"; int value2 = -1; try { if ((SoCustomComparison)(object)val.fpsItem != (SoCustomComparison)null) { value = ((Object)val.fpsItem).name; value2 = val.fpsItem.slotPriority; } } catch { } string value3 = "?"; string value4 = "?"; try { value3 = $"{val.fpsItemOffset.x:0.###},{val.fpsItemOffset.y:0.###},{val.fpsItemOffset.z:0.###}"; } catch { } try { value4 = $"{val.fpsItemRotation.x:0.#},{val.fpsItemRotation.y:0.#},{val.fpsItemRotation.z:0.#}"; } catch { } Log($" {text,-28} fpsItem={value,-20} slot={value2,-3} offset=({value3}) rot=({value4})"); } } catch (Exception ex) { Log(" [gun fpsItem dump failed: " + ex.Message + "]"); } } private static void DumpClipPool() { Log("--- FPS ANIMATOR (clips) ---"); try { Animator val = (((Object)(object)InterfaceController.Instance != (Object)null) ? InterfaceController.Instance.firstPersonAnimator : null); if ((Object)(object)val == (Object)null) { Log(" (no firstPersonAnimator)"); return; } RuntimeAnimatorController runtimeAnimatorController = val.runtimeAnimatorController; Il2CppReferenceArray val2 = (((Object)(object)runtimeAnimatorController != (Object)null) ? runtimeAnimatorController.animationClips : null); if (val2 == null) { return; } StringBuilder stringBuilder = new StringBuilder(" clips: "); for (int i = 0; i < ((Il2CppArrayBase)(object)val2).Length; i++) { if (i > 0) { stringBuilder.Append(", "); } stringBuilder.Append(((Object)(object)((Il2CppArrayBase)(object)val2)[i] != (Object)null) ? ((Object)((Il2CppArrayBase)(object)val2)[i]).name : "null"); } Log(stringBuilder.ToString()); Log($" [{((Il2CppArrayBase)(object)val2).Length} clips]"); } catch (Exception ex) { Log(" [clip dump failed: " + ex.Message + "]"); } } private static void DumpRig() { Log("--- FPS RIG (for Plan C) ---"); try { FirstPersonItemController instance = FirstPersonItemController.Instance; Transform val = (((Object)(object)instance != (Object)null) ? instance.rightHandObjectParent : null); if ((Object)(object)val == (Object)null) { Log(" (no rightHandObjectParent)"); return; } Transform val2 = val; for (int i = 0; i < 6; i++) { if (!((Object)(object)val2.parent != (Object)null)) { break; } val2 = val2.parent; } int count = 0; DumpTransform(val2, 0, ref count, 200); Log($" [{count} transforms shown]"); } catch (Exception ex) { Log(" [rig dump failed: " + ex.Message + "]"); } } private static void DumpTransform(Transform t, int depth, ref int count, int cap) { if (!((Object)(object)t == (Object)null) && count < cap) { count++; Log(" " + new string(' ', depth * 2) + ((Object)t).name); for (int i = 0; i < t.childCount; i++) { DumpTransform(t.GetChild(i), depth + 1, ref count, cap); } } } private static int SafeInt(Func f) { try { return f(); } catch { return -1; } } private static bool SafeBool(Func f) { try { return f(); } catch { return false; } } private static void Log(string s) { Plugin.Logger.LogInfo((object)("[PoseLab] " + s)); } } } namespace TheSyndicate.Evidence { internal static class PlayerEvidence { private sealed class PrintRecord { public int RoomId; public long LocationId; public int Heat; public string ObjectName = "object"; } public readonly struct PrintInfo { public readonly long Key; public readonly int Heat; public readonly string Name; public PrintInfo(long key, int heat, string name) { Key = key; Heat = heat; Name = name; } } private static readonly Dictionary Prints = new Dictionary(); private static readonly Random Rng = new Random(); public static int TotalPrints => Prints.Count; public static void RecordPrint(long interactableId, int roomId, long locationId, string objectName = "object") { if (interactableId != 0L && !Prints.ContainsKey(interactableId)) { int num = ((SyndicateConfig.FingerprintMinHeat != null) ? SyndicateConfig.FingerprintMinHeat.Value : 3); int num2 = ((SyndicateConfig.FingerprintMaxHeat != null) ? SyndicateConfig.FingerprintMaxHeat.Value : 12); if (num2 < num) { num2 = num; } Prints[interactableId] = new PrintRecord { RoomId = roomId, LocationId = locationId, Heat = Rng.Next(num, num2 + 1), ObjectName = (string.IsNullOrEmpty(objectName) ? "object" : objectName) }; } } public static bool HasPrint(long interactableId) { if (interactableId != 0L) { return Prints.ContainsKey(interactableId); } return false; } public static void DebugDump() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(48, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PrintProbe] PlayerEvidence: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Prints.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" recorded print(s)."); } logger.LogInfo(val); foreach (KeyValuePair print in Prints) { ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(38, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PrintProbe] id="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(print.Key); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" room="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(print.Value.RoomId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" heat="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(print.Value.Heat); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" name='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(print.Value.ObjectName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); } logger2.LogInfo(val); } } public static void RemovePrint(long interactableId) { Prints.Remove(interactableId); } public static int SumPrintHeatInRoom(int roomId) { if (roomId < 0) { return 0; } int num = 0; foreach (KeyValuePair print in Prints) { if (print.Value.RoomId == roomId) { num += print.Value.Heat; } } return num; } public static List GetPrintExamplesInRoom(int roomId, int max) { List list = new List(); if (roomId < 0) { return list; } foreach (KeyValuePair print in Prints) { if (print.Value.RoomId == roomId) { list.Add(print.Value.ObjectName); if (list.Count >= max) { break; } } } return list; } public static int CountPrintsInLocation(long locationId) { if (locationId == 0L) { return 0; } int num = 0; foreach (KeyValuePair print in Prints) { if (print.Value.LocationId == locationId) { num++; } } return num; } public static int SumPrintHeatInLocation(long locationId) { if (locationId == 0L) { return 0; } int num = 0; foreach (KeyValuePair print in Prints) { if (print.Value.LocationId == locationId) { num += print.Value.Heat; } } return num; } public static List GetPrintExamplesInLocation(long locationId, int max) { List list = new List(); if (locationId == 0L) { return list; } foreach (KeyValuePair print in Prints) { if (print.Value.LocationId == locationId) { list.Add(print.Value.ObjectName); if (list.Count >= max) { break; } } } return list; } public static List GetRecordsInLocation(long locationId) { List list = new List(); if (locationId == 0L) { return list; } foreach (KeyValuePair print in Prints) { if (print.Value.LocationId == locationId) { list.Add(new PrintInfo(print.Key, print.Value.Heat, print.Value.ObjectName)); } } return list; } public static void Clear() { Prints.Clear(); } public static int ClearLocation(long locationId) { if (locationId == 0L) { return 0; } List list = new List(); foreach (KeyValuePair print in Prints) { if (print.Value.LocationId == locationId) { list.Add(print.Key); } } foreach (long item in list) { Prints.Remove(item); } return list.Count; } public static List CaptureDtos() { List list = new List(); foreach (KeyValuePair print in Prints) { list.Add(new PrintDto { InteractableId = print.Key, RoomId = print.Value.RoomId, LocKey = print.Value.LocationId, Heat = print.Value.Heat, ObjectName = print.Value.ObjectName }); } return list; } public static void RestoreFrom(List dtos) { Prints.Clear(); if (dtos == null) { return; } foreach (PrintDto dto in dtos) { if (dto.InteractableId != 0L) { Prints[dto.InteractableId] = new PrintRecord { RoomId = dto.RoomId, LocationId = dto.LocKey, Heat = dto.Heat, ObjectName = (string.IsNullOrEmpty(dto.ObjectName) ? "object" : dto.ObjectName) }; } } } } internal static class PrintKeys { private const long FixtureBit = 1099511627776L; public static long For(Interactable obj) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (obj == null) { return 0L; } try { if ((Object)(object)obj.isActor != (Object)null) { return 0L; } } catch { } long num = 0L; try { num = obj.id; } catch { } if (num != 0L) { return num; } try { Vector3 spWPos = obj.spWPos; long num2 = (long)Math.Round(spWPos.x * 100f); long num3 = (long)Math.Round(spWPos.y * 100f); long num4 = (long)Math.Round(spWPos.z * 100f); long num5 = 1469598103934665603L; num5 = (num5 ^ num2) * 1099511628211L; num5 = (num5 ^ num3) * 1099511628211L; num5 = (num5 ^ num4) * 1099511628211L; string text = (((SoCustomComparison)(object)obj.preset != (SoCustomComparison)null) ? ((Object)obj.preset).name : ""); for (int i = 0; i < text.Length; i++) { num5 = (num5 ^ text[i]) * 1099511628211L; } return 0x10000000000L | (num5 & 0xFFFFFFFFFFL); } catch { return 0L; } } public static bool IsImmovable(long key) { if (key >= 0) { return (key & 0x10000000000L) != 0; } return true; } } } namespace TheSyndicate.DebugTools { internal static class CruncherProbe { internal static bool Trace; internal static void Census() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Expected O, but got Unknown //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Expected O, but got Unknown bool flag = default(bool); try { Il2CppArrayBase val = Resources.FindObjectsOfTypeAll(); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(54, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CruncherProbe] ===== CruncherAppPreset census: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val.Length); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ====="); } logger.LogInfo(val2); foreach (CruncherAppPreset item in val) { if ((SoCustomComparison)(object)item == (SoCustomComparison)null) { continue; } StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(41, 2, stringBuilder2); handler.AppendLiteral("[CruncherProbe] app '"); handler.AppendFormatted(((SoCustomComparison)item).presetName); handler.AppendLiteral("' icon='"); handler.AppendFormatted(((Object)(object)item.desktopIcon != (Object)null) ? ((Object)item.desktopIcon).name : "null"); handler.AppendLiteral("' content="); stringBuilder3.Append(ref handler); if (item.appContent == null) { stringBuilder.Append("null"); } else { stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendLiteral("["); handler.AppendFormatted(item.appContent.Count); handler.AppendLiteral("]"); stringBuilder4.Append(ref handler); for (int i = 0; i < item.appContent.Count; i++) { GameObject val3 = item.appContent[i]; if ((Object)(object)val3 == (Object)null) { stringBuilder.Append(" {null}"); continue; } stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(32, 3, stringBuilder2); handler.AppendLiteral(" {name="); handler.AppendFormatted(((Object)val3).name); handler.AppendLiteral(", kind="); handler.AppendFormatted(ContentKind(val3)); handler.AppendLiteral(", hasMultiSelect="); handler.AppendFormatted((Object)(object)val3.GetComponentInChildren(true) != (Object)null); handler.AppendLiteral("}"); stringBuilder5.Append(ref handler); } } Plugin.Logger.LogInfo((object)stringBuilder.ToString()); } Il2CppArrayBase obj = Resources.FindObjectsOfTypeAll(); int num = 0; foreach (InteractablePreset item2 in obj) { if ((SoCustomComparison)(object)item2 == (SoCustomComparison)null || !item2.isComputer) { continue; } num++; StringBuilder stringBuilder6 = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder6; StringBuilder stringBuilder7 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(72, 4, stringBuilder2); handler.AppendLiteral("[CruncherProbe] computer '"); handler.AppendFormatted(((SoCustomComparison)item2).presetName); handler.AppendLiteral("' boot='"); handler.AppendFormatted(AppName(item2.bootApp)); handler.AppendLiteral("' login='"); handler.AppendFormatted(AppName(item2.logInApp)); handler.AppendLiteral("' desktop='"); handler.AppendFormatted(AppName(item2.desktopApp)); handler.AppendLiteral("' additionalApps="); stringBuilder7.Append(ref handler); if (item2.additionalApps == null) { stringBuilder6.Append("null"); } else { stringBuilder2 = stringBuilder6; StringBuilder stringBuilder8 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendLiteral("["); handler.AppendFormatted(item2.additionalApps.Count); handler.AppendLiteral("]"); stringBuilder8.Append(ref handler); for (int j = 0; j < item2.additionalApps.Count; j++) { stringBuilder2 = stringBuilder6; StringBuilder stringBuilder9 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendLiteral(" "); handler.AppendFormatted(AppName(item2.additionalApps[j])); stringBuilder9.Append(ref handler); } } Plugin.Logger.LogInfo((object)stringBuilder6.ToString()); } ManualLogSource logger2 = Plugin.Logger; val2 = new BepInExInfoLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CruncherProbe] ===== computer presets: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ====="); } logger2.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[CruncherProbe] Census failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex); } logger3.LogError(val4); } } private static string ContentKind(GameObject go) { try { if ((Object)(object)go.GetComponent() == (Object)null) { return "none"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "VMailApp"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "DatabaseApp"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "SurveillanceApp"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "SalesRecordsApp"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "ProfileApp"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "SecurityApp"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "DesktopApp"; } if ((Object)(object)go.GetComponent() != (Object)null) { return "ComputerLogin"; } return "CruncherAppContent(other)"; } catch { return "?"; } } private static string AppName(CruncherAppPreset p) { if (!((SoCustomComparison)(object)p != (SoCustomComparison)null)) { return "null"; } return ((SoCustomComparison)p).presetName; } } [HarmonyPatch(typeof(ComputerController), "SetComputerApp")] internal static class CruncherSetAppTrace { private static void Postfix(CruncherAppPreset newApp, bool forceUpdate) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (CruncherProbe.Trace) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CruncherProbe] SetComputerApp('"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((SoCustomComparison)(object)newApp != (SoCustomComparison)null) ? ((SoCustomComparison)newApp).presetName : "null"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', force="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(forceUpdate); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logger.LogInfo(val); } } } [HarmonyPatch(typeof(ComputerController), "OnAppLoaded")] internal static class CruncherAppLoadedTrace { private static void Postfix(ComputerController __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (CruncherProbe.Trace) { int num = (((Object)(object)__instance != (Object)null && __instance.spawnedContent != null) ? __instance.spawnedContent.Count : (-1)); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CruncherProbe] OnAppLoaded spawnedContent="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); } logger.LogInfo(val); } } } [HarmonyPatch(typeof(ComputerController), "OnAppExit")] internal static class CruncherAppExitTrace { private static void Postfix() { if (CruncherProbe.Trace) { Plugin.Logger.LogInfo((object)"[CruncherProbe] OnAppExit"); } } } [HarmonyPatch(typeof(DesktopApp), "UpdateIcons")] internal static class CruncherUpdateIconsTrace { private static void Postfix() { if (CruncherProbe.Trace) { Plugin.Logger.LogInfo((object)"[CruncherProbe] DesktopApp.UpdateIcons()"); } } } public class DebugHud : MonoBehaviour { private bool _visible; private Vector2 _scroll; public DebugHud(IntPtr ptr) : base(ptr) { } private void Update() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (Input.GetKeyDown((KeyCode)287)) { _visible = !_visible; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Debug HUD "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_visible ? "shown" : "hidden"); } logger.LogInfo(val); } if (Input.GetKeyDown((KeyCode)289)) { PrintInspector.InspectLookedAt(); } } private void OnGUI() { //IL_0bca: Unknown result type (might be due to invalid IL or missing references) //IL_0bd1: Expected O, but got Unknown //IL_1128: Unknown result type (might be due to invalid IL or missing references) //IL_112f: Expected O, but got Unknown //IL_1239: Unknown result type (might be due to invalid IL or missing references) //IL_1240: Expected O, but got Unknown //IL_0023: 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) //IL_004a: 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_1292: Unknown result type (might be due to invalid IL or missing references) //IL_1299: Expected O, but got Unknown //IL_11ba: Unknown result type (might be due to invalid IL or missing references) //IL_11c1: Expected O, but got Unknown //IL_11ff: Unknown result type (might be due to invalid IL or missing references) //IL_1206: Expected O, but got Unknown //IL_1323: Unknown result type (might be due to invalid IL or missing references) //IL_132a: Expected O, but got Unknown //IL_07f2: Unknown result type (might be due to invalid IL or missing references) //IL_07f9: Expected O, but got Unknown //IL_075a: Unknown result type (might be due to invalid IL or missing references) //IL_0761: Expected O, but got Unknown //IL_14db: Unknown result type (might be due to invalid IL or missing references) //IL_14e2: Expected O, but got Unknown //IL_0941: Unknown result type (might be due to invalid IL or missing references) //IL_0948: Expected O, but got Unknown //IL_0a10: Unknown result type (might be due to invalid IL or missing references) //IL_0a17: Expected O, but got Unknown //IL_0ab6: Unknown result type (might be due to invalid IL or missing references) //IL_0abd: Expected O, but got Unknown //IL_0b07: Unknown result type (might be due to invalid IL or missing references) //IL_0b0e: Expected O, but got Unknown //IL_0b58: Unknown result type (might be due to invalid IL or missing references) //IL_0b5f: Expected O, but got Unknown //IL_178a: Unknown result type (might be due to invalid IL or missing references) //IL_1791: Expected O, but got Unknown //IL_1837: Unknown result type (might be due to invalid IL or missing references) //IL_183e: Expected O, but got Unknown //IL_110a: Unknown result type (might be due to invalid IL or missing references) if (!_visible) { return; } SyndicateData data = SyndicateState.Data; GUILayout.BeginArea(new Rect(20f, 20f, 420f, 640f), GUI.skin.box); GUILayout.Label("THE SYNDICATE — DEBUG (F6)", (Il2CppReferenceArray)null); _scroll = GUILayout.BeginScrollView(_scroll, (Il2CppReferenceArray)null); GUILayout.Space(4f); GUILayout.Label($"Underworld Rep: {data.UnderworldRep} (Level {SyndicateState.Level}, Tier {SyndicateState.Tier}, rewarded≤{data.LastRewardedLevel})", (Il2CppReferenceArray)null); GUILayout.Label($"Heat Score: {data.PlayerHeatScore} | Suspicion: {data.SuspicionState}", (Il2CppReferenceArray)null); GUILayout.Label("Warrant: " + (data.ActiveWarrant ? ("ACTIVE (expires " + data.WarrantExpires + ")") : "none"), (Il2CppReferenceArray)null); GUILayout.Label($"Fines: {FineLedger.Outstanding:n0}cr ({FineLedger.UnpaidCount} unpaid)", (Il2CppReferenceArray)null); foreach (string item in FineLedger.ItemizedLines()) { GUILayout.Label(" · " + item, (Il2CppReferenceArray)null); } GUILayout.Label("Resolve window: " + (data.InvestigationActive ? ("warrant at " + data.InvestigationExpires) : "none"), (Il2CppReferenceArray)null); GUILayout.Label($"Scenes: {CrimeSceneManager.ActiveCount} active ({CrimeSceneManager.UnreportedCount} unreported) | witnesses pending: {CrimeSceneManager.WitnessCount}", (Il2CppReferenceArray)null); GUILayout.Label("Sight (loc): " + CrimeSceneManager.DebugSightSummary(), (Il2CppReferenceArray)null); GUILayout.Label($"Room: {CrimeSceneManager.DebugRoomSummary()} | Hunters: {ManhuntController.ActiveHunters()}", (Il2CppReferenceArray)null); GUILayout.Label($"Gloves: {(SyndicateState.GlovesActive ? "ACTIVE (Second Skin always-on)" : (data.GlovesDiskInstalled ? "installed" : "NO DISK"))} | Prints left: {PlayerEvidence.TotalPrints}", (Il2CppReferenceArray)null); GameplayController instance = GameplayController.Instance; GUILayout.Label(((Object)(object)instance != (Object)null) ? $"Hit tokens: {data.HitTokens} (lifetime {data.HitTokensEarnedTotal}) | Social credit: {instance.socialCredit} (L{instance.GetCurrentSocialCreditLevel()}, next @ {instance.GetNextSocialCreditLevelThreshold()})" : $"Hit tokens: {data.HitTokens} (lifetime {data.HitTokensEarnedTotal}) | Social credit: (n/a)", (Il2CppReferenceArray)null); GUILayout.Label("Save sync: " + SyndicateState.LastSyncStatus, (Il2CppReferenceArray)null); GUILayout.Space(4f); GUILayout.Label($"Contracts ({data.ActiveContracts.Count})", (Il2CppReferenceArray)null); foreach (ContractData activeContract in data.ActiveContracts) { string value = TryDescribeTarget(activeContract); int value2 = ((activeContract.BasePayout > 0) ? activeContract.BasePayout : activeContract.Reward); GUILayout.Label($"[{activeContract.Type}/T{activeContract.Tier}/{activeContract.InfoLevel}] {activeContract.TargetName} (#{activeContract.TargetId}) — {activeContract.Status} — {value2}cr — {value}", (Il2CppReferenceArray)null); if (!(activeContract.Status == "Active") || activeContract.Objectives == null || activeContract.Objectives.Count <= 0) { continue; } StringBuilder stringBuilder = new StringBuilder(" objectives: "); for (int i = 0; i < activeContract.Objectives.Count; i++) { if (i > 0) { stringBuilder.Append(", "); } stringBuilder.Append(activeContract.Objectives[i].Type).Append(':').Append(activeContract.Objectives[i].Outcome); } GUILayout.Label(stringBuilder.ToString(), (Il2CppReferenceArray)null); } if (data.ActiveContracts.Count == 0) { GUILayout.Label("(none)", (Il2CppReferenceArray)null); } GUILayout.Space(6f); bool flag = default(bool); if (GUILayout.Button("Advance 1 Syndicate Level", (Il2CppReferenceArray)null)) { int num = (SyndicateState.Level + 1) switch { 3 => SyndicateConfig.Level3Rep?.Value ?? 100, 2 => SyndicateConfig.Level2Rep?.Value ?? 50, 1 => SyndicateConfig.Level1Rep?.Value ?? 20, _ => -1, }; if (num < 0) { Plugin.Logger.LogInfo((object)"[Debug] Already at max Syndicate level (3)."); } else { data.UnderworldRep = Math.Max(data.UnderworldRep + 1, num); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] Rep -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.UnderworldRep); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (Level "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateState.Level); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Tier "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateState.Tier); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logger.LogInfo(val); ProgressionManager.Evaluate(); } } if (GUILayout.Button("Dock -25 Rep (simulate punishment)", (Il2CppReferenceArray)null)) { data.UnderworldRep = Math.Max(0, data.UnderworldRep - 25); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] Rep -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.UnderworldRep); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (Level "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateState.Level); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logger2.LogInfo(val); ProgressionManager.Evaluate(); } if (GUILayout.Button("Reset Progression Rewards (re-test level-ups)", (Il2CppReferenceArray)null)) { data.LastRewardedLevel = 0; Plugin.Logger.LogInfo((object)"[Debug] Progression reward high-water mark reset to 0 — next rep gain re-fires level rewards."); } if (GUILayout.Button("Clear Warrant / Reset Heat", (Il2CppReferenceArray)null)) { ManhuntController.ClearWarrant(busted: false); data.PlayerHeatScore = 0; CrimeSceneManager.Reset(); Plugin.Logger.LogInfo((object)"[Debug] Warrant cleared via ClearWarrant; heat reset, open scenes discarded."); } if (GUILayout.Button("Re-deliver gloves disk", (Il2CppReferenceArray)null)) { data.GlovesDiskDelivered = false; Rewards.DeliverGlovesDiskOnce(); } if (GUILayout.Button($"Toggle Mask (worn={data.IsWearingMask}, disk={data.MaskDiskInstalled})", (Il2CppReferenceArray)null)) { if (!data.MaskDiskInstalled) { data.MaskDiskInstalled = true; Plugin.Logger.LogInfo((object)"[Debug] Mask disk gate force-installed for testing."); } data.IsWearingMask = !data.IsWearingMask; ManualLogSource logger3 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] Mask -> worn="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.IsWearingMask); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (MaskActive="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateState.MaskActive); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logger3.LogInfo(val); } if (GUILayout.Button("Re-deliver mask disk", (Il2CppReferenceArray)null)) { data.MaskDiskDelivered = false; Rewards.DeliverMaskDiskOnce(); } if (GUILayout.Button("Clear Syndicate v-mails (reset thread)", (Il2CppReferenceArray)null)) { Rewards.ClearSyndicateVmails(); } if (GUILayout.Button("Dump recorded prints (our tally)", (Il2CppReferenceArray)null)) { PlayerEvidence.DebugDump(); } if (GUILayout.Button("Force Enforcer Raid (player location)", (Il2CppReferenceArray)null)) { ForceEnforcerRaid(); } if (GUILayout.Button("Spawn Random Contract", (Il2CppReferenceArray)null)) { ContractManager.SpawnRandomContract(); } if (GUILayout.Button("Regenerate Offer Board (L3 jobs)", (Il2CppReferenceArray)null)) { int num2 = ContractManager.RegenerateOfferBoard(); ManualLogSource logger4 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(80, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] RegenerateOfferBoard -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" offer(s). Re-open the Cruncher job app to view."); } logger4.LogInfo(val); } if (GUILayout.Button("Force Target Death", (Il2CppReferenceArray)null)) { ContractManager.ForceFirstTargetDeath(); } if (GUILayout.Button("Cancel Active Hit (small rep cost)", (Il2CppReferenceArray)null)) { ContractManager.CancelActiveContract(); } if (GUILayout.Button("Contracts Paused: " + (data.ContractsPaused ? "YES — off the books" : "no") + " (toggle)", (Il2CppReferenceArray)null)) { PauseLine.DebugToggle(); } if (GUILayout.Button("Resolve Contract Forensics (→ collectable)", (Il2CppReferenceArray)null)) { bool flag2 = ContractManager.DebugForceForensicsOnOldestAwaiting(); ManualLogSource logger5 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(48, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] DebugForceForensicsOnOldestAwaiting -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger5.LogInfo(val); } if (GUILayout.Button("Collect Payable Contracts (settle)", (Il2CppReferenceArray)null)) { int num3 = ContractManager.CollectAllPayable(); ManualLogSource logger6 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] CollectAllPayable -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cr."); } logger6.LogInfo(val); } if (GUILayout.Button("Call In Tip (accelerate forensics)", (Il2CppReferenceArray)null)) { bool flag3 = ContractManager.TipOldestAwaiting(); ManualLogSource logger7 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] TipOldestAwaiting -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger7.LogInfo(val); } if (GUILayout.Button("Add $1000", (Il2CppReferenceArray)null)) { try { GameplayController.Instance.AddMoney(1000, true, "Debug"); Plugin.Logger.LogInfo((object)"[Debug] +1000cr"); } catch (Exception ex) { ManualLogSource logger8 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Debug] AddMoney failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger8.LogError(val2); } } if (GUILayout.Button("Spawn Knife (inventory)", (Il2CppReferenceArray)null)) { SpawnItemIntoInventory("Knife", "KitchenKnife", "CombatKnife", "SwissArmyKnife"); } if (GUILayout.Button("Clean Fingerprints (looking at) [dev]", (Il2CppReferenceArray)null)) { PrintCleaner.CleanLookedAt(); } if (GUILayout.Button("Inspect Prints (looking at) [F8]", (Il2CppReferenceArray)null)) { PrintInspector.InspectLookedAt(); } if (GUILayout.Button("Scan Location (print evidence)", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugScanCurrentLocation(); } if (GUILayout.Button("Dump Active Scenes (to log)", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugDumpScenes(); } if (GUILayout.Button("Discover Oldest Scene (body found)", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugDiscoverOldest(); } if (GUILayout.Button("Force Welfare Raid Now (undiscovered body)", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugForceWelfareRaid(); } if (GUILayout.Button("Force Witness Reports Now", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugForceReportsOldest(); } if (GUILayout.Button("Force Scene Cold Now (forensics)", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugForceColdOldest(); } if (GUILayout.Button("KO Nearest NPC (silence test)", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugKoNearest(); } if (GUILayout.Button("Resolve Warrant Delay Now", (Il2CppReferenceArray)null)) { InvestigationTimer.ResolveNow(); } GUILayout.Space(6f); GUILayout.Label("— F6 News —", (Il2CppReferenceArray)null); if (GUILayout.Button("News: Seed BODY FOUND", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("BodyFound"); } if (GUILayout.Button("News: Seed WELFARE-CHECK body", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("BodyFound", "welfare"); } if (GUILayout.Button("News: Seed RULED SUICIDE", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("SuicideRuled"); } if (GUILayout.Button("News: Seed POLICE BAFFLED (traces)", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("CaseCold", "traces"); } if (GUILayout.Button("News: Seed MASKED SUSPECT", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("MaskedSuspect"); } if (GUILayout.Button("News: Seed RECORDS VANISH", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("RecordsStolen"); } if (GUILayout.Button("News: Seed COLD CASES REOPENED (3)", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("ColdCasesReopened", "3"); } if (GUILayout.Button("News: Seed SUSPECT APPREHENDED", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("Busted"); } if (GUILayout.Button("News: Seed MANHUNT LAPSES", (Il2CppReferenceArray)null)) { NewsEngine.DebugSeed("WarrantExpired"); } GUILayout.BeginHorizontal((Il2CppReferenceArray)null); if (GUILayout.Button("Force WANTED (" + ((NewsEngine.DebugForceStory == "Wanted") ? "on" : "off") + ")", (Il2CppReferenceArray)null)) { NewsEngine.DebugToggleForce("Wanted"); } if (GUILayout.Button("Force CRIME WAVE (" + ((NewsEngine.DebugForceStory == "CrimeWave") ? "on" : "off") + ")", (Il2CppReferenceArray)null)) { NewsEngine.DebugToggleForce("CrimeWave"); } GUILayout.EndHorizontal(); if (GUILayout.Button("News: Force TEST story", (Il2CppReferenceArray)null)) { NewsEngine.DebugForceTest(); } if (GUILayout.Button("News: Regenerate paper now", (Il2CppReferenceArray)null)) { NewsEngine.RegenerateNow(); } if (GUILayout.Button("News: Dump paper state (to log)", (Il2CppReferenceArray)null)) { NewsEngine.DumpState(); } if (GUILayout.Button("News: Clear forced story", (Il2CppReferenceArray)null)) { NewsEngine.ClearForced(); } if (GUILayout.Button("News: Clear event ring", (Il2CppReferenceArray)null)) { NewsEngine.ClearEvents(); } GUILayout.Space(6f); GUILayout.Label("— F7 Mask Notoriety —", (Il2CppReferenceArray)null); GUILayout.Label($"Notoriety: {MaskNotoriety.Value:P0} incidents: {data.MaskedIncidents?.Count ?? 0} (unmerged: {(MaskNotoriety.HasUnmergedIncidents ? "yes" : "no")}) bustPending: {data.MaskedBustPending}", (Il2CppReferenceArray)null); GUILayout.BeginHorizontal((Il2CppReferenceArray)null); if (GUILayout.Button("N = 0", (Il2CppReferenceArray)null)) { data.MaskNotoriety = 0f; } if (GUILayout.Button("N += 0.25", (Il2CppReferenceArray)null)) { data.MaskNotoriety = Mathf.Clamp01(data.MaskNotoriety + 0.25f); } if (GUILayout.Button("N = 1.0", (Il2CppReferenceArray)null)) { data.MaskNotoriety = 1f; } GUILayout.EndHorizontal(); if (GUILayout.Button("Persona: Add fake masked incident (here)", (Il2CppReferenceArray)null)) { MaskNotoriety.DebugAddIncident(); } if (GUILayout.Button("Persona: Dump (to log)", (Il2CppReferenceArray)null)) { MaskNotoriety.DebugDump(); } if (GUILayout.Button("Persona: Force merge-on-slip (unmask)", (Il2CppReferenceArray)null)) { MaskNotoriety.MergeOnSlip("debug slip", viaBust: false); } if (GUILayout.Button("Persona: Force BUSTED while masked (merge + destroy)", (Il2CppReferenceArray)null)) { MaskNotoriety.MergeOnSlip("debug bust", viaBust: true); ConfigEntry maskBustedDestroysMask = SyndicateConfig.MaskBustedDestroysMask; if (maskBustedDestroysMask == null || maskBustedDestroysMask.Value) { MaskNotoriety.DestroyMask(); } } ConfigEntry maskEnforcerSoftStopEnabled = SyndicateConfig.MaskEnforcerSoftStopEnabled; if (GUILayout.Button("Persona: Enforcer soft-stop = " + ((maskEnforcerSoftStopEnabled != null && maskEnforcerSoftStopEnabled.Value) ? "ON" : "off") + " (toggle)", (Il2CppReferenceArray)null) && SyndicateConfig.MaskEnforcerSoftStopEnabled != null) { SyndicateConfig.MaskEnforcerSoftStopEnabled.Value = !SyndicateConfig.MaskEnforcerSoftStopEnabled.Value; } GUILayout.Space(6f); GUILayout.Label("— Manhunt (Phase 5) —", (Il2CppReferenceArray)null); if (GUILayout.Button("Issue Warrant Now (start hunt)", (Il2CppReferenceArray)null)) { ManhuntController.StartHuntNow("a target", "Debug: a warrant has been issued — enforcers are hunting you."); } if (GUILayout.Button("End Warrant (evaded)", (Il2CppReferenceArray)null)) { ManhuntController.ClearWarrant(busted: false); } if (GUILayout.Button("Force Busted (fine + clear)", (Il2CppReferenceArray)null)) { ManhuntController.DebugForceBusted(); } if (GUILayout.Button("KO Me (busted test)", (Il2CppReferenceArray)null)) { try { Player.Instance.TriggerPlayerKO(Vector3.forward, 1f, false); } catch (Exception ex2) { ManualLogSource logger9 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Debug] KO me failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2); } logger9.LogError(val2); } } if (GUILayout.Button("Add Test Murder Fine", (Il2CppReferenceArray)null)) { FineLedger.AddFine("Test Victim", -1, (SyndicateConfig.MurderFineAmount != null) ? SyndicateConfig.MurderFineAmount.Value : 2000, "debug"); } if (GUILayout.Button("Pay Fines Early (discounted)", (Il2CppReferenceArray)null)) { FineLedger.SettleEarly(); } if (GUILayout.Button("Money Probe (-100) [P-L1]", (Il2CppReferenceArray)null)) { try { GameplayController instance2 = GameplayController.Instance; ManualLogSource logger10 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Fines] money before="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance2.money); } logger10.LogInfo(val); instance2.AddMoney(-100, true, "probe"); ManualLogSource logger11 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Fines] money after="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance2.money); } logger11.LogInfo(val); } catch (Exception ex3) { ManualLogSource logger12 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Debug] money probe failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex3); } logger12.LogError(val2); } } if (GUILayout.Button("Force Home Raid (Increment 2)", (Il2CppReferenceArray)null)) { ManhuntController.DebugForceHomeRaid(); } if (GUILayout.Button("Track Held Item as Murder Weapon", (Il2CppReferenceArray)null)) { string text = WeaponConsequences.DebugTrackHeldItem(); ManualLogSource logger13 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] Track held item -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text ?? "nothing held"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger13.LogInfo(val); } if (GUILayout.Button("Print Held Item Name (to log)", (Il2CppReferenceArray)null)) { WeaponConsequences.DebugPrintHeldItem(); } if (GUILayout.Button("Supplies Catalog Probe (to log)", (Il2CppReferenceArray)null)) { SuppliesProbe.Run(); } if (GUILayout.Button("Firearms Asset Probe (fireEvent/fpsItem/shots)", (Il2CppReferenceArray)null)) { FirearmsAssetTuner.Probe(); } if (GUILayout.Button("Supplies: Deliver Pending Now", (Il2CppReferenceArray)null)) { int num4 = SupplyDelivery.DebugDeliverNow(); ManualLogSource logger14 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(54, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] Advanced "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" pending supply delivery(ies) to now."); } logger14.LogInfo(val); } if (GUILayout.Button("Pose Lab: DUMP fps items/clips/rig (to log)", (Il2CppReferenceArray)null)) { PoseLab.Dump(); } GUILayout.Label(PoseLab.StatusLine(), (Il2CppReferenceArray)null); GUILayout.BeginHorizontal((Il2CppReferenceArray)null); if (GUILayout.Button("< Prev donor", (Il2CppReferenceArray)null)) { PoseLab.CycleDonor(-1); } if (GUILayout.Button("Next donor >", (Il2CppReferenceArray)null)) { PoseLab.CycleDonor(1); } if (GUILayout.Button("Toggle aim", (Il2CppReferenceArray)null)) { PoseLab.ToggleRaised(); } GUILayout.EndHorizontal(); if (GUILayout.Button("Pose Lab: LOG current donor + offsets", (Il2CppReferenceArray)null)) { PoseLab.LogCurrent(); } if (GUILayout.Button("Pose Lab: zero the offset", (Il2CppReferenceArray)null)) { PoseLab.ZeroOffset(); } if (GUILayout.Button("Raid Weapon Sweep Now", (Il2CppReferenceArray)null)) { data.RaidWeaponSweepDone = false; WeaponConsequences.RunHomeRaidSweep(); } if (GUILayout.Button("Cruncher Raid Check Now", (Il2CppReferenceArray)null)) { data.CruncherRaidCheckDone = false; CruncherRaidCheck.Run(); } if (GUILayout.Button("Carry Weapon Check Now", (Il2CppReferenceArray)null)) { WeaponConsequences.RunCarryCheckAtBust(); } if (GUILayout.Button("Dump Tracked Weapons (to log)", (Il2CppReferenceArray)null)) { WeaponConsequences.DebugDump(); } if (GUILayout.Button("Dump Enforcer Calls (to log)", (Il2CppReferenceArray)null)) { ManhuntController.DumpEnforcerCalls(); } if (GUILayout.Button("Dump Stakeout Guard Goals [probe]", (Il2CppReferenceArray)null)) { ManhuntController.DebugDumpGuardGoals(); } if (GUILayout.Button("Dump Rooms Here (scoping check)", (Il2CppReferenceArray)null)) { CrimeSceneManager.DebugDumpRooms(); } if (GUILayout.Button("Cancel All Pursuits", (Il2CppReferenceArray)null)) { ManhuntController.CancelAllPursuits(); } GUILayout.Space(6f); GUILayout.Label("— Social Credit (L3) —", (Il2CppReferenceArray)null); if (GUILayout.Button("Buy Standing (1 token + money → social credit)", (Il2CppReferenceArray)null)) { StandingStore.TryBuyStanding(); } if (GUILayout.Button("+1 Hit Token", (Il2CppReferenceArray)null)) { data.HitTokens++; data.HitTokensEarnedTotal++; ManualLogSource logger15 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] +1 hit token (now "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.HitTokens); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", lifetime "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.HitTokensEarnedTotal); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } logger15.LogInfo(val); } if (GUILayout.Button("Reset Hit Tokens (0)", (Il2CppReferenceArray)null)) { data.HitTokens = 0; Plugin.Logger.LogInfo((object)"[Debug] Hit tokens reset to 0 (lifetime earned unchanged)."); } if (GUILayout.Button("SC Probe: +50 credit (log thresholds)", (Il2CppReferenceArray)null)) { SocialCreditProbe(); } if (GUILayout.Button("Echelon Trespass Probe (STAND IN THE ZONE, then click)", (Il2CppReferenceArray)null)) { EchelonProbe(); } if (GUILayout.Button($"Cripple nearest NPC (test limp) [{CrippleController.ActiveCount} active]", (Il2CppReferenceArray)null)) { CrippleNearestNpc(); } if (GUILayout.Button("F3 Camera LOS Probe (which cameras see me)", (Il2CppReferenceArray)null)) { CrimeSceneManager.CameraLosProbe(); } if (GUILayout.Button("Dump InterfaceControls colours (hex) [UI pass]", (Il2CppReferenceArray)null)) { DumpInterfaceColours(); } if (GUILayout.Button($"Residual Heat +band [now {HeatMeterState.Value:P0}, {HeatMeterState.ContributorCount} contrib] [F2]", (Il2CppReferenceArray)null)) { HeatMeterState.Add(1f, -1, "Debug murder"); } if (GUILayout.Button("Clear Residual Heat [F2]", (Il2CppReferenceArray)null)) { HeatMeterState.Clear(); } GUILayout.Label(EvidenceHeist.DebugStatus(), (Il2CppReferenceArray)null); if (GUILayout.Button("Heist: Force 80% Offer + spawn folder", (Il2CppReferenceArray)null)) { EvidenceHeist.DebugForceOffer(); } if (GUILayout.Button("Heist: Force-complete Steal (grab folder)", (Il2CppReferenceArray)null)) { EvidenceHeist.DebugForceSteal(); } if (GUILayout.Button("Heist: Force Dispose (as if thrown in sea)", (Il2CppReferenceArray)null)) { EvidenceHeist.Dispose(); } if (GUILayout.Button("Heist: Force 100% Punishment", (Il2CppReferenceArray)null)) { List residualHeatContributors = data.ResidualHeatContributors; if (residualHeatContributors == null || residualHeatContributors.Count == 0) { HeatMeterState.Add(1f, -1, "debug victim"); } data.ResidualHeat = 1f; EvidenceHeist.Punish(); } if (GUILayout.Button("Dump document/folder presets (find the folder item) [F2]", (Il2CppReferenceArray)null)) { EvidenceHeist.DebugDumpFolderPresets(); } if (GUILayout.Button("Find 'secret envelope'-like presets (scan ALL by display name) [F2]", (Il2CppReferenceArray)null)) { EvidenceHeist.DebugFindDocLikePresets(); } if (GUILayout.Button("Spawn NEXT folder candidate at feet (cycle + test throw) [F2]", (Il2CppReferenceArray)null)) { EvidenceHeist.DebugSpawnNextCandidate(); } if (GUILayout.Button("Heist: Dump enforcer offices + secure back rooms [F2]", (Il2CppReferenceArray)null)) { EvidenceHeist.DebugDumpEnforcerOffices(); } GUILayout.Space(6f); GUILayout.Label("— Cruncher probe —", (Il2CppReferenceArray)null); if (GUILayout.Button("Cruncher Census (log presets → console) [P1]", (Il2CppReferenceArray)null)) { CruncherProbe.Census(); } bool trace = CruncherProbe.Trace; if (GUILayout.Button("Cruncher Lifecycle Trace: " + (trace ? "ON" : "off") + " [P2]", (Il2CppReferenceArray)null)) { CruncherProbe.Trace = !CruncherProbe.Trace; ManualLogSource logger16 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CruncherProbe] lifecycle trace -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(CruncherProbe.Trace ? "ON" : "off"); } logger16.LogInfo(val); } GUILayout.Space(6f); GUILayout.Label("— Safehouse —", (Il2CppReferenceArray)null); bool flag4 = SyndicateConfig.SafehouseBreachEnabled != null && SyndicateConfig.SafehouseBreachEnabled.Value; if (GUILayout.Button("Safehouse Breach: " + (flag4 ? "ON" : "off"), (Il2CppReferenceArray)null) && SyndicateConfig.SafehouseBreachEnabled != null) { SyndicateConfig.SafehouseBreachEnabled.Value = !SyndicateConfig.SafehouseBreachEnabled.Value; ManualLogSource logger17 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Safehouse] Breach-on-entry -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SyndicateConfig.SafehouseBreachEnabled.Value ? "ON" : "off"); } logger17.LogInfo(val); } GUILayout.EndScrollView(); GUILayout.EndArea(); } private static void SocialCreditProbe() { //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown bool flag = default(bool); try { GameplayController instance = GameplayController.Instance; if ((Object)(object)instance == (Object)null) { Plugin.Logger.LogWarning((object)"[SC Probe] GameplayController not ready."); return; } int num = ((instance.socialCreditPerks != null) ? instance.socialCreditPerks.Count : (-1)); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(56, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SC Probe] BEFORE: socialCredit="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.socialCredit); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", level="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.GetCurrentSocialCreditLevel()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", next@="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.GetNextSocialCreditLevelThreshold()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", perks="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); } logger.LogInfo(val); try { float num2 = (((Object)(object)UpgradeEffectController.Instance != (Object)null) ? UpgradeEffectController.Instance.GetUpgradeEffect((Effect)68) : (-1f)); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(92, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SC Probe] echelon access: allowedInEchelons="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((num2 > 0f) ? "CLEARED — you will NOT trespass in echelon zones" : "NOT cleared — echelon zones should trespass-flag you"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); Game.allowEchelons="); BepInExInfoLogInterpolatedStringHandler obj = val; Game instance2 = Game.Instance; ((BepInExLogInterpolatedStringHandler)obj).AppendFormatted((instance2 != null) ? new bool?(instance2.allowEchelons) : ((bool?)null)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Game.disableTrespass="); BepInExInfoLogInterpolatedStringHandler obj2 = val; Game instance3 = Game.Instance; ((BepInExLogInterpolatedStringHandler)obj2).AppendFormatted((instance3 != null) ? new bool?(instance3.disableTrespass) : ((bool?)null)); } logger2.LogInfo(val); } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SC Probe] echelon check failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logger3.LogWarning(val2); } StringBuilder stringBuilder = new StringBuilder("[SC Probe] threshold table "); for (int i = 1; i <= 10; i++) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 2, stringBuilder2); handler.AppendLiteral("L"); handler.AppendFormatted(i); handler.AppendLiteral("="); handler.AppendFormatted(instance.GetSocialCreditThresholdForLevel(i)); handler.AppendLiteral(" "); stringBuilder2.Append(ref handler); } Plugin.Logger.LogInfo((object)stringBuilder.ToString()); instance.AddSocialCredit(50, true, "Syndicate probe"); int num3 = ((instance.socialCreditPerks != null) ? instance.socialCreditPerks.Count : (-1)); ManualLogSource logger4 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(59, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SC Probe] AFTER +50: socialCredit="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.socialCredit); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", level="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.GetCurrentSocialCreditLevel()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", next@="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.GetNextSocialCreditLevelThreshold()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", perks="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num3); } logger4.LogInfo(val); } catch (Exception ex2) { ManualLogSource logger5 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[SC Probe] failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2); } logger5.LogError(val3); } } private static void CrippleNearestNpc() { //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)CityData.Instance == (Object)null || CityData.Instance.citizenDirectory == null) { Plugin.Logger.LogWarning((object)"[Cripple] no player / city directory."); return; } Vector3 position = ((Component)instance).transform.position; Citizen val = null; float num = float.MaxValue; Enumerator enumerator = CityData.Instance.citizenDirectory.GetEnumerator(); while (enumerator.MoveNext()) { Citizen current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !((Actor)current).isDead && !((Actor)current).isPlayer) { float num2; try { num2 = Vector3.Distance(position, ((Component)current).transform.position); } catch { continue; } if (num2 < num) { num = num2; val = current; } } } if ((Object)(object)val == (Object)null) { Plugin.Logger.LogInfo((object)"[Cripple] no citizen found to cripple."); return; } CrippleController.Apply(((Human)val).humanID); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(98, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Cripple] crippled nearest: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Human)val).GetCitizenName()); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (#"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Human)val).humanID); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num, "F1"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m — watch them limp; recovers after [Cripple] DurationSeconds."); } logger.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Cripple] test-cripple failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } logger2.LogError(val3); } } private static void EchelonProbe() { //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Expected O, but got Unknown //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Expected O, but got Unknown //IL_06eb: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Expected O, but got Unknown //IL_0649: Unknown result type (might be due to invalid IL or missing references) //IL_0650: Expected O, but got Unknown //IL_05ab: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown bool isEchelons = default(bool); try { Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { Plugin.Logger.LogWarning((object)"[Echelon Probe] no Player.Instance."); return; } Game instance2 = Game.Instance; UpgradeEffectController instance3 = UpgradeEffectController.Instance; float num = (((Object)(object)instance3 != (Object)null) ? instance3.GetUpgradeEffect((Effect)68) : (-999f)); Plugin.Logger.LogInfo((object)"[Echelon Probe] ===== standing-in-zone dump ====="); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(58, 2, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] Game.allowEchelons="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)instance2 != (Object)null) ? instance2.allowEchelons.ToString() : "null"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Game.disableTrespass="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)instance2 != (Object)null) ? instance2.disableTrespass.ToString() : "null"); } logger.LogInfo(val); ManualLogSource logger2 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(67, 4, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] perk allowedInEchelons="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((num > 0f) ? "CLEARED (will NOT trespass)" : "NOT cleared"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); socialCredit="); BepInExInfoLogInterpolatedStringHandler obj = val; GameplayController instance4 = GameplayController.Instance; ((BepInExLogInterpolatedStringHandler)obj).AppendFormatted((instance4 != null) ? new int?(instance4.socialCredit) : ((int?)null)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", level="); BepInExInfoLogInterpolatedStringHandler obj2 = val; GameplayController instance5 = GameplayController.Instance; ((BepInExLogInterpolatedStringHandler)obj2).AppendFormatted((instance5 != null) ? new int?(instance5.GetCurrentSocialCreditLevel()) : ((int?)null)); } logger2.LogInfo(val); NewRoom currentRoom = ((Actor)instance).currentRoom; if ((Object)(object)currentRoom == (Object)null) { Plugin.Logger.LogInfo((object)"[Echelon Probe] currentRoom = NULL (outdoors/street?)."); } else { ManualLogSource logger3 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] room.featuresStairwell="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(currentRoom.featuresStairwell); } logger3.LogInfo(val); NewGameLocation gameLocation = currentRoom.gameLocation; if ((Object)(object)gameLocation == (Object)null) { Plugin.Logger.LogInfo((object)"[Echelon Probe] room.gameLocation = NULL."); } else { NewFloor floor = gameLocation.floor; ManualLogSource logger4 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(82, 3, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] room.gameLocation.isLobby="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(gameLocation.isLobby); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; gameLocation.floor="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)floor != (Object)null) ? floor.floor.ToString() : "null"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", floor.isEchelons="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)floor != (Object)null) ? floor.isEchelons.ToString() : "null"); } logger4.LogInfo(val); NewBuilding val2 = (((Object)(object)floor != (Object)null) ? floor.building : null); if ((Object)(object)val2 != (Object)null && (SoCustomComparison)(object)val2.preset != (SoCustomComparison)null) { ManualLogSource logger5 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(104, 3, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] BUILDING preset: buildingFeaturesEchelonFloors="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(val2.preset.buildingFeaturesEchelonFloors); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", echelonFloorStart="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(val2.preset.echelonFloorStart); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (you are on floor "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)floor != (Object)null) ? floor.floor.ToString() : "?"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logger5.LogInfo(val); try { StringBuilder stringBuilder = new StringBuilder("[Echelon Probe] this building's floors isEchelons: "); Enumerator enumerator = val2.floors.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder2); handler.AppendLiteral("F"); handler.AppendFormatted(current.Key); handler.AppendLiteral("="); object value; if (!((Object)(object)current.Value != (Object)null)) { value = "?"; } else { isEchelons = current.Value.isEchelons; value = isEchelons.ToString(); } handler.AppendFormatted((string?)value); handler.AppendLiteral(" "); stringBuilder2.Append(ref handler); } Plugin.Logger.LogInfo((object)stringBuilder.ToString()); } catch (Exception ex) { ManualLogSource logger6 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Echelon Probe] floor map failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } logger6.LogWarning(val3); } } else { Plugin.Logger.LogInfo((object)"[Echelon Probe] building/preset not resolvable from this floor."); } NewAddress thisAsAddress = gameLocation.thisAsAddress; if ((Object)(object)thisAsAddress == (Object)null) { Plugin.Logger.LogInfo((object)"[Echelon Probe] room.gameLocation.thisAsAddress = NULL → native echelon-trespass branch is SKIPPED here (commons/corridor is not an addressed space)."); } else { NewFloor floor2 = ((NewGameLocation)thisAsAddress).floor; ManualLogSource logger7 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(80, 2, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] thisAsAddress present; address.floor="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)floor2 != (Object)null) ? floor2.floor.ToString() : "null"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", address.floor.isEchelons="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)floor2 != (Object)null) ? floor2.isEchelons.ToString() : "null"); } logger7.LogInfo(val); } } int num2 = 0; bool flag = false; try { flag = ((Actor)instance).IsTrespassing(currentRoom, ref num2, true); } catch (Exception ex2) { ManualLogSource logger8 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Echelon Probe] IsTrespassing threw: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex2.Message); } logger8.LogWarning(val3); } ManualLogSource logger9 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(74, 2, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] >>> Player.IsTrespassing(currentRoom) = "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", escalation="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" <<<"); } logger9.LogInfo(val); } GameplayController instance6 = GameplayController.Instance; bool flag2 = false; try { flag2 = (Object)(object)currentRoom != (Object)null && (Object)(object)currentRoom.gameLocation != (Object)null && instance.apartmentsOwned != null && instance.apartmentsOwned.Contains(((Il2CppObjectBase)currentRoom.gameLocation).TryCast()); } catch { } ManualLogSource logger10 = Plugin.Logger; val = new BepInExInfoLogInterpolatedStringHandler(71, 3, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Echelon Probe] apartmentsOwned="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((instance.apartmentsOwned != null) ? instance.apartmentsOwned.Count : (-1)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (owns current location="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); guestPasses="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)instance6 != (Object)null && instance6.guestPasses != null) ? instance6.guestPasses.Count : (-1)); } logger10.LogInfo(val); Plugin.Logger.LogInfo((object)"[Echelon Probe] ===== end dump ====="); } catch (Exception ex3) { ManualLogSource logger11 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref isEchelons); if (isEchelons) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Echelon Probe] failed: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex3); } logger11.LogError(val4); } } private static void DumpInterfaceColours() { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) try { InterfaceControls instance = InterfaceControls.Instance; if ((Object)(object)instance == (Object)null) { Plugin.Logger.LogWarning((object)"[UI Probe] InterfaceControls.Instance is null."); return; } Plugin.Logger.LogInfo((object)"[UI Probe] ===== InterfaceControls colours ====="); L("selectionColour", instance.selectionColour); L("nonSelectionColour", instance.nonSelectionColour); L("neutralColour", instance.neutralColour); L("incriminatingColour", instance.incriminatingColour); L("innocentColour", instance.innocentColour); L("markedLinkColour", instance.markedLinkColour); L("messageRed", instance.messageRed); L("messageGreen", instance.messageGreen); L("messageBlue", instance.messageBlue); L("messageYellow", instance.messageYellow); L("messageGrey", instance.messageGrey); L("trespassingEscalationZero", instance.trespassingEscalationZero); L("trespassingEscalationOne", instance.trespassingEscalationOne); L("notificationColorMax", instance.notificationColorMax); L("notificationColorMin", instance.notificationColorMin); L("playerSpeechColour", instance.playerSpeechColour); L("spottedNormalEmission(HDR)", instance.spottedNormalEmission); L("arrowNormalEmission(HDR)", instance.arrowNormalEmission); L("awarenessAlertEmission(HDR)", instance.awarenessAlertEmission); Plugin.Logger.LogInfo((object)"[UI Probe] ===== end ====="); } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[UI Probe] dump failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } logger.LogError(val); } static void L(string name, Color c) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00a6: Unknown result type (might be due to invalid IL or missing references) ManualLogSource logger2 = Plugin.Logger; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(26, 6, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[UI Probe] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(name.PadRight(26)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" #"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ColorUtility.ToHtmlStringRGBA(c)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (rgba "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(c.r, "F2"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(","); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(c.g, "F2"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(","); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(c.b, "F2"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(","); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(c.a, "F2"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } logger2.LogInfo(val2); } } private static string TryDescribeTarget(ContractData c) { try { Human val = null; if ((Object)(object)CityData.Instance == (Object)null || !CityData.Instance.GetHuman(c.TargetId, ref val, false) || (Object)(object)val == (Object)null) { return "target?"; } if (((Actor)val).isDead) { return "DEAD"; } if ((Object)(object)((Actor)val).ai != (Object)null && ((Actor)val).ai.ko) { return "KO"; } return "Alive"; } catch { return "target?"; } } private static void SpawnItemIntoInventory(params string[] presetNames) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown bool flag = default(bool); try { foreach (string text in presetNames) { InteractablePreset interactablePreset = Toolbox.Instance.GetInteractablePreset(text); if (!((SoCustomComparison)(object)interactablePreset == (SoCustomComparison)null)) { interactablePreset.SpawnIntoInventory(); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug] Spawned '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' into inventory."); } logger.LogInfo(val); return; } } ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Debug] No preset found among: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(string.Join(", ", presetNames)); } logger2.LogWarning(val2); } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Debug] Spawn item failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } logger3.LogError(val3); } } private static void ForceEnforcerRaid() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown bool flag = default(bool); try { Player instance = Player.Instance; NewGameLocation val = ((instance != null) ? ((Actor)instance).currentGameLocation : null); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogWarning((object)"[Debug] Raid failed: player location unavailable."); return; } GameplayController.Instance.CallEnforcers(val, false, true, 0f); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(50, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Debug] Enforcers called to "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)val).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (immediate teleport)."); } logger.LogInfo(val2); } catch (Exception ex) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Debug] Raid failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } logger2.LogError(val3); } } } internal static class SuppliesProbe { private static readonly string[] BriefcaseCandidates = new string[6] { "BriefcaseCustom", "Briefcase", "BriefcaseDocuments", "BriefcaseMoney", "BriefcaseBomb", "BriefcaseBombKnownContents" }; private static readonly string[] CatalogCandidates = new string[23] { "tracker", "codebreaker", "doorWedge", "flashbomb", "incapacitator", "opticalCammo", "camera", "fingerptintScanner", "fingerprintScanner", "handcuffs", "food_medicine", "food_foodBar", "food_drink", "lockpick", "LockpickKit", "PrintScanner", "watch", "coin", "newspaper", "item_Small", "CleaningSpray", "cleaningSpray", "cleaningspray" }; private static readonly string[] GroceryCandidates = new string[28] { "Noodles", "noodles", "Donut", "donut", "Cheeseburger", "CheeseburgerInBox", "cheeseburgerinbox", "FishNChips", "FishNChipsInBox", "fishnchipsinbox", "BananaCue", "bananacue", "FairyBread", "fairybread", "BreathMints", "breathmints", "CoughMedicine", "coughmedicine", "ChateauDArc1868", "chateaudarc1868", "CupOfWater", "cupofwater", "Gemsteader", "gemsteader", "MugTea", "mugtea", "MugCoffee", "mugcoffee" }; private static readonly string[] ChloroKeywords = new string[22] { "rag", "cloth", "towel", "hand", "spray", "aerosol", "chem", "solvent", "clean", "bleach", "med", "sedat", "chloro", "gas", "poison", "vial", "bottle", "canister", "mask", "syringe", "drug", "pill" }; private static readonly string[] GunNames = new string[6] { "SemiAutomaticPistol", "SemiAutomaticPistolSilenced", "Revolver", "Shotgun", "BattleRifle", "SniperRifle" }; private static readonly string[] AmmoNames = new string[5] { "21AmmoSmall", "21AmmoLarge", "309Ammo", "BuckshotAmmo", "HuntingAmmo" }; public static void Run() { Log("========== SUPPLIES PROBE (read-only) =========="); ProbeCandidates("BRIEFCASE candidates", BriefcaseCandidates); ProbeCandidates("CATALOG candidates", CatalogCandidates); ProbeCandidates("GROCERY expansion candidates (holdable=Y = addable; value shows the price baseline)", GroceryCandidates); DumpChloroformCandidates(); DumpHoldableUniverse(); DumpAllWeapons(); DumpGunData(); DumpGearNames(); DumpCompanyPrices(); Log("========== SUPPLIES PROBE end =========="); try { Lib.GameMessage.Broadcast("Supplies probe done — see BepInEx log.", (GameMessageType)0, (Icon)21, (Color?)null, 0f); } catch { } } private static void ProbeCandidates(string header, string[] names) { Log("--- " + header + " ---"); try { Toolbox instance = Toolbox.Instance; foreach (string text in names) { InteractablePreset val = null; try { val = instance.GetInteractablePreset(text); } catch { } if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { Log($" {text,-26} : (no preset)"); } else { Log($" {text,-26} : {Describe(val)}"); } } } catch (Exception ex) { Log(" [candidate probe failed: " + ex.Message + "]"); } } private static void DumpChloroformCandidates() { Log("--- #G CHLOROFORM CANDIDATES (holdable presets hinting at a rag/spray/chemical — pick one, set [Combat] ChloroformPreset) ---"); try { Dictionary objectPresetDictionary = Toolbox.Instance.objectPresetDictionary; int num = 0; Enumerator enumerator = objectPresetDictionary.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; InteractablePreset value = current.Value; if ((SoCustomComparison)(object)value == (SoCustomComparison)null) { continue; } bool flag = false; try { flag = (SoCustomComparison)(object)value.fpsItem != (SoCustomComparison)null; } catch { } if (!flag) { continue; } string text = current.Key ?? ""; string text2 = ""; try { text2 = Strings.Get("evidence.names", ((SoCustomComparison)value).presetName, (Casing)0, false, true, false, (Human)null) ?? ""; } catch { } string text3 = (text + " " + text2).ToLowerInvariant(); bool flag2 = false; string[] chloroKeywords = ChloroKeywords; foreach (string value2 in chloroKeywords) { if (text3.Contains(value2)) { flag2 = true; break; } } if (flag2) { num++; Log($" {text,-28} | \"{text2}\" | {Describe(value)}"); } } Log($" [{num} candidate(s). If none fit, scan the full HOLDABLE ITEM UNIVERSE dump below.]"); } catch (Exception ex) { Log(" [chloroform candidate dump failed: " + ex.Message + "]"); } } private static void DumpHoldableUniverse() { Log("--- HOLDABLE ITEM UNIVERSE (preset.fpsItem != null) ---"); try { Dictionary objectPresetDictionary = Toolbox.Instance.objectPresetDictionary; int num = 0; int num2 = 0; Enumerator enumerator = objectPresetDictionary.GetEnumerator(); while (enumerator.MoveNext()) { num++; KeyValuePair current = enumerator.Current; InteractablePreset value = current.Value; if (!((SoCustomComparison)(object)value == (SoCustomComparison)null)) { bool flag = false; try { flag = (SoCustomComparison)(object)value.fpsItem != (SoCustomComparison)null; } catch { } if (flag) { num2++; Log($" {current.Key,-26} : {Describe(value)}"); } } } Log($" [{num2} holdable of {num} total object presets]"); } catch (Exception ex) { Log(" [holdable dump failed: " + ex.Message + "]"); } } private static void DumpAllWeapons() { //IL_0051: 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) Log("--- ALL WEAPONS (Toolbox.allWeapons) ---"); try { List allWeapons = Toolbox.Instance.allWeapons; for (int i = 0; i < allWeapons.Count; i++) { InteractablePreset val = allWeapons[i]; if (!((SoCustomComparison)(object)val == (SoCustomComparison)null)) { string value = "?"; try { value = (((SoCustomComparison)(object)val.weapon != (SoCustomComparison)null) ? ((object)val.weapon.type/*cast due to .constrained prefix*/).ToString() : "-"); } catch { } Log($" {((Object)val).name,-26} : value[{Val(val)}] type={value}"); } } Log($" [{allWeapons.Count} weapons]"); } catch (Exception ex) { Log(" [weapon dump failed: " + ex.Message + "]"); } } private static void DumpGunData() { //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) Log("--- GUN FIRING DATA (#47: type / ammunition / damage / fireDelay / brass / casing / range / shots) ---"); try { Toolbox instance = Toolbox.Instance; string[] gunNames = GunNames; foreach (string text in gunNames) { InteractablePreset val = null; try { val = instance.GetInteractablePreset(text); } catch { } if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { Log($" {text,-28} : (no preset)"); continue; } MurderWeaponPreset weapon = val.weapon; if ((SoCustomComparison)(object)weapon == (SoCustomComparison)null) { Log($" {text,-28} : (not a weapon preset)"); continue; } string text2 = "-"; try { if (weapon.ammunition != null && weapon.ammunition.Count > 0) { List list = new List(); for (int j = 0; j < weapon.ammunition.Count; j++) { InteractablePreset val2 = weapon.ammunition[j]; list.Add(((SoCustomComparison)(object)val2 != (SoCustomComparison)null) ? ((Object)val2).name : "null"); } text2 = string.Join("|", list); } else { text2 = "(empty)"; } } catch (Exception ex) { text2 = "(err:" + ex.Message + ")"; } string value = "?"; string value2 = "?"; string value3 = "?"; string value4 = "?"; string value5 = "?"; string value6 = "?"; string value7 = "?"; try { value = ((object)weapon.type/*cast due to .constrained prefix*/).ToString(); } catch { } try { value2 = $"{weapon.attackDamage.x:0.##}-{weapon.attackDamage.y:0.##}"; } catch { } try { value3 = $"{weapon.fireDelay.x:0.##}-{weapon.fireDelay.y:0.##}"; } catch { } try { value4 = ((object)weapon.ejectBrassSetting/*cast due to .constrained prefix*/).ToString(); } catch { } try { value5 = (((SoCustomComparison)(object)weapon.shellCasing != (SoCustomComparison)null) ? ((Object)weapon.shellCasing).name : "none"); } catch { } try { value6 = $"{weapon.maximumBulletRange:0.#}"; } catch { } try { value7 = weapon.shots.ToString(); } catch { } Log($" {text,-28} : type={value} ammo=[{text2}] dmg={value2} fireDelay={value3} brass={value4} casing={value5} range={value6} shots={value7}"); } Log(" -- ammo presets (resolve + holdable?) --"); gunNames = AmmoNames; foreach (string text3 in gunNames) { InteractablePreset val3 = null; try { val3 = instance.GetInteractablePreset(text3); } catch { } if ((SoCustomComparison)(object)val3 == (SoCustomComparison)null) { Log($" {text3,-26} : (no preset)"); } else { Log($" {text3,-26} : {Describe(val3)}"); } } } catch (Exception ex2) { Log(" [gun-data dump failed: " + ex2.Message + "]"); } } private static void DumpGearNames() { Log("--- GEAR SHOP NAMES (shop label | preset | in-world name the player sees) ---"); try { Toolbox instance = Toolbox.Instance; SupplyEntry[] entries = SupplyCatalog.Entries; foreach (SupplyEntry supplyEntry in entries) { if (supplyEntry.Group != SupplyGroup.Gear) { continue; } string presetName = supplyEntry.PresetName; string text = "?"; try { InteractablePreset interactablePreset = instance.GetInteractablePreset(supplyEntry.PresetName); if ((SoCustomComparison)(object)interactablePreset == (SoCustomComparison)null) { text = "(no preset — special grant)"; } else { presetName = ((SoCustomComparison)interactablePreset).presetName; text = Strings.Get("evidence.names", ((SoCustomComparison)interactablePreset).presetName, (Casing)0, false, true, false, (Human)null); } } catch (Exception ex) { text = "(err: " + ex.Message + ")"; } Log($" {supplyEntry.DisplayName,-18} | {presetName,-28} | {text}"); } } catch (Exception ex2) { Log(" [gear names dump failed: " + ex2.Message + "]"); } } private static void DumpCompanyPrices() { Log("--- COMPANY PRICES (first companies with a non-empty price list) ---"); try { List companyDirectory = CityData.Instance.companyDirectory; int num = 0; for (int i = 0; i < companyDirectory.Count; i++) { if (num >= 3) { break; } Company val = companyDirectory[i]; if (val == null || val.prices == null || val.prices.Count == 0) { continue; } num++; string value = "?"; try { value = val.name ?? "?"; } catch { } Log($" COMPANY '{value}' — {val.prices.Count} priced items:"); int num2 = 0; Enumerator enumerator = val.prices.GetEnumerator(); while (enumerator.MoveNext() && num2 < 40) { num2++; KeyValuePair current = enumerator.Current; string value2 = "?"; try { value2 = (((SoCustomComparison)(object)current.Key != (SoCustomComparison)null) ? ((Object)current.Key).name : "?"); } catch { } Log($" {value2,-26} : {current.Value}cr"); } } if (num == 0) { Log(" [no company had a non-empty prices dict yet]"); } } catch (Exception ex) { Log(" [company price dump failed: " + ex.Message + "]"); } } private static string Describe(InteractablePreset p) { bool flag = false; try { flag = (SoCustomComparison)(object)p.weapon != (SoCustomComparison)null; } catch { } bool flag2 = false; try { flag2 = (SoCustomComparison)(object)p.fpsItem != (SoCustomComparison)null; } catch { } return $"value[{Val(p)}] weapon={(flag ? "Y" : "n")} holdable={(flag2 ? "Y" : "n")}"; } private static string Val(InteractablePreset p) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) try { return $"{p.value.x:0}-{p.value.y:0}"; } catch { return "?"; } } private static void Log(string s) { Plugin.Logger.LogInfo((object)("[SuppliesProbe] " + s)); } } } namespace TheSyndicate.CruncherApp { [HarmonyPatch(typeof(MainMenuController), "Start")] internal static class MainMenuController_Start_BuildSyndicateApp { [HarmonyPostfix] private static void Postfix() { SyndicateAppBuilder.EnsureBuilt(); SuppliesAppBuilder.EnsureBuilt(); GroceriesAppBuilder.EnsureBuilt(); } } [HarmonyPatch(typeof(DesktopIconController), "Setup")] internal static class DesktopIcon_Setup_SyndicateLabel { [HarmonyPostfix] private static void Postfix(DesktopIconController __instance, CruncherAppPreset newApp) { try { if (!((SoCustomComparison)(object)newApp == (SoCustomComparison)null) && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.iconText == (Object)null)) { CruncherAppPreset preset = SyndicateAppBuilder.Preset; CruncherAppPreset preset2 = SuppliesAppBuilder.Preset; CruncherAppPreset preset3 = GroceriesAppBuilder.Preset; if ((SoCustomComparison)(object)preset != (SoCustomComparison)null && ((Il2CppObjectBase)newApp).Pointer == ((Il2CppObjectBase)preset).Pointer) { ((TMP_Text)__instance.iconText).text = "Syndicate"; } else if ((SoCustomComparison)(object)preset2 != (SoCustomComparison)null && ((Il2CppObjectBase)newApp).Pointer == ((Il2CppObjectBase)preset2).Pointer) { ((TMP_Text)__instance.iconText).text = "Supplies"; } else if ((SoCustomComparison)(object)preset3 != (SoCustomComparison)null && ((Il2CppObjectBase)newApp).Pointer == ((Il2CppObjectBase)preset3).Pointer) { ((TMP_Text)__instance.iconText).text = "Groceries"; } } } catch (Exception ex) { Plugin.LogVerbose("[SynApp] icon label set failed: " + ex.Message); } } } [HarmonyPatch(typeof(DesktopApp), "UpdateIcons")] internal static class DesktopApp_UpdateIcons_HomeGate { [HarmonyPrefix] private static void Prefix(DesktopApp __instance) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown try { SyndicateAppBuilder.EnsureBuilt(); SuppliesAppBuilder.EnsureBuilt(); GroceriesAppBuilder.EnsureBuilt(); ComputerController controller = ((CruncherAppContent)__instance).controller; if ((Object)(object)controller == (Object)null || (Object)(object)controller.ic == (Object)null) { Plugin.Logger.LogWarning((object)"[SynApp] Gate: DesktopApp has no controller/ic (unexpected — report timing)"); return; } Interactable interactable = controller.ic.interactable; if (interactable == null || (SoCustomComparison)(object)interactable.preset == (SoCustomComparison)null) { return; } InteractablePreset preset = interactable.preset; List additionalApps = preset.additionalApps; if (additionalApps != null) { NewAddress val = null; NewNode node = interactable.node; if (node != null && (Object)(object)node.gameLocation != (Object)null) { val = node.gameLocation.thisAsAddress; } Player instance = Player.Instance; NewAddress val2 = (((Object)(object)instance != (Object)null) ? ((Human)instance).home : null); bool flag = (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)val2).Pointer; GateApp(additionalApps, SyndicateAppBuilder.Preset, flag, preset, val); bool flag2 = SyndicateConfig.SuppliesEnabled?.Value ?? true; GateApp(additionalApps, SuppliesAppBuilder.Preset, flag && flag2, preset, val); bool flag3 = SyndicateConfig.GroceriesEnabled?.Value ?? true; GateApp(additionalApps, GroceriesAppBuilder.Preset, flag && flag3, preset, val); } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag4 = default(bool); BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(34, 1, ref flag4); if (flag4) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[SynApp] UpdateIcons gate failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } logger.LogError(val3); } } private static void GateApp(List apps, CruncherAppPreset preset, bool wantInstalled, InteractablePreset hostPreset, NewAddress addr) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown if ((SoCustomComparison)(object)preset == (SoCustomComparison)null) { return; } int num = -1; for (int i = 0; i < apps.Count; i++) { CruncherAppPreset val = apps[i]; if ((SoCustomComparison)(object)val != (SoCustomComparison)null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)preset).Pointer) { num = i; break; } } bool flag = default(bool); if (wantInstalled && num < 0) { int num2 = Math.Max(0, apps.Count - 2); apps.Insert(num2, preset); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(50, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SynApp] Gate: '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((SoCustomComparison)preset).presetName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' inserted at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" on '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((SoCustomComparison)hostPreset).presetName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' @ '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)(object)addr != (Object)null) ? ((Object)addr).name : "?"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (count "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(apps.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } logger.LogInfo(val2); } else if (!wantInstalled && num >= 0) { apps.RemoveAt(num); ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(42, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SynApp] Gate: '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((SoCustomComparison)preset).presetName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' removed from '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((SoCustomComparison)hostPreset).presetName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (count "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(apps.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } logger2.LogInfo(val2); } } } internal static class GroceriesAppBuilder { internal const string PresetName = "SyndicateGroceries"; internal static CruncherAppPreset Preset; private static GameObject _holder; private static bool _done; internal static void EnsureBuilt() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (_done) { return; } _done = true; bool flag = default(bool); try { Build(); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(55, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GrocApp] Build complete: preset '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("SyndicateGroceries"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ready (donor=VMail)"); } logger.LogInfo(val); } catch (Exception ex) { Preset = null; ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GrocApp] Build FAILED: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger2.LogError(val2); } } private static void Build() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) CruncherAppPreset val = null; foreach (CruncherAppPreset item in Resources.FindObjectsOfTypeAll()) { if ((SoCustomComparison)(object)item != (SoCustomComparison)null && ((SoCustomComparison)item).presetName == "VMail") { val = item; break; } } if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { throw new Exception("VMail CruncherAppPreset not found (too early?)"); } if (val.appContent == null || val.appContent.Count == 0) { throw new Exception("VMail preset has empty appContent"); } _holder = new GameObject("SyndicateGroceries_CruncherAppHolder"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); GameObject val2 = ((Il2CppObjectBase)Object.Instantiate((Object)(object)val.appContent[0], _holder.transform)).Cast(); ((Object)val2).name = "SyndicateGroceriesContent"; VMailApp component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { throw new Exception("clone carries no VMailApp — wrong donor object?"); } Object.DestroyImmediate((Object)(object)component); val2.AddComponent(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(88, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[GrocApp] Template ready: VMailApp stripped, SuppliesAppContent added, MultiSelect kept="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted((Object)(object)val2.GetComponentInChildren(true) != (Object)null); } logger.LogInfo(val3); CruncherAppPreset obj = ((Il2CppObjectBase)ScriptableObject.CreateInstance(Il2CppType.Of())).Cast(); ((Object)obj).name = "SyndicateGroceries"; ((SoCustomComparison)obj).presetName = "SyndicateGroceries"; ((Object)obj).hideFlags = (HideFlags)32; obj.desktopIcon = FindIconSprite("textdocument") ?? val.desktopIcon; obj.loadBackground = val.loadBackground; obj.loadedBackground = val.loadedBackground; obj.useCursor = val.useCursor; obj.cursorSprite = val.cursorSprite; obj.loadTime = val.loadTime; obj.loadDemand = val.loadDemand; obj.screenLightColourOnLoad = val.screenLightColourOnLoad; obj.screenLightColourOnFinishLoad = val.screenLightColourOnFinishLoad; obj.onStartSound = val.onStartSound; obj.onExitSound = val.onExitSound; obj.onFinishedLoadingSound = val.onFinishedLoadingSound; obj.alwaysInstalled = true; obj.installationConditions = new List(); obj.onlyInAddresses = new List(); List val4 = new List(); val4.Add(val2); obj.appContent = val4; Preset = obj; } private static Sprite FindIconSprite(string spriteName) { try { foreach (CruncherAppPreset item in Resources.FindObjectsOfTypeAll()) { if ((SoCustomComparison)(object)item != (SoCustomComparison)null && (Object)(object)item.desktopIcon != (Object)null && ((Object)item.desktopIcon).name == spriteName) { return item.desktopIcon; } } } catch { } return null; } } internal static class SuppliesAppBuilder { internal const string PresetName = "SyndicateSupplies"; internal static CruncherAppPreset Preset; private static GameObject _holder; private static bool _done; internal static void EnsureBuilt() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (_done) { return; } _done = true; bool flag = default(bool); try { Build(); ManualLogSource logger = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(54, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SupApp] Build complete: preset '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("SyndicateSupplies"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ready (donor=VMail)"); } logger.LogInfo(val); } catch (Exception ex) { Preset = null; ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(23, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SupApp] Build FAILED: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger2.LogError(val2); } } private static void Build() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) CruncherAppPreset val = null; foreach (CruncherAppPreset item in Resources.FindObjectsOfTypeAll()) { if ((SoCustomComparison)(object)item != (SoCustomComparison)null && ((SoCustomComparison)item).presetName == "VMail") { val = item; break; } } if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { throw new Exception("VMail CruncherAppPreset not found (too early?)"); } if (val.appContent == null || val.appContent.Count == 0) { throw new Exception("VMail preset has empty appContent"); } _holder = new GameObject("SyndicateSupplies_CruncherAppHolder"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); GameObject val2 = ((Il2CppObjectBase)Object.Instantiate((Object)(object)val.appContent[0], _holder.transform)).Cast(); ((Object)val2).name = "SyndicateSuppliesContent"; VMailApp component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { throw new Exception("clone carries no VMailApp — wrong donor object?"); } Object.DestroyImmediate((Object)(object)component); val2.AddComponent(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(87, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[SupApp] Template ready: VMailApp stripped, SuppliesAppContent added, MultiSelect kept="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted((Object)(object)val2.GetComponentInChildren(true) != (Object)null); } logger.LogInfo(val3); CruncherAppPreset obj = ((Il2CppObjectBase)ScriptableObject.CreateInstance(Il2CppType.Of())).Cast(); ((Object)obj).name = "SyndicateSupplies"; ((SoCustomComparison)obj).presetName = "SyndicateSupplies"; ((Object)obj).hideFlags = (HideFlags)32; obj.desktopIcon = FindIconSprite("security") ?? val.desktopIcon; obj.loadBackground = val.loadBackground; obj.loadedBackground = val.loadedBackground; obj.useCursor = val.useCursor; obj.cursorSprite = val.cursorSprite; obj.loadTime = val.loadTime; obj.loadDemand = val.loadDemand; obj.screenLightColourOnLoad = val.screenLightColourOnLoad; obj.screenLightColourOnFinishLoad = val.screenLightColourOnFinishLoad; obj.onStartSound = val.onStartSound; obj.onExitSound = val.onExitSound; obj.onFinishedLoadingSound = val.onFinishedLoadingSound; obj.alwaysInstalled = true; obj.installationConditions = new List(); obj.onlyInAddresses = new List(); List val4 = new List(); val4.Add(val2); obj.appContent = val4; Preset = obj; } private static Sprite FindIconSprite(string spriteName) { try { foreach (CruncherAppPreset item in Resources.FindObjectsOfTypeAll()) { if ((SoCustomComparison)(object)item != (SoCustomComparison)null && (Object)(object)item.desktopIcon != (Object)null && ((Object)item.desktopIcon).name == spriteName) { return item.desktopIcon; } } } catch { } return null; } } public class SuppliesAppContent : CruncherAppContent { private const int RowCart = 0; private const int CatalogRowBase = 100; private bool _didSetup; private ComputerOSMultiSelect _list; private IntPtr _listPtr; private TextMeshProUGUI _title; private TextMeshProUGUI _detailMeta; private TextMeshProUGUI _detailBody; private Button _actionButton; private Button _pageForwardButton; private Button _pageBackButton; private Button _scrollUpButton; private Button _scrollDownButton; private int _detailPage = 1; private int _detailPageCount = 1; private int _selectedRow; private int _lastActionFrame = -1; private int _catalogPage; private readonly Dictionary _cart = new Dictionary(); private NewSelection _onNewSelection; private SupplyGroup _group; private int[] _indices = Array.Empty(); private string _appTitle = "SYNDICATE SUPPLY"; private void Awake() { Plugin.Logger.LogInfo((object)"[SupApp] Awake on spawned content"); } private void OnDestroy() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown try { if ((Object)(object)_list != (Object)null && (Delegate)(object)_onNewSelection != (Delegate)null) { ComputerOSMultiSelect list = _list; list.OnNewSelection -= _onNewSelection; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SupApp] OnDestroy unsubscribe: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogWarning(val); } try { if (_listPtr != IntPtr.Zero) { SuppliesListGuard.Unregister(_listPtr); } } catch { } Plugin.Logger.LogInfo((object)"[SupApp] Content destroyed (app exit / desktop switch)"); } public override void Setup(ComputerController cc) { ((CruncherAppContent)this).controller = cc; Plugin.Logger.LogInfo((object)"[SupApp] Setup(ComputerController) fired"); DoSetup(); } public override void OnSetup() { Plugin.Logger.LogInfo((object)"[SupApp] OnSetup fired"); DoSetup(); } public override void PrintButton() { } private void DoSetup() { //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Expected O, but got Unknown //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Expected O, but got Unknown //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown if (_didSetup) { return; } _didSetup = true; bool flag = default(bool); try { _title = FindTmp("AppTitleText"); _detailMeta = FindTmp("VmailDisplay/ToFromText"); _detailBody = FindTmp("VmailDisplay/VmaiDisplay/ElementParent/VmailText"); _list = ((Component)this).GetComponentInChildren(true); if ((Object)(object)_list == (Object)null) { Plugin.Logger.LogError((object)"[SupApp] no ComputerOSMultiSelect in clone — catalog cannot render"); } _group = (((Object)((Component)this).gameObject).name.Contains("Grocer") ? SupplyGroup.Grocery : SupplyGroup.Gear); _appTitle = ((_group == SupplyGroup.Grocery) ? "SYNDICATE GROCERIES" : "SYNDICATE SUPPLY"); _indices = SupplyCatalog.IndicesForGroup(_group); SetTextHard(_title, _appTitle); Il2CppArrayBase