using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using FishNet.Connection; using FishNet.Object; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using Ndrangheta; using Ndrangheta.Compat; using Ndrangheta.Families; using Ndrangheta.Framework; using Ndrangheta.Helper; using Ndrangheta.Messaging; using Ndrangheta.NPCs; using Ndrangheta.Quests; using S1API.Entities; using S1API.Entities.Appearances.AccessoryFields; using S1API.Entities.Appearances.BodyLayerFields; using S1API.Entities.Appearances.CustomizationFields; using S1API.Entities.Appearances.FaceLayerFields; using S1API.Internal.Abstraction; using S1API.Quests; using S1API.Quests.Constants; using S1API.Quests.Identifiers; using S1API.Saveables; using S1API.Vehicles; using ScheduleOne; using ScheduleOne.Audio; using ScheduleOne.AvatarFramework; using ScheduleOne.AvatarFramework.Emotions; using ScheduleOne.AvatarFramework.Equipping; using ScheduleOne.Building; using ScheduleOne.Cartel; using ScheduleOne.Combat; using ScheduleOne.Core.Items.Framework; using ScheduleOne.DevUtilities; using ScheduleOne.Dialogue; using ScheduleOne.Doors; using ScheduleOne.Dragging; using ScheduleOne.Economy; using ScheduleOne.EntityFramework; using ScheduleOne.Equipping; using ScheduleOne.GameTime; using ScheduleOne.Interaction; using ScheduleOne.ItemFramework; using ScheduleOne.Map; using ScheduleOne.Messaging; using ScheduleOne.Money; using ScheduleOne.NPCs; using ScheduleOne.NPCs.Behaviour; using ScheduleOne.NPCs.CharacterClasses; using ScheduleOne.NPCs.Relation; using ScheduleOne.NPCs.Responses; using ScheduleOne.NPCs.Schedules; using ScheduleOne.Noise; using ScheduleOne.ObjectScripts; using ScheduleOne.Persistence; using ScheduleOne.Persistence.Datas; using ScheduleOne.Persistence.Loaders; using ScheduleOne.PlayerScripts; using ScheduleOne.PlayerScripts.Health; using ScheduleOne.Police; using ScheduleOne.Product; using ScheduleOne.Product.Packaging; using ScheduleOne.Property; using ScheduleOne.Quests; using ScheduleOne.Storage; using ScheduleOne.Tiles; using ScheduleOne.Tools; using ScheduleOne.UI; using ScheduleOne.UI.Compass; using ScheduleOne.UI.Phone; using ScheduleOne.UI.Phone.Messages; using ScheduleOne.Vehicles; using ScheduleOne.Vehicles.Modification; using ScheduleOne.Vision; using SteamNetworkLib; using SteamNetworkLib.Events; using SteamNetworkLib.Sync; using Steamworks; using UnityEngine; using UnityEngine.AI; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonOptionalDependencies(new string[] { "SteamNetworkLib" })] [assembly: AssemblyTitle("Ndrangheta")] [assembly: AssemblyDescription("Schedule I MelonLoader Mod")] [assembly: AssemblyCompany("Virtunerd")] [assembly: AssemblyProduct("Ndrangheta")] [assembly: AssemblyCopyright("Copyright (c) Virtunerd 2026")] [assembly: ComVisible(false)] [assembly: Guid("1197b5da-0218-4ec8-8548-e328bd9c8b5f")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: MelonInfo(typeof(NdranghetaMod), "Ndrangheta", "1.0.7", "Virtunerd", null)] [assembly: MelonGame(null, "Schedule I")] [assembly: AssemblyFileVersion("1.0.7")] [assembly: AssemblyInformationalVersion("1.0.7")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.7.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 Ndrangheta { internal static class ImguiCompat { private static GUIStyle _style; internal static void DrawTexture(Rect position, Texture2D image) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Blit(position, image); } internal static void DrawTexture(Rect position, Texture2D image, ScaleMode scaleMode) { //IL_0001: 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) Blit(Fit(position, image, scaleMode), image); } private static Rect Fit(Rect position, Texture2D image, ScaleMode scaleMode) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0018: 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_00cb: 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_0054: Invalid comparison between Unknown and I4 //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_00c2: 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) if ((Object)(object)image == (Object)null || (int)scaleMode == 0) { return position; } float num = ((Texture)image).width; float num2 = ((Texture)image).height; if (num <= 0f || num2 <= 0f) { return position; } float num3 = (((int)scaleMode == 2) ? Mathf.Min(((Rect)(ref position)).width / num, ((Rect)(ref position)).height / num2) : Mathf.Max(((Rect)(ref position)).width / num, ((Rect)(ref position)).height / num2)); float num4 = num * num3; float num5 = num2 * num3; return new Rect(((Rect)(ref position)).x + (((Rect)(ref position)).width - num4) * 0.5f, ((Rect)(ref position)).y + (((Rect)(ref position)).height - num5) * 0.5f, num4, num5); } private static void Blit(Rect position, Texture2D image) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //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_005f: 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_007a: 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_0047: Expected O, but got Unknown if ((Object)(object)image == (Object)null) { return; } Event current = Event.current; if (current != null && (int)current.type == 7) { if (_style == null) { _style = new GUIStyle(); } _style.normal.background = image; Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = Color.white; _style.Draw(position, false, false, false, false); GUI.backgroundColor = backgroundColor; } } } public class NdranghetaMod : MelonMod { private const string MAIN_SCENE_NAME = "Main"; private bool _inMainScene; private bool _npcSpawned; private float _startupTimer; private float _saveDataRefreshTimer; private float _clientPresenceTimer; private bool _netDiagDone; private float _netDiagTimer; private bool _wasAuthority; private bool _demotedToClient; private static bool _netLayerDown; private static bool _s1apiMissing; private static float _staleMarkerSweepAt; private static float _depositoRescueAt; private static float _depositoRescueUntil; private static bool _depositoReloadDetected; private static float _depositoForceDismissAt; private static bool _depositoForcedDismiss; private static float _depositoLastScreenUpAt; private static float _clientLoadStuckSince; private static float _clientLoadDiagAt; private static bool _clientLoadForced; private static float _clientLoadReqAt; private static int _clientLoadReqs; private static float _clientGatesOkSince; private const float CLIENT_LOAD_GATES_GRACE = 3f; private const float CLIENT_LOAD_FORCE_SECONDS = 18f; private static float _chatRestoreAt; private const float CHAT_INTERFACE_RESTORE_GRACE = 1.5f; private const float NPC_SPAWN_DELAY = 3f; private const float SAVE_DATA_REFRESH_INTERVAL = 1f; private bool _clientDonSeenLogged; private bool _clientDonMissingLogged; private bool _clientQuestStarted; private bool _clientMetSent; private bool _clientChatMenuBuilt; private int _clientChatMenuState = -1; private bool _clientConsentShown; private static bool _clientBattAnnounced; private static bool _clientBattAttackSent; private static int _coopPaySeqApplied = -1; private static string _clientDropoffSentFor; private static string _clientShortCashSmsFor; private static bool _s1apiRedirectLogged; private static GUIStyle _s1apiWarnStyle; private void DemoteToClient() { if (_demotedToClient) { return; } _demotedToClient = true; NDLog.Debug("Authority lost (became FishNet client) — switching to client mode, cleaning transient host state."); try { IntroController.ResetForSceneReload(); } catch { } try { TerritoryHandover.ForceReset(); } catch { } try { PizzoJobManager.ResetForSceneReload(); } catch { } try { RankManager.ResetForSceneReload(); } catch { } try { DailyTribute.ResetForSceneReload(); } catch { } try { BattesimoController.ResetForSceneReload(); } catch { } try { ConsentController.ResetForSceneReload(); } catch { } try { LuckyTargetPicker.ResetForSceneReload(); } catch { } try { LuckyBrawlManager.ResetForSceneReload(); } catch { } try { LaBombaManager.ResetForSceneReload(); } catch { } try { RapimentoManager.ResetForSceneReload(); } catch { } try { TortureManager.ResetForSceneReload(); } catch { } try { GangBattleManager.ResetForSceneReload(); } catch { } try { GangWarManager.ResetForSceneReload(); } catch { } try { FearState.ResetForSceneReload(); } catch { } try { FaidaState.ResetForSceneReload(); } catch { } try { CarBombManager.ResetForSceneReload(); } catch { } try { InformantiManager.ResetForSceneReload(); } catch { } try { RealEstateManager.ResetForSceneReload(); } catch { } try { PropVisuals.ResetForSceneReload(); } catch { } try { MobTeleport.ResetForSceneReload(); } catch { } try { MirrorRenderer.ResetForSceneReload(); } catch { } try { VisualMirror.Reset(); } catch { } try { TeleportMirror.ResetForSceneReload(); } catch { } try { FamigliaReskinSync.ResetForSceneReload(); } catch { } try { Sfx.ResetForSceneReload(); } catch { } try { MobFamilyRegistry.ResetAllForSceneReload(); } catch { } try { LuckyCombatDriver.Reset(); } catch { } _staleMarkerSweepAt = Time.time + 12f; ArmDepositoReloadRescue(); _clientLoadStuckSince = 0f; _clientLoadDiagAt = 0f; _clientLoadForced = false; _clientLoadReqAt = 0f; _clientLoadReqs = 0; _clientGatesOkSince = 0f; _chatRestoreAt = 0f; try { ClientActionNet.Reset(); } catch { } _clientDropoffSentFor = null; _clientShortCashSmsFor = null; _coopPaySeqApplied = -1; _clientBattAnnounced = false; _clientBattAttackSent = false; try { BattesimoQuest.ClearInstanceForNext(); } catch { } _clientConsentShown = false; _clientMetSent = false; try { ClientIntroQuest.ResetForSceneReload(); } catch { } _clientChatMenuBuilt = false; _clientChatMenuState = -1; try { DonSalvatoreNPC.ResetForDemotion(); } catch { } try { LuckyNPC.ResetForDemotion(); } catch { } try { NPCRelationData val = NPCManager.GetNPC("Ndrangheta_don_salvatore")?.RelationData; if (val != null && val.Unlocked) { val.Unlocked = false; NDLog.Debug("Don contact re-locked (client demotion)."); } } catch { } _npcSpawned = false; _startupTimer = 0f; } private static int GetCurrentJobCut() { try { PizzoJobManager.ActiveJob current = PizzoJobManager.Current; if (current == null) { return 0; } return (current.Type == PizzoJobManager.JobType.Pizzo || current.Type == PizzoJobManager.JobType.Trasporto) ? current.CutAmount : 0; } catch { return 0; } } private static int GetCurrentJobDropReward() { try { PizzoJobManager.ActiveJob current = PizzoJobManager.Current; if (current == null) { return 0; } return (current.Type == PizzoJobManager.JobType.Trasporto || current.Type == PizzoJobManager.JobType.Carico) ? current.RewardAmount : 0; } catch { return 0; } } private static void GetCurrentStepSync(out string entryText, out string entryPoi) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_00be: Invalid comparison between Unknown and I4 entryText = ""; entryPoi = ""; try { Quest val = null; PizzoJobManager.ActiveJob current = PizzoJobManager.Current; if (current == null) { return; } switch (current.Type) { case PizzoJobManager.JobType.Pizzo: val = (Quest)(object)PizzoQuest.Instance; break; case PizzoJobManager.JobType.Trasporto: val = (Quest)(object)TrasportoQuest.Instance; break; case PizzoJobManager.JobType.Contratto: val = (Quest)(object)ContrattoQuest.Instance; break; case PizzoJobManager.JobType.Carico: val = (Quest)(object)CaricoQuest.Instance; break; } if (val == null) { return; } List questEntries = val.QuestEntries; if (questEntries == null) { return; } for (int i = 0; i < questEntries.Count; i++) { QuestEntry val2 = questEntries[i]; if (val2 == null) { continue; } bool flag = false; try { flag = (int)val2.State == 1; } catch { } if (!flag) { continue; } try { entryText = val2.Title ?? ""; } catch { } try { Vector3 pOIPosition = val2.POIPosition; if (((Vector3)(ref pOIPosition)).sqrMagnitude > 1f) { entryPoi = string.Format(CultureInfo.InvariantCulture, "{0:F1};{1:F1};{2:F1}", pOIPosition.x, pOIPosition.y, pOIPosition.z); } break; } catch { break; } } } catch (Exception ex) { NDLog.DebugWarn("GetCurrentStepSync: " + ex.Message); } } private static string GetCurrentJobCode() { try { PizzoJobManager.Phase currentPhase = PizzoJobManager.CurrentPhase; if (currentPhase == PizzoJobManager.Phase.Idle || currentPhase == PizzoJobManager.Phase.Cooldown) { return ""; } PizzoJobManager.ActiveJob current = PizzoJobManager.Current; if (current == null) { return ""; } return current.Type switch { PizzoJobManager.JobType.Contratto => current.LuckyDispatched ? "lc" : "c", PizzoJobManager.JobType.Pizzo => "p", PizzoJobManager.JobType.Trasporto => "t", PizzoJobManager.JobType.Carico => "ca", _ => "", }; } catch { return ""; } } private static string GetCurrentJobTarget() { try { PizzoJobManager.ActiveJob current = PizzoJobManager.Current; if (current == null) { return ""; } if (current.Type == PizzoJobManager.JobType.Contratto) { return current.LuckyDispatched ? (current.LuckyTargetName ?? "") : (current.ContrattoTargetName ?? ""); } return ""; } catch { return ""; } } private static string GetCurrentJobTargetPos() { //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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) try { PizzoJobManager.ActiveJob current = PizzoJobManager.Current; if (current == null || current.Type != PizzoJobManager.JobType.Contratto) { return ""; } NPC activeContrattoTarget = PizzoJobManager.ActiveContrattoTarget; if ((Object)(object)activeContrattoTarget == (Object)null || (Object)(object)((Component)activeContrattoTarget).transform == (Object)null) { return ""; } Vector3 position = ((Component)activeContrattoTarget).transform.position; return string.Format(CultureInfo.InvariantCulture, "{0:F1};{1:F1};{2:F1}", position.x, position.y, position.z); } catch { return ""; } } private static string GetBossMarkerPos() { //IL_0002: 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_002c: 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_0042: Unknown result type (might be due to invalid IL or missing references) try { Vector3 pos = BossMarkerSync.Pos; if (((Vector3)(ref pos)).sqrMagnitude < 1f) { return ""; } return string.Format(CultureInfo.InvariantCulture, "{0:F1};{1:F1};{2:F1}", pos.x, pos.y, pos.z); } catch { return ""; } } private static string FmtVec(Vector3 p) { //IL_0025: 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_003b: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref p)).sqrMagnitude < 1f) { return ""; } return string.Format(CultureInfo.InvariantCulture, "{0:F1};{1:F1};{2:F1}", p.x, p.y, p.z); } private static Vector3 ParseVec3(string s) { //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) //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_00a0: 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_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 { if (string.IsNullOrEmpty(s)) { return Vector3.zero; } string[] array = s.Split(new char[1] { ';' }); if (array.Length != 3) { return Vector3.zero; } CultureInfo invariantCulture = CultureInfo.InvariantCulture; NumberStyles style = NumberStyles.Float; if (float.TryParse(array[0], style, invariantCulture, out var result) && float.TryParse(array[1], style, invariantCulture, out var result2) && float.TryParse(array[2], style, invariantCulture, out var result3)) { return new Vector3(result, result2, result3); } } catch { } return Vector3.zero; } private void ClientPresenceTick() { //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: 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_023b: 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_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0432: 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_0135: 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_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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) _clientPresenceTimer -= Time.deltaTime; if (_clientPresenceTimer > 0f) { return; } _clientPresenceTimer = 2f; try { RealEstateManager.ClientMirror(QuestNetSync.HasRemoteState ? QuestNetSync.RemoteEstate : 0); } catch { } bool flag = QuestNetSync.HasRemoteState && QuestNetSync.RemoteDonReady; bool flag2 = QuestNetSync.HasRemoteState && QuestNetSync.RemoteRecruited; Vector3 val2; try { NPC nPC = NPCManager.GetNPC("Ndrangheta_don_salvatore"); if ((Object)(object)nPC != (Object)null && (Object)(object)((Component)nPC).transform != (Object)null) { if (!_clientDonSeenLogged) { Vector3 position = ((Component)nPC).transform.position; NDLog.Debug($"[CLIENTDON] host-Don replicated, found at ({position.x:F1},{position.y:F1},{position.z:F1})"); _clientDonSeenLogged = true; } EnsureNpcStationaryOnClient(nPC); Vector3 pos; if (QuestNetSync.RemoteHandover) { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, -2000f, 0f); val2 = ((Component)nPC).transform.position - val; if (((Vector3)(ref val2)).sqrMagnitude > 100f) { ((Component)nPC).transform.position = val; } } else if (DonSalvatoreNPC.ResolveGazeboPosition(out pos)) { val2 = ((Component)nPC).transform.position - pos; if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Component)nPC).transform.position = pos; } } } else if (!_clientDonMissingLogged) { NDLog.Debug("[CLIENTDON] no Don via NPCManager — host-Don NOT replicated to client yet."); _clientDonMissingLogged = true; } } catch { } try { if (!LuckyNetSync.ClientCombatActive) { NPC nPC2 = NPCManager.GetNPC("Ndrangheta_lucky"); if ((Object)(object)nPC2 != (Object)null && (Object)(object)((Component)nPC2).transform != (Object)null) { Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(0f, -2000f, 0f); val2 = ((Component)nPC2).transform.position - val3; if (((Vector3)(ref val2)).sqrMagnitude > 100f) { ((Component)nPC2).transform.position = val3; } } } } catch { } if (flag) { try { DonMessaging.TryUnlock(); } catch { } try { DonMessaging.PatchAsSupplier(); } catch { } try { DonMessaging.SendClientPresenceMessageIfNotYet(); } catch { } } bool flag3 = false; try { flag3 = (Object)(object)PlayerSingleton.Instance != (Object)null; } catch { } if (!flag) { _clientMetSent = false; } if (flag && !flag2) { if (flag3 && DonSalvatoreNPC.ResolveGazeboPosition(out var pos2)) { if (ClientIntroQuest.Instance == null) { ClientIntroQuest.EnsureCreated(pos2); } else { ClientIntroQuest.RefreshPoi(pos2); } TryClientMeetDon(pos2); } } else if (flag2 && ClientIntroQuest.Instance != null) { try { ClientIntroQuest.CompleteAndClear(); } catch { } } if (flag2 && QuestNetSync.RemoteHandover) { try { PersistentDonPresenceQuest.CompleteAndClear(); } catch { } } else if (flag2) { if (flag3) { try { PersistentDonPresenceQuest.EnsureStarted(); } catch { } } try { PersistentDonPresenceQuest.RefreshPoi(); } catch { } if (PersistentDonPresenceQuest.Instance != null && !_clientQuestStarted) { NDLog.Debug("[QUESTSYNC] client started Don-presence quest from host state."); _clientQuestStarted = true; } } if (flag2 && QuestNetSync.HasRemoteState) { string text = QuestNetSync.RemoteJobCode ?? ""; string target = QuestNetSync.RemoteJobTarget ?? ""; bool flag4 = !string.IsNullOrEmpty(text); if (flag4 && flag3 && ClientJobMirrorQuest.Instance == null) { _clientDropoffSentFor = null; _clientShortCashSmsFor = null; Vector3 pos3 = ParseVec3(QuestNetSync.RemoteJobTargetPos); try { ClientJobMirrorQuest.EnsureCreated(text, target, pos3); } catch (Exception ex) { NDLog.DebugWarn("ClientJobMirrorQuest start: " + ex.Message); } } else if (!flag4 && ClientJobMirrorQuest.Instance != null) { try { ClientJobMirrorQuest.CompleteAndClear(); } catch { } } if (flag4 && ClientJobMirrorQuest.Instance != null) { try { if (!DonSalvatoreNPC.ResolveGazeboPosition(out var pos4)) { pos4 = Vector3.zero; } ClientJobMirrorQuest.UpdateStage(QuestNetSync.RemoteJobStage, text, pos4, QuestNetSync.RemoteEntryText, ParseVec3(QuestNetSync.RemoteEntryPoi)); } catch (Exception ex2) { NDLog.DebugWarn("Client stage mirror: " + ex2.Message); } try { ClientJobDropoffTick(text); } catch (Exception ex3) { NDLog.DebugWarn("ClientJobDropoffTick: " + ex3.Message); } } try { ApplyCoopPayout(); } catch (Exception ex4) { NDLog.DebugWarn("ApplyCoopPayout: " + ex4.Message); } try { ClientBattesimoTick(flag3); } catch (Exception ex5) { NDLog.DebugWarn("ClientBattesimoTick: " + ex5.Message); } try { ClientBossMarkerTick(flag3); } catch (Exception ex6) { NDLog.DebugWarn("ClientBossMarkerTick: " + ex6.Message); } try { ClientTortureQuestTick(flag3); } catch (Exception ex7) { NDLog.DebugWarn("ClientTortureQuestTick: " + ex7.Message); } try { ClientConsentTick(); } catch (Exception ex8) { NDLog.DebugWarn("ClientConsentTick: " + ex8.Message); } } try { ClientChatMenuTick(); } catch (Exception ex9) { NDLog.DebugWarn("ClientChatMenuTick: " + ex9.Message); } } private void ClientChatMenuTick() { if (!QuestNetSync.HasRemoteState || !QuestNetSync.RemoteRecruited || !QuestNetSync.RemoteHandover) { _clientChatMenuBuilt = false; _clientChatMenuState = -1; } else if (DonMessaging.ResolveConversation() != null && !_clientChatMenuBuilt && !DonMessaging.IsPhoneOpen()) { LuckyChatController.OpenMainMenu(); _clientChatMenuBuilt = true; _clientChatMenuState = 1; NDLog.Debug("[CLIENTCHAT] Don chat menu built on client (boss)."); } } private void ClientConsentTick() { bool flag = QuestNetSync.HasRemoteState && QuestNetSync.RemoteConsentPending; if (flag && !_clientConsentShown) { DonMessaging.RegisterYesNoButtons("Yes, more contracts.", delegate { ClientActionNet.SendAction("consent", "yes"); }, "Not for me. Ask later.", delegate { ClientActionNet.SendAction("consent", "no"); }); _clientConsentShown = true; NDLog.Debug("[CLIENTCONSENT] Yes/No buttons shown on client."); } else if (!flag && _clientConsentShown) { try { DonMessaging.RemoveYesNoButtons("Yes, more contracts.", "Not for me. Ask later."); } catch { } _clientConsentShown = false; NDLog.Debug("[CLIENTCONSENT] Yes/No buttons cleared on client."); } } private void ClientBossMarkerTick(bool journalReady) { //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_004b: 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_0098: 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) string text = QuestNetSync.RemoteBossLabel ?? ""; bool flag = !string.IsNullOrEmpty(text); Vector3 pos = ParseVec3(QuestNetSync.RemoteBossPos); if (flag && journalReady) { if (ClientBossMarkerQuest.Instance == null) { ClientBossMarkerQuest.EnsureCreated(text, pos, QuestNetSync.RemoteBossKind); } else { ClientBossMarkerQuest.UpdateLabelAndPoi(text, pos, QuestNetSync.RemoteBossKind); } } else if (!flag && ClientBossMarkerQuest.Instance != null) { ClientBossMarkerQuest.CompleteAndClear(); } if (flag && QuestNetSync.RemoteBossKind == 1 && ((Vector3)(ref pos)).sqrMagnitude > 1f) { InformantiManager.ClientShowNote(pos); } else { InformantiManager.ClientHideNote(); } if (flag && QuestNetSync.RemoteBossKind == 2 && ((Vector3)(ref pos)).sqrMagnitude > 1f) { LaBombaManager.ClientShowProp(pos, text != null && text.IndexOf("ARMED", StringComparison.OrdinalIgnoreCase) >= 0); } else { LaBombaManager.ClientHideProp(); } } private void ClientTortureQuestTick(bool journalReady) { bool flag = QuestNetSync.RemoteSceneActive && TerritoryHandover.IsBossForLocalPeer; if (flag && journalReady) { if (TortureManager.ClientSceneText(QuestNetSync.RemoteOpVariant, QuestNetSync.RemoteSceneKoReached, out var title, out var objective)) { if (TortureClientMirrorQuest.Instance == null) { TortureClientMirrorQuest.EnsureCreated(title, objective); } else { TortureClientMirrorQuest.UpdateLabel(objective); } } } else if (!flag && TortureClientMirrorQuest.Instance != null) { TortureClientMirrorQuest.CompleteAndClear(); } } private void TryClientMeetDon(Vector3 donPos) { //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) //IL_0047: 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_0055: 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_0064: 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) if (_clientMetSent) { return; } try { Player local = Player.Local; if (!((Object)(object)local == (Object)null) && !((Object)(object)((Component)local).transform == (Object)null)) { Vector3 position = ((Component)local).transform.position; float num = position.x - donPos.x; float num2 = position.z - donPos.z; float num3 = position.y - donPos.y; float num4 = num * num + num2 * num2 + num3 * num3 * 0.25f; if (!(num4 > 16f) && ClientActionNet.SendAction("metdon", "")) { _clientMetSent = true; NDLog.Debug("[CLIENTINTRO] client reached the Don — sent 'metdon' to host."); } } } catch { } } private void ClientBattesimoTick(bool journalReady) { int remoteBattesimoStage = QuestNetSync.RemoteBattesimoStage; if ((remoteBattesimoStage == 1 || remoteBattesimoStage == 2) && journalReady) { BattesimoQuest.EnsureCreated(); BattesimoQuest.EnsureFirstEntryActive(); if (!_clientBattAnnounced && BattesimoQuest.Instance != null) { _clientBattAnnounced = true; try { DonMessaging.SendDon("Il battesimo — that goes for every one of you. Hit a cop, walk away clean, stay free for an hour. Check the journal."); } catch { } } } if (remoteBattesimoStage >= 2) { BattesimoQuest.OnAttackDetected(); } if (remoteBattesimoStage >= 3 && BattesimoQuest.Instance != null) { BattesimoQuest.OnSurvived(); } if (remoteBattesimoStage == 1 && !_clientBattAttackSent) { try { List officers = PoliceOfficer.Officers; if (officers != null) { for (int i = 0; i < officers.Count; i++) { PoliceOfficer val; try { val = officers[i]; } catch { continue; } if (!((Object)(object)val == (Object)null)) { float num; try { num = (((Object)(object)((NPC)val).Health != (Object)null) ? ((float)((NPC)val).Health.HoursSinceAttackedByPlayer) : (-1f)); } catch { continue; } if (num >= 0f && num < 2f) { if (ClientActionNet.SendAction("battattack", "")) { _clientBattAttackSent = true; NDLog.Debug("[CLIENTACT] battesimo attack detected locally — reported to host."); } break; } } } } return; } catch { return; } } if (remoteBattesimoStage != 1) { _clientBattAttackSent = false; } } private void ApplyCoopPayout() { int remotePaySeq = QuestNetSync.RemotePaySeq; if (_coopPaySeqApplied < 0) { _coopPaySeqApplied = remotePaySeq; } else { if (remotePaySeq <= _coopPaySeqApplied) { return; } _coopPaySeqApplied = remotePaySeq; int remotePayAmount = QuestNetSync.RemotePayAmount; if (remotePayAmount <= 0) { return; } string text = QuestNetSync.RemotePayExclude ?? ""; string localIdString = LuckyNetSync.LocalIdString; if (string.IsNullOrEmpty(text) || !(text == localIdString)) { PayoutHelper.AddCash(remotePayAmount, "Famiglia coop share"); try { ClientActionNet.SendAction("income", $"q|{remotePayAmount}"); } catch { } try { DonMessaging.SendDon($"Your share of the famiglia's take: ${remotePayAmount}."); } catch { } NDLog.Info($"[COOPPAY] client credited ${remotePayAmount} (seq={remotePaySeq})."); } } } private static void EnsureNpcStationaryOnClient(NPC npc) { try { NPCMovement movement = npc.Movement; if ((Object)(object)movement != (Object)null && ((Behaviour)movement).enabled) { try { movement.PauseMovement(); } catch { } try { movement.SetAgentEnabled(false); } catch { } try { ((Behaviour)movement).enabled = false; } catch { } } } catch { } try { NavMeshAgent val = (((Object)(object)((Component)npc).gameObject != (Object)null) ? ((Component)npc).gameObject.GetComponent() : null); if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled) { ((Behaviour)val).enabled = false; } } catch { } try { NPCBehaviour behaviour = npc.Behaviour; if ((Object)(object)behaviour != (Object)null && ((Behaviour)behaviour).enabled) { ((Behaviour)behaviour).enabled = false; } } catch { } } private void ClientJobDropoffTick(string jCode) { //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_00df: 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) int remoteJobStage = QuestNetSync.RemoteJobStage; if (remoteJobStage != 6 || string.Equals(_clientDropoffSentFor, jCode, StringComparison.Ordinal)) { return; } Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null) { return; } Vector3 pos; if (QuestNetSync.RemoteHandover) { if (!DonSalvatoreNPC.ResolveGazeboPosition(out pos)) { return; } } else { NPC nPC = NPCManager.GetNPC("Ndrangheta_don_salvatore"); if ((Object)(object)nPC != (Object)null && (Object)(object)((Component)nPC).transform != (Object)null) { pos = ((Component)nPC).transform.position; } else if (!DonSalvatoreNPC.ResolveGazeboPosition(out pos)) { return; } } Vector3 val = ((Component)local).transform.position - pos; val.y = 0f; float num = 4.5f; if (!(((Vector3)(ref val)).sqrMagnitude > num * num) && ClientActionNet.SendAction("dropoff", jCode)) { _clientDropoffSentFor = jCode; NDLog.Debug($"[CLIENTACT] contratto report-to-Don sent for job '{jCode}' (stage={remoteJobStage})."); } } private static bool IsAssemblyLoaded(string simpleName) { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { try { if (string.Equals(assemblies[i].GetName().Name, simpleName, StringComparison.OrdinalIgnoreCase)) { return true; } } catch { } } } catch { } return false; } private static Assembly ResolveS1ApiAny(object sender, ResolveEventArgs args) { try { string name = new AssemblyName(args.Name).Name; if (!string.Equals(name, "S1API", StringComparison.OrdinalIgnoreCase)) { return null; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { try { if (!string.Equals(assemblies[i].GetName().Name, "S1API", StringComparison.OrdinalIgnoreCase)) { continue; } if (!_s1apiRedirectLogged) { _s1apiRedirectLogged = true; NDLog.Warn("S1API binding redirected: requested '" + args.Name + "' -> loaded '" + assemblies[i].GetName().FullName + "' (installed S1API has a different assembly version — tolerated, same product version)."); } return assemblies[i]; } catch { } } } catch { } return null; } public override void OnInitializeMelon() { try { AppDomain.CurrentDomain.AssemblyResolve += ResolveS1ApiAny; } catch { } ModConfig.Initialize(); NDLog.DebugLogging = ModConfig.DebugLogging; if (!IsAssemblyLoaded("S1API")) { _s1apiMissing = true; NDLog.Error("S1API NOT found — TheMob requires S1API (plugin 'S1APILoader' + 'S1API.Il2Cpp.MelonLoader.dll'). Mod is DISABLED (no world content, no quests). Please install S1API and restart the game."); return; } try { MobFamilyRegistry.Register((MobFamily)(object)new NdranghetaFamily()); } catch (Exception ex) { NDLog.Warn("[MOB] family registration failed: " + ex.Message); } NDLog.Info("v" + ((MelonBase)this).Info.Version + " initializing."); try { LuckyNetSync.Initialize(); } catch (Exception ex2) { _netLayerDown = true; NDLog.Warn("Net layer unavailable (SteamNetworkLib missing?) — running solo. " + ex2.GetType().Name); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (_s1apiMissing) { return; } _inMainScene = string.Equals(sceneName, "Main", StringComparison.Ordinal); if (!_inMainScene) { _npcSpawned = false; _startupTimer = 0f; _saveDataRefreshTimer = 0f; _wasAuthority = false; _demotedToClient = false; IntroController.ResetForSceneReload(); try { TerritoryHandover.ForceReset(); } catch { } PizzoJobManager.ResetForSceneReload(); RankManager.ResetForSceneReload(); DailyTribute.ResetForSceneReload(); BattesimoController.ResetForSceneReload(); ConsentController.ResetForSceneReload(); LuckyBrawlManager.ResetForSceneReload(); LaBombaManager.ResetForSceneReload(); RapimentoManager.ResetForSceneReload(); TortureManager.ResetForSceneReload(); try { GangBattleManager.ResetForSceneReload(); } catch { } try { GangWarManager.ResetForSceneReload(); } catch { } try { FearState.ResetForSceneReload(); } catch { } try { FaidaState.ResetForSceneReload(); } catch { } CarBombManager.ResetForSceneReload(); InformantiManager.ResetForSceneReload(); RealEstateManager.ResetForSceneReload(); LuckyTargetPicker.ResetForSceneReload(); PropVisuals.ResetForSceneReload(); try { MobTeleport.ResetForSceneReload(); } catch { } try { MirrorRenderer.ResetForSceneReload(); } catch { } try { VisualMirror.Reset(); } catch { } try { TeleportMirror.ResetForSceneReload(); } catch { } try { FamigliaReskinSync.ResetForSceneReload(); } catch { } try { Sfx.ResetForSceneReload(); } catch { } try { MobFamilyRegistry.ResetAllForSceneReload(); } catch { } try { LuckyCombatDriver.Reset(); } catch { } _staleMarkerSweepAt = 0f; ClientActionNet.Reset(); _clientDropoffSentFor = null; _clientShortCashSmsFor = null; _coopPaySeqApplied = -1; _clientBattAnnounced = false; _clientBattAttackSent = false; try { BattesimoQuest.ClearInstanceForNext(); } catch { } _clientConsentShown = false; _clientMetSent = false; try { ClientIntroQuest.ResetForSceneReload(); } catch { } _clientChatMenuBuilt = false; _clientChatMenuState = -1; } else { NDLog.Debug("Entered Main scene — waiting for spawn delay."); _staleMarkerSweepAt = Time.time + 12f; ArmDepositoReloadRescue(); } } private static void ArmDepositoReloadRescue() { bool flag = _depositoRescueUntil > Time.time; _depositoRescueAt = Time.time + 1f; _depositoRescueUntil = Time.time + 30f; _depositoLastScreenUpAt = Time.time; if (!flag) { _depositoReloadDetected = false; _depositoForceDismissAt = 0f; _depositoForcedDismiss = false; } } public override void OnGUI() { if (_s1apiMissing) { DrawS1ApiMissingBanner(); return; } try { TortureManager.OnGUI(); } catch { } try { GangBattleManager.OnGUI(); } catch { } try { GangWarManager.OnGUI(); } catch { } try { InformantiManager.OnGUI(); } catch { } } private static void DrawS1ApiMissingBanner() { //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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00cf: 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_010b: 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_001b: 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: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) try { if (_s1apiWarnStyle == null) { _s1apiWarnStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 15, fontStyle = (FontStyle)1, wordWrap = true }; _s1apiWarnStyle.normal.textColor = Color.white; } float num = Mathf.Min(740f, (float)Screen.width - 20f); float num2 = 64f; float num3 = ((float)Screen.width - num) * 0.5f; float num4 = 12f; Color backgroundColor = GUI.backgroundColor; Color color = GUI.color; GUI.backgroundColor = new Color(0.55f, 0.05f, 0.05f, 0.92f); GUI.Box(new Rect(num3, num4, num, num2), GUIContent.none); GUI.color = Color.white; GUI.Label(new Rect(num3 + 12f, num4 + 6f, num - 24f, num2 - 12f), "TheMob (Ndrangheta) is DISABLED — S1API not found.\nInstall the S1APILoader plugin + S1API.Il2Cpp.MelonLoader.dll (v3.0.5) and restart the game.", _s1apiWarnStyle); GUI.backgroundColor = backgroundColor; GUI.color = color; } catch { } } public override void OnUpdate() { //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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_01ff: Unknown result type (might be due to invalid IL or missing references) if (_s1apiMissing) { return; } if (!_netLayerDown) { try { LuckyNetSync.Tick(); QuestNetSync.Tick(); } catch (Exception ex) { _netLayerDown = true; NDLog.Warn("Net layer unavailable (SteamNetworkLib missing?) — running solo. " + ex.GetType().Name); } } if (!_inMainScene) { return; } if (!_netDiagDone) { _netDiagTimer += Time.deltaTime; if (_netDiagTimer >= 5f) { _netDiagDone = true; SessionGate.LogDiagnostics(); } } bool isAuthority = SessionGate.IsAuthority; if (isAuthority != _wasAuthority) { NDLog.Debug($"[AUTH] {_wasAuthority}->{isAuthority} {SessionGate.Describe()}"); } if (_wasAuthority && !isAuthority) { DemoteToClient(); } _wasAuthority = isAuthority; if (!_netLayerDown) { if (isAuthority) { GetCurrentStepSync(out var entryText, out var entryPoi); QuestNetSync.PublishState(RecruitmentState.WelcomeSmsSent || RecruitmentState.Recruited, RecruitmentState.Recruited, RecruitmentState.HasMetDon, GetCurrentJobCode(), GetCurrentJobTarget(), GetCurrentJobTargetPos(), (int)PizzoJobManager.CurrentPhase, GetCurrentJobCut(), GetCurrentJobDropReward(), entryText, entryPoi, PizzoJobManager.CoopPaySeq, PizzoJobManager.CoopPayAmount, PizzoJobManager.CoopPayExclude, (int)BattesimoController.CurrentStage, TerritoryHandover.HandoverActive, RealEstateManager.SyncCode, FearState.Points, FaidaState.BenziePoints, BossMarkerSync.Label, GetBossMarkerPos(), RapimentoManager.ActiveVanGuid ?? "", ConsentController.QuestionPending, BossMarkerSync.Kind, RealEstateManager.GuardPatrolSyncCode, BossMarkerSync.RaidSeconds, IncomeTracker.QuestIncome, IncomeTracker.OtherIncome, RapimentoManager.IsRecruiting, RapimentoManager.OpDropActive, FmtVec(RapimentoManager.OpDropPos), RapimentoManager.OpDropReachInt, RapimentoManager.CurrentVariant, TortureManager.SceneActive, FmtVec(TortureManager.ScenePlayerPos), FmtVec(TortureManager.SceneReturnPos), TortureManager.SceneReturnYawInt, TortureManager.SceneBeginSeq, TortureManager.SceneEndSeq, VisualMirror.Encode(), TeleportMirror.Encode(), LuckyBrawlManager.BrawlPhase, FamigliaReskinSync.Encode(), TortureManager.SceneTimeLeftInt, TortureManager.SceneKoReached, Sfx.MirrorSeq, Sfx.MirrorName, (int)(Sfx.MirrorVol * 100f), Sfx.LoopName, RapimentoManager.ReleasedVictimSeq, RapimentoManager.ReleasedVictimObjId, FaidaState.TriadPoints); } try { TeleportMirror.TickLocalApply(); } catch (Exception ex2) { NDLog.DebugWarn("[TPMIRROR] host apply: " + ex2.Message); } ClientActionNet.TickHost(Time.deltaTime); try { if (isAuthority) { IncomeTracker.ClearDisplayOverride(); } else { IncomeTracker.SetDisplayOverride(QuestNetSync.RemoteQuestIncome, QuestNetSync.RemoteOtherIncome); } } catch { } } if (_staleMarkerSweepAt > 0f && Time.time >= _staleMarkerSweepAt) { _staleMarkerSweepAt = 0f; try { LuckyBrawlManager.SweepStaleMarker(); } catch { } try { LaBombaManager.SweepStaleMarker(); } catch { } try { RapimentoManager.SweepStaleMarker(); } catch { } try { GangBattleManager.SweepStaleMarker(); } catch { } try { GangWarManager.SweepStaleMarker(); } catch { } try { CarBombManager.SweepStaleMarker(); } catch { } try { InformantiManager.SweepStaleMarker(); } catch { } try { RealEstateManager.SweepStaleMarker(); } catch { } try { KidnapSackItem.EnsureRegistered(); } catch { } } if (!isAuthority && _depositoRescueUntil > 0f && Time.time < _depositoRescueUntil) { bool flag = GameCompat.IsLoadingScreenOpen(); if (flag) { _depositoLastScreenUpAt = Time.time; } if ((flag || Time.time - _depositoLastScreenUpAt < 5f) && Time.time >= _depositoRescueAt) { _depositoRescueAt = Time.time + 0.5f; bool flag2 = false; try { flag2 = LagerRoom.RescuePlayerIfInside(); } catch { } if (flag2) { _depositoReloadDetected = true; } } if (_depositoReloadDetected && flag) { if (_depositoForceDismissAt <= 0f) { _depositoForceDismissAt = Time.time + 4f; } else if (Time.time >= _depositoForceDismissAt) { bool flag3 = GameCompat.ForceCloseLoadingScreen(); if (!_depositoForcedDismiss) { _depositoForcedDismiss = true; NDLog.Debug("[LAGER] client stuck on orphaned join-loading-screen after deposito-reload — force-closing it (" + (flag3 ? "ok" : "still open") + ")."); } } } else if (!flag) { _depositoForceDismissAt = 0f; } if (_depositoReloadDetected && !flag) { Player local = Player.Local; if ((Object)(object)local != (Object)null && (Object)(object)((Component)local).transform != (Object)null && ((Component)local).transform.position.y > -7f) { _depositoRescueUntil = 0f; _depositoForceDismissAt = 0f; _depositoForcedDismiss = false; } } } else if (_depositoRescueUntil > 0f && (isAuthority || Time.time >= _depositoRescueUntil)) { _depositoRescueUntil = 0f; _depositoForceDismissAt = 0f; _depositoForcedDismiss = false; } if (!isAuthority) { bool flag4 = false; bool flag5 = false; try { flag4 = GameCompat.IsGameLoading(); } catch { } try { flag5 = GameCompat.IsLoadingScreenOpen(); } catch { } Player val = null; try { val = Player.Local; } catch { } if (flag4 && flag5 && (Object)(object)val != (Object)null) { if (_clientLoadStuckSince <= 0f) { _clientLoadStuckSince = Time.time; _clientLoadDiagAt = 0f; _clientLoadReqAt = 0f; _clientLoadReqs = 0; _clientGatesOkSince = 0f; } float num = Time.time - _clientLoadStuckSince; if (Time.time >= _clientLoadDiagAt) { _clientLoadDiagAt = Time.time + 3f; try { GameCompat.LogClientLoadGateState(num); } catch { } } bool flag6 = false; try { flag6 = GameCompat.ClientLoadGatesSatisfied(); } catch { } if (flag6) { if (_clientGatesOkSince <= 0f) { _clientGatesOkSince = Time.time; } } else { _clientGatesOkSince = 0f; if (num >= 5f && _clientLoadReqs < 3 && Time.time >= _clientLoadReqAt) { _clientLoadReqAt = Time.time + 4f; _clientLoadReqs++; bool flag7 = false; try { flag7 = GameCompat.TryReRequestPlayerData(); } catch { } NDLog.Debug($"[CLIENTLOAD] gates not satisfied at {num:0}s — re-requesting player data (attempt {_clientLoadReqs}/3, sent={flag7})."); } } bool flag8 = _clientGatesOkSince > 0f && Time.time - _clientGatesOkSince >= 3f; bool flag9 = num >= 18f; if (flag8 || flag9) { bool flag10 = false; try { flag10 = GameCompat.ForceCloseLoadingScreen(); } catch { } if (!_clientLoadForced) { _clientLoadForced = true; NDLog.Debug(string.Format("[CLIENTLOAD] load gates satisfied but screen stuck (dead LoadAsClient coroutine) — forcing load complete at {0:0}s ({1}; reason={2}).", num, flag10 ? "closed" : "still open", flag8 ? "gates+grace" : "timeout")); } } } else { _clientLoadStuckSince = 0f; _clientLoadDiagAt = 0f; _clientLoadForced = false; _clientLoadReqAt = 0f; _clientLoadReqs = 0; _clientGatesOkSince = 0f; } } try { if (TerritoryHandover.IsBossForLocalPeer && !_netLayerDown && DonMessaging.NeedsChoiceInterfaceRestore()) { if (_chatRestoreAt <= 0f) { _chatRestoreAt = Time.time + 1.5f; } else if (Time.time >= _chatRestoreAt) { _chatRestoreAt = 0f; NDLog.Debug("[CHAT] interface was button-less — restoring main menu (FIX-151 watchdog)."); LuckyChatController.OpenMainMenu(); } } else { _chatRestoreAt = 0f; } } catch (Exception ex3) { NDLog.DebugWarn("[CHAT] interface watchdog: " + ex3.Message); } if (_demotedToClient || !isAuthority) { if (_netLayerDown) { return; } ClientPresenceTick(); try { bool villaOwned = QuestNetSync.HasRemoteState && (QuestNetSync.RemoteEstate & 8) != 0; RealEstateManager.ClientGuardTick(villaOwned, QuestNetSync.HasRemoteState ? QuestNetSync.RemoteGuardPatrol : 0); } catch { } try { RapimentoManager.Tick(Time.deltaTime); } catch (Exception ex4) { NDLog.DebugWarn("[CLIENT] RapimentoManager.Tick: " + ex4.Message); } try { CarBombManager.Tick(Time.deltaTime); } catch (Exception ex5) { NDLog.DebugWarn("[CLIENT] CarBombManager.Tick: " + ex5.Message); } try { LaBombaManager.ClientTickBeep(); } catch (Exception ex6) { NDLog.DebugWarn("[CLIENT] LaBombaManager.ClientTickBeep: " + ex6.Message); } try { if (QuestNetSync.HasRemoteState) { Sfx.ApplyMirror(QuestNetSync.RemoteSfxSeq, QuestNetSync.RemoteSfxName, (float)QuestNetSync.RemoteSfxVol100 / 100f, QuestNetSync.RemoteSfxLoop); } } catch (Exception ex7) { NDLog.DebugWarn("[CLIENT] Sfx.ApplyMirror: " + ex7.Message); } try { if (QuestNetSync.HasRemoteState) { RapimentoManager.ClientApplyRelease(QuestNetSync.RemoteReleasedSeq, QuestNetSync.RemoteReleasedObjId); } } catch (Exception ex8) { NDLog.DebugWarn("[CLIENT] RapimentoManager.ClientApplyRelease: " + ex8.Message); } try { LuckyNetSync.ClientTick(Time.deltaTime); } catch (Exception ex9) { NDLog.DebugWarn("[CLIENT] LuckyNetSync.ClientTick: " + ex9.Message); } try { MirrorRenderer.RenderVisuals(VisualMirror.Decode(QuestNetSync.RemoteVisualsRaw)); } catch (Exception ex10) { NDLog.DebugWarn("[CLIENT] MirrorRenderer.RenderVisuals: " + ex10.Message); } try { MirrorRenderer.RenderTeleports(TeleportMirror.Decode(QuestNetSync.RemoteTeleportsRaw)); } catch (Exception ex11) { NDLog.DebugWarn("[CLIENT] MirrorRenderer.RenderTeleports: " + ex11.Message); } try { FamigliaReskinSync.ClientApply(QuestNetSync.RemoteFamigliaGoons); } catch (Exception ex12) { NDLog.DebugWarn("[CLIENT] FamigliaReskinSync: " + ex12.Message); } try { LuckyChatController.ClientBrawlMenuTick(); } catch (Exception ex13) { NDLog.DebugWarn("[CLIENT] ClientBrawlMenuTick: " + ex13.Message); } try { RapimentoManager.ClientApplyVanColor(); } catch (Exception ex14) { NDLog.DebugWarn("[CLIENT] ClientApplyVanColor: " + ex14.Message); } try { TortureManager.ClientGuardTick(); return; } catch (Exception ex15) { NDLog.DebugWarn("[CLIENT] TortureManager.ClientGuardTick: " + ex15.Message); return; } } try { MobFamilyRegistry.EnsureDefaultActive(); } catch { } if (!_npcSpawned) { _startupTimer += Time.deltaTime; if (!(_startupTimer < 3f)) { TrySpawnDon(); } return; } IntroController.Tick(Time.deltaTime); PizzoJobManager.Tick(Time.deltaTime); IntroQuest.RefreshPoi(); if (RecruitmentState.Recruited) { if (TerritoryHandover.HandoverActive) { PersistentDonPresenceQuest.CompleteAndClear(); } else { PersistentDonPresenceQuest.EnsureStarted(); PersistentDonPresenceQuest.RefreshPoi(); } } if (!ProductRegistry.IsRegistered) { ProductRegistry.TryRegister(); } DailyTribute.Tick(Time.deltaTime); BattesimoController.Tick(Time.deltaTime); ConsentController.Tick(Time.deltaTime); LuckyCombatDriver.Tick(Time.deltaTime); LuckyBrawlManager.Tick(Time.deltaTime); LaBombaManager.Tick(Time.deltaTime); InformantiManager.Tick(Time.deltaTime); RapimentoManager.Tick(Time.deltaTime); TortureManager.Tick(Time.deltaTime); GangBattleManager.Tick(Time.deltaTime); GangWarManager.Tick(Time.deltaTime); CarBombManager.Tick(Time.deltaTime); RealEstateManager.Tick(Time.deltaTime); LagerGrid.Tick(Time.deltaTime); LuckyNPC.TickWatchdog(); DonSalvatoreNPC.TickWatchdog(); GuardNPC.TickHiddenWatchdog(); HeartbeatSave(); } private void HeartbeatSave() { _saveDataRefreshTimer -= Time.deltaTime; if (_saveDataRefreshTimer <= 0f) { _saveDataRefreshTimer = 1f; NdranghetaSaveData.Instance?.PushNow(); } } private void TrySpawnDon() { try { DonSalvatoreNPC instance = DonSalvatoreNPC.Instance; if (instance != null) { GameObject val = null; try { val = ((NPC)instance).gameObject; } catch { } if ((Object)(object)val != (Object)null) { _npcSpawned = true; EnsureVillaGuardsLoaded(); return; } } try { NPC nPC = NPCManager.GetNPC("Ndrangheta_don_salvatore"); if ((Object)(object)nPC != (Object)null && (Object)(object)((Component)nPC).gameObject != (Object)null) { _npcSpawned = true; EnsureVillaGuardsLoaded(); return; } } catch { } NDLog.Debug("[SPAWN] creating Don/Lucky now — " + SessionGate.Describe()); try { if (SessionGate.IsAuthority && LuckyNPC.Instance == null && (Object)(object)NPCManager.GetNPC("Ndrangheta_lucky") == (Object)null) { new LuckyNPC(); NDLog.Debug($"LuckyNPC instantiated (visible={true})."); } } catch (Exception ex) { NDLog.Warn("LuckyNPC spawn: " + ex.Message); } new DonSalvatoreNPC(); _npcSpawned = true; NDLog.Debug("DonSalvatoreNPC instantiated."); EnsureVillaGuardsLoaded(); } catch (Exception ex2) { NDLog.Warn("DonSalvatoreNPC spawn failed (will retry): " + ex2.Message); _startupTimer = 0f; } } private static void EnsureVillaGuardsLoaded() { try { GuardNPC.CreateAll(); } catch (Exception ex) { NDLog.Warn("GuardNPC.CreateAll: " + ex.Message); } } } public sealed class NdranghetaSaveData : Saveable { [SaveableField("Ndrangheta_state")] private NdranghetaSnapshot _data = new NdranghetaSnapshot(); private static string _cachedGridItems = ""; public static NdranghetaSaveData Instance { get; private set; } public NdranghetaSaveData() { try { _data = CaptureFromLiveState(); } catch { } Instance = this; } public void PushNow(bool refreshGrids = false) { try { _data = CaptureFromLiveState(refreshGrids); } catch (Exception ex) { NDLog.DebugWarn("PushNow: " + ex.Message); } } protected override void OnLoaded() { try { NDLog.Debug($"SaveData OnLoaded: recruited={_data?.Recruited} count={_data?.PizzoCompletedCount} phase={_data?.JobPhase}"); ApplyToLiveState(_data ?? new NdranghetaSnapshot()); } catch (Exception ex) { NDLog.Warn("OnLoaded apply failed: " + ex.Message); } } protected override void OnSaved() { try { _data = CaptureFromLiveState(); } catch { } } private static string GridItemsCapture(bool refresh) { if (refresh) { try { _cachedGridItems = GridPersistence.CaptureAllString(); } catch (Exception ex) { NDLog.DebugWarn("GridItems capture: " + ex.Message); } } return _cachedGridItems; } public static NdranghetaSnapshot CaptureFromLiveState(bool refreshGrids = true) { PizzoJobManager.JobSnapshot jobSnapshot = PizzoJobManager.CaptureSnapshot(); return new NdranghetaSnapshot { WelcomeSmsSent = RecruitmentState.WelcomeSmsSent, HasMetDon = RecruitmentState.HasMetDon, Recruited = RecruitmentState.Recruited, CurrentRank = (int)RankManager.CurrentRank, LastTributeDay = DailyTribute.LastTributeDay, BattesimoStage = BattesimoController.SaveStage, BattesimoAttackDay = BattesimoController.SaveAttackDay, BattesimoAttackTime = BattesimoController.SaveAttackTime, ConsentState = (int)ConsentController.CurrentState, LastConsentAskDay = ConsentController.LastAskDay, PizzoCompletedCount = jobSnapshot.CompletedCount, JobPhase = jobSnapshot.Phase, JobType = jobSnapshot.JobType, JobCooldownRemaining = jobSnapshot.CooldownRemaining, JobCashSpawned = jobSnapshot.CashSpawned, JobTargetName = jobSnapshot.TargetName, JobDropBName = jobSnapshot.DropBName, JobDropBGuid = jobSnapshot.DropBGuid, JobDropBPosX = jobSnapshot.DropBPosX, JobDropBPosY = jobSnapshot.DropBPosY, JobDropBPosZ = jobSnapshot.DropBPosZ, JobTargetShopHint = jobSnapshot.TargetShopHint, JobDropName = jobSnapshot.DropName, JobDropGuid = jobSnapshot.DropGuid, JobDropPosX = jobSnapshot.DropPosX, JobDropPosY = jobSnapshot.DropPosY, JobDropPosZ = jobSnapshot.DropPosZ, JobEnvelopeAmount = jobSnapshot.EnvelopeAmount, JobCutAmount = jobSnapshot.CutAmount, JobRewardAmount = jobSnapshot.RewardAmount, JobIsCurfew = jobSnapshot.IsCurfew, JobContrattoTargetName = jobSnapshot.ContrattoTargetName, JobContrattoTargetCategory = jobSnapshot.ContrattoTargetCategory, JobCaricoItemId = jobSnapshot.CaricoItemId, JobCaricoItemDisplayName = jobSnapshot.CaricoItemDisplayName, JobCaricoQuantity = jobSnapshot.CaricoQuantity, JobCaricoBonusBricks = jobSnapshot.CaricoBonusBricks, JobSchemaVersion = jobSnapshot.SchemaVersion, DropoffBaseline = jobSnapshot.DropoffBaseline, HandoverActive = TerritoryHandover.HandoverActive, ContrattiCompletedCount = PizzoJobManager.ContrattiCompletedCount, LuckyTargetName = jobSnapshot.LuckyTargetName, LuckyTargetCategory = jobSnapshot.LuckyTargetCategory, LuckyTargetRegion = jobSnapshot.LuckyTargetRegion, LuckyMethod = jobSnapshot.LuckyMethod, LuckyDispatched = jobSnapshot.LuckyDispatched, EstateOwned = false, EstateSpotIndex = 0, EstateFacingYaw = 0f, VillaOwned = RealEstateManager.VillaOwned, LagerMask = RealEstateManager.LagerMask, VillaBuildingName = (VillaLocator.BuildingName ?? ""), LagerFurnishA0 = RealEstateManager.GetFurnishA(0), LagerFurnishA1 = RealEstateManager.GetFurnishA(1), LagerFurnishA2 = RealEstateManager.GetFurnishA(2), LagerFurnishB0 = RealEstateManager.GetFurnishB(0), LagerFurnishB1 = RealEstateManager.GetFurnishB(1), LagerFurnishB2 = RealEstateManager.GetFurnishB(2), VillaFurnishA = RealEstateManager.GetFurnishA(3), VillaFurnishB = RealEstateManager.GetFurnishB(3), GridItems = GridItemsCapture(refreshGrids), KidnapVanGuid = (RapimentoManager.ActiveVanGuid ?? ""), IncomeQuest = IncomeTracker.QuestIncome, IncomeOther = IncomeTracker.OtherIncome, FearPoints = FearState.Points, FaidaBenziePoints = FaidaState.BenziePoints, FaidaReveals = FaidaState.RevealedDeals, FaidaTriadPoints = FaidaState.TriadPoints }; } public static void ApplyToLiveState(NdranghetaSnapshot snap) { if (snap == null) { snap = new NdranghetaSnapshot(); } try { GridPersistence.LoadStash(snap.GridItems); } catch (Exception ex) { NDLog.DebugWarn("GridItems stash: " + ex.Message); } try { RapimentoManager.SetPendingOrphanVan(snap.KidnapVanGuid); } catch (Exception ex2) { NDLog.DebugWarn("KidnapVan pending: " + ex2.Message); } try { IncomeTracker.LoadSnapshot(snap.IncomeQuest, snap.IncomeOther); } catch (Exception ex3) { NDLog.DebugWarn("Income restore: " + ex3.Message); } try { FearState.LoadPoints(snap.FearPoints); } catch (Exception ex4) { NDLog.DebugWarn("Fear restore: " + ex4.Message); } try { FaidaState.Load(snap.FaidaBenziePoints, snap.FaidaReveals, snap.FaidaTriadPoints); } catch (Exception ex5) { NDLog.DebugWarn("Faida restore: " + ex5.Message); } RecruitmentState.WelcomeSmsSent = snap.WelcomeSmsSent; RecruitmentState.HasMetDon = snap.HasMetDon; RecruitmentState.Recruited = snap.Recruited; RankManager.LoadRank((Rank)snap.CurrentRank); RankManager.ReconcileFromCompleted(snap.PizzoCompletedCount); DailyTribute.LoadLastDay(snap.LastTributeDay); BattesimoController.LoadStage(snap.BattesimoStage, snap.BattesimoAttackDay, snap.BattesimoAttackTime); ConsentController.LoadState(snap.ConsentState, snap.LastConsentAskDay); TerritoryHandover.LoadState(snap.HandoverActive); PizzoJobManager.LoadContrattiCount(snap.ContrattiCompletedCount); try { RealEstateManager.LoadState(snap.VillaOwned, snap.LagerMask, snap.VillaBuildingName, snap.EstateOwned, snap.EstateSpotIndex); RealEstateManager.LoadFurnish(snap.LagerFurnishA0, snap.LagerFurnishA1, snap.LagerFurnishA2, snap.VillaFurnishA, snap.LagerFurnishB0, snap.LagerFurnishB1, snap.LagerFurnishB2, snap.VillaFurnishB); } catch (Exception ex6) { NDLog.DebugWarn("RealEstate LoadState: " + ex6.Message); } PizzoJobManager.LoadFromSnapshot(new PizzoJobManager.JobSnapshot { Phase = snap.JobPhase, JobType = snap.JobType, CompletedCount = snap.PizzoCompletedCount, CooldownRemaining = snap.JobCooldownRemaining, CashSpawned = snap.JobCashSpawned, TargetName = snap.JobTargetName, DropBName = snap.JobDropBName, DropBGuid = snap.JobDropBGuid, DropBPosX = snap.JobDropBPosX, DropBPosY = snap.JobDropBPosY, DropBPosZ = snap.JobDropBPosZ, TargetShopHint = snap.JobTargetShopHint, DropName = snap.JobDropName, DropGuid = snap.JobDropGuid, DropPosX = snap.JobDropPosX, DropPosY = snap.JobDropPosY, DropPosZ = snap.JobDropPosZ, EnvelopeAmount = snap.JobEnvelopeAmount, CutAmount = snap.JobCutAmount, RewardAmount = snap.JobRewardAmount, IsCurfew = snap.JobIsCurfew, ContrattoTargetName = snap.JobContrattoTargetName, ContrattoTargetCategory = snap.JobContrattoTargetCategory, CaricoItemId = snap.JobCaricoItemId, CaricoItemDisplayName = snap.JobCaricoItemDisplayName, CaricoQuantity = snap.JobCaricoQuantity, CaricoBonusBricks = snap.JobCaricoBonusBricks, SchemaVersion = snap.JobSchemaVersion, LuckyTargetName = snap.LuckyTargetName, LuckyTargetCategory = snap.LuckyTargetCategory, LuckyTargetRegion = snap.LuckyTargetRegion, LuckyMethod = snap.LuckyMethod, LuckyDispatched = snap.LuckyDispatched, DropoffBaseline = snap.DropoffBaseline }); if (snap.HandoverActive && PizzoJobManager.Current == null) { try { LuckyChatController.RefreshIfHandoverActive(); } catch (Exception ex7) { NDLog.DebugWarn("OnLoaded LuckyChat refresh: " + ex7.Message); } } } } [Serializable] public sealed class NdranghetaSnapshot { public bool WelcomeSmsSent; public bool HasMetDon; public bool Recruited; public int CurrentRank; public int LastTributeDay = -1; public int BattesimoStage; public int BattesimoAttackDay; public int BattesimoAttackTime; public int ConsentState; public int LastConsentAskDay = -1; public int PizzoCompletedCount; public int JobPhase; public int JobType; public float JobCooldownRemaining; public bool JobCashSpawned; public string JobTargetName; public string JobDropBName; public string JobDropBGuid; public float JobDropBPosX; public float JobDropBPosY; public float JobDropBPosZ; public string JobTargetShopHint; public string JobDropName; public string JobDropGuid; public float JobDropPosX; public float JobDropPosY; public float JobDropPosZ; public int JobEnvelopeAmount; public int JobCutAmount; public int JobRewardAmount; public bool JobIsCurfew; public string JobContrattoTargetName; public string JobContrattoTargetCategory; public string JobCaricoItemId; public string JobCaricoItemDisplayName; public int JobCaricoQuantity; public int JobCaricoBonusBricks; public int JobSchemaVersion; public int DropoffBaseline = -1; public bool HandoverActive; public int ContrattiCompletedCount; public string LuckyTargetName; public string LuckyTargetCategory; public string LuckyTargetRegion; public int LuckyMethod; public bool LuckyDispatched; public bool EstateOwned; public int EstateSpotIndex; public float EstateFacingYaw; public bool VillaOwned; public int LagerMask; public string VillaBuildingName; public int LagerFurnishA0; public int LagerFurnishA1; public int LagerFurnishA2; public int LagerFurnishB0; public int LagerFurnishB1; public int LagerFurnishB2; public int VillaFurnishA; public int VillaFurnishB; public string GridItems; public string KidnapVanGuid; public long IncomeQuest; public long IncomeOther; public int FearPoints; public int FaidaBenziePoints; public int FaidaReveals; public int FaidaTriadPoints; } } namespace Ndrangheta.Quests { [QuestName("Il Battesimo")] internal sealed class BattesimoQuestId : IQuestIdentifier { } internal sealed class BattesimoQuest : Quest { public const string QuestGuid = "Ndrangheta.battesimo"; protected override string Title => "Il Battesimo"; protected override string Description => "The 'Ndrina wants proof you can bleed without ending up in cuffs. Hit a cop, any cop. Then survive an hour clean. After that the famiglia will trust you with the real work — il contratto."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryAttack { get; private set; } public QuestEntry EntrySurvive { get; private set; } internal static BattesimoQuest Instance { get; private set; } public BattesimoQuest() { EntryAttack = ((Quest)this).AddEntry("Bleed for the famiglia — attack any cop and walk away", (Vector3?)null); EntrySurvive = ((Quest)this).AddEntry("Survive one hour clean, no arrests", (Vector3?)null); try { EntryAttack.ClearPOI(); } catch { } try { EntrySurvive.ClearPOI(); } catch { } Instance = this; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); if ((Object)(object)val != (Object)null) { QuestIconHelper.ApplyAsync((Quest)(object)this, val); } NDLog.Debug("BattesimoQuest constructed."); } public static void EnsureCreated() { try { if (Instance == null && QuestManager.GetQuestByName("Il Battesimo") == null) { QuestManager.CreateQuest("Ndrangheta.battesimo"); NDLog.Debug("BattesimoQuest created."); } } catch (Exception ex) { NDLog.Warn("BattesimoQuest.EnsureCreated: " + ex.Message); } } public static void EnsureFirstEntryActive() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { BattesimoQuest instance = Instance; if (instance?.EntryAttack != null && (int)instance.EntryAttack.State == 0) { instance.EntryAttack.Begin(); } } catch { } } public static void OnAttackDetected() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 try { BattesimoQuest instance = Instance; if (instance?.EntryAttack != null && (int)instance.EntryAttack.State != 2) { instance.EntryAttack.Complete(); } if (instance?.EntrySurvive != null && (int)instance.EntrySurvive.State == 0) { instance.EntrySurvive.Begin(); } } catch (Exception ex) { NDLog.Warn("BattesimoQuest.OnAttackDetected: " + ex.Message); } } public static void OnSurvived() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { BattesimoQuest instance = Instance; if (instance?.EntrySurvive != null && (int)instance.EntrySurvive.State != 2) { instance.EntrySurvive.Complete(); } } catch (Exception ex) { NDLog.Warn("BattesimoQuest.OnSurvived: " + ex.Message); } } public static void ClearInstanceForNext() { Instance = null; } } [QuestName("Pacco Bomba")] internal sealed class BombaMarkerQuestId : IQuestIdentifier { } internal sealed class BombaMarkerQuest : Quest { private static string _pendingText = "Pacco Bomba"; internal static BombaMarkerQuest Instance { get; private set; } protected override string Title => "Pacco Bomba"; protected override string Description => "The package is on its way. Keep your distance when it's armed."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public BombaMarkerQuest() { EntryMain = ((Quest)this).AddEntry(_pendingText, (Vector3?)null); Instance = this; NDLog.Debug("[BOMBA] marker quest created."); } internal static void EnsureCreated(string text, Vector3 pos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { if (Instance != null) { SetText(text); MoveTo(pos); return; } _pendingText = text ?? "Pacco Bomba"; string text2 = $"Ndrangheta.bomba.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text2); if (Instance != null && ((Vector3)(ref pos)).sqrMagnitude > 1f) { Instance.EntryMain.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(Instance.EntryMain, val); } } } catch (Exception ex) { NDLog.DebugWarn("BombaMarkerQuest.EnsureCreated: " + ex.Message); } } internal static void SetText(string text) { try { if (Instance?.EntryMain != null && !string.IsNullOrEmpty(text)) { Instance.EntryMain.Title = text; } } catch { } } internal static void MoveTo(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if (Instance?.EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(Instance.EntryMain, pos); } } catch { } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } Instance = null; NDLog.Debug("[BOMBA] marker quest cleared."); } } [QuestName("Brawl")] internal sealed class BrawlMarkerQuestId : IQuestIdentifier { } internal sealed class BrawlMarkerQuest : Quest { private static string _pendingText = "Brawl"; internal static BrawlMarkerQuest Instance { get; private set; } protected override string Title => "Brawl"; protected override string Description => "Our men are ready to crack skulls. Follow the marker."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public BrawlMarkerQuest() { EntryMain = ((Quest)this).AddEntry(_pendingText, (Vector3?)null); Instance = this; NDLog.Debug("[BRAWL] marker quest created."); } internal static void EnsureCreated(string text, Vector3 pos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { if (Instance != null) { SetText(text); MoveTo(pos); return; } _pendingText = text ?? "Brawl"; string text2 = $"Ndrangheta.brawl.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text2); if (Instance != null && ((Vector3)(ref pos)).sqrMagnitude > 1f) { Instance.EntryMain.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(Instance.EntryMain, val); } } } catch (Exception ex) { NDLog.DebugWarn("BrawlMarkerQuest.EnsureCreated: " + ex.Message); } } internal static void SetText(string text) { try { if (Instance?.EntryMain != null && !string.IsNullOrEmpty(text)) { Instance.EntryMain.Title = text; } } catch { } } internal static void MoveTo(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if (Instance?.EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(Instance.EntryMain, pos); } } catch { } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { PoiIconHelper.SetPoiVisible(Instance.EntryMain, visible: false); } catch { } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.ClearPOI(); } } catch { } try { Instance.ForceHideHudTracker(); } catch { } try { QuestEntry entryMain2 = Instance.EntryMain; if (entryMain2 != null) { entryMain2.Complete(); } } catch { } try { Instance.ForceHideHudTracker(); } catch { } Instance = null; NDLog.Debug("[BRAWL] marker quest cleared."); } internal static void FailAndClear() { if (Instance == null) { return; } try { PoiIconHelper.SetPoiVisible(Instance.EntryMain, visible: false); } catch { } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.ClearPOI(); } } catch { } try { Instance.ForceHideHudTracker(); } catch { } try { QuestEntry entryMain2 = Instance.EntryMain; if (entryMain2 != null) { entryMain2.SetState((QuestState)3); } } catch { } try { ((Quest)Instance).Fail(); } catch { } Instance = null; NDLog.Debug("[BRAWL] marker quest FAILED + cleared."); } private Quest TryGetVanillaQuest() { try { Type type = ((object)this).GetType(); while (type != null) { PropertyInfo property = type.GetProperty("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object? value = property.GetValue(this); Quest val = (Quest)((value is Quest) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(Quest))) { object? value2 = fieldInfo.GetValue(this); Quest val2 = (Quest)((value2 is Quest) ? value2 : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } type = type.BaseType; } } catch { } return null; } private void ForceHideHudTracker() { try { Quest val = TryGetVanillaQuest(); if ((Object)(object)val == (Object)null) { return; } try { val.TrackOnBegin = false; } catch { } try { ((object)val).GetType().GetMethod("SetIsTracked", new Type[1] { typeof(bool) })?.Invoke(val, new object[1] { false }); } catch { } try { ((object)val).GetType().GetMethod("DestroyHUDUI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } try { ((object)val).GetType().GetMethod("DestroyJournalEntry", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } } catch { } } } [QuestName("Car Bomb")] internal sealed class CarBombMarkerQuestId : IQuestIdentifier { } internal sealed class CarBombMarkerQuest : Quest { private static string _pendingText = "Car Bomb"; internal static CarBombMarkerQuest Instance { get; private set; } protected override string Title => "Car Bomb"; protected override string Description => "The car's wired. Mark the spot, give the word, and get clear before the fuse runs out."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public CarBombMarkerQuest() { EntryMain = ((Quest)this).AddEntry(_pendingText, (Vector3?)null); Instance = this; NDLog.Debug("[CARBOMB] marker quest created."); } internal static void EnsureCreated(string text, Vector3 pos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { if (Instance != null) { SetText(text); MoveTo(pos); return; } _pendingText = text ?? "Car Bomb"; string text2 = $"Ndrangheta.carbomb.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text2); if (Instance != null && ((Vector3)(ref pos)).sqrMagnitude > 1f) { Instance.EntryMain.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(Instance.EntryMain, val); } } } catch (Exception ex) { NDLog.DebugWarn("CarBombMarkerQuest.EnsureCreated: " + ex.Message); } } internal static void SetText(string text) { try { if (Instance?.EntryMain != null && !string.IsNullOrEmpty(text)) { Instance.EntryMain.Title = text; } } catch { } } internal static void MoveTo(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if (Instance?.EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(Instance.EntryMain, pos); } } catch { } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } Instance = null; NDLog.Debug("[CARBOMB] marker quest cleared."); } } [QuestName("Carico")] internal sealed class CaricoQuestId : IQuestIdentifier { } internal sealed class CaricoQuest : Quest { public static string CurrentJobGuid; private string _titleText; private string _descriptionText; private Vector3 _bPos; private Vector3 _donPos; protected override string Title => _titleText ?? "Carico"; protected override string Description => _descriptionText ?? "Move a partita from one drop to another, then collect your share from the Don."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryPickup { get; private set; } public QuestEntry EntryDeliver { get; private set; } public QuestEntry EntryDropOff { get; private set; } internal static CaricoQuest Instance { get; private set; } public CaricoQuest() { EntryPickup = ((Quest)this).AddEntry("Pick up the partita", (Vector3?)null); EntryDeliver = ((Quest)this).AddEntry("Deliver the partita", (Vector3?)null); EntryDropOff = ((Quest)this).AddEntry("Collect your share from the Don", (Vector3?)null); Instance = this; NDLog.Debug("CaricoQuest constructed."); } public void Apply(string itemDisplayName, string itemId, int quantity, string aName, Vector3 aPos, string bName, Vector3 bPos, int reward) { //IL_004c: 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_00a0: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_012a: 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_0137: Unknown result type (might be due to invalid IL or missing references) _titleText = LoreStrings.CaricoTitle(itemDisplayName); _descriptionText = LoreStrings.CaricoDescription(itemDisplayName, itemId, quantity, aName, bName, reward); try { if (EntryPickup != null) { EntryPickup.Title = LoreStrings.CaricoEntryPickup(itemDisplayName, itemId, quantity, aName); EntryPickup.POIPosition = aPos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(EntryPickup, val); } } if (EntryDeliver != null) { EntryDeliver.Title = LoreStrings.CaricoEntryDeliver(itemDisplayName, itemId, quantity, bName); _bPos = bPos; EntryDeliver.POIPosition = bPos; Sprite val2 = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val2 != (Object)null) { PoiIconHelper.ApplyAsync(EntryDeliver, val2); } } if (EntryDropOff != null) { EntryDropOff.Title = (TerritoryHandover.HandoverActive ? "Report to the cassa at the Gazebo for your share" : "Collect your share from Don Salvatore at the Gazebo"); Vector3 val3 = ResolveDonWorldPos(); if (val3 != Vector3.zero) { _donPos = val3; EntryDropOff.POIPosition = val3; Sprite val4 = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val4 != (Object)null) { PoiIconHelper.ApplyAsync(EntryDropOff, val4); } } else { try { EntryDropOff.ClearPOI(); } catch { } } } } catch (Exception ex) { NDLog.Warn("CaricoQuest.Apply: " + ex.Message); } EnsureFirstEntryActive(); } private static Vector3 ResolveDonWorldPos() { //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_0069: 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_0021: 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_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) try { if (TerritoryHandover.HandoverActive) { if (DonSalvatoreNPC.ResolveGazeboPosition(out var pos)) { return pos; } return Vector3.zero; } NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).transform != (Object)null) { return ((Component)cachedGameNpc).transform.position; } } catch { } return Vector3.zero; } public static void EnsureCreated() { try { if (Instance == null && QuestManager.GetQuestByName("Carico") == null) { CurrentJobGuid = $"Ndrangheta.carico.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(CurrentJobGuid); NDLog.Debug("CaricoQuest created."); } } catch (Exception ex) { NDLog.Warn("CaricoQuest.EnsureCreated: " + ex.Message); } } public static void CompletePickup() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 try { CaricoQuest instance = Instance; if (instance?.EntryPickup != null && (int)instance.EntryPickup.State != 2) { instance.EntryPickup.Complete(); } if (instance?.EntryDeliver != null && (int)instance.EntryDeliver.State == 0) { instance.EntryDeliver.Begin(); } ReapplyDeliverIcon(); } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void CompleteDeliver() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 try { CaricoQuest instance = Instance; if (instance?.EntryDeliver != null && (int)instance.EntryDeliver.State != 2) { instance.EntryDeliver.Complete(); } if (instance?.EntryDropOff != null && (int)instance.EntryDropOff.State == 0) { instance.EntryDropOff.Begin(); } ReapplyDropOffIcon(); } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void CompleteDropOff() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { CaricoQuest instance = Instance; if (instance?.EntryDropOff != null && (int)instance.EntryDropOff.State != 2) { instance.EntryDropOff.Complete(); } } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void EnsureFirstEntryActive() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { CaricoQuest instance = Instance; if (instance?.EntryPickup != null && (int)instance.EntryPickup.State == 0) { instance.EntryPickup.Begin(); } } catch { } } private static void ReapplyDeliverIcon() { //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_0038: Unknown result type (might be due to invalid IL or missing references) try { CaricoQuest instance = Instance; if (instance?.EntryDeliver != null) { if (instance._bPos != Vector3.zero) { instance.EntryDeliver.POIPosition = instance._bPos; } Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryDeliver, val); } } } catch { } } private static void ReapplyDropOffIcon() { //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_0023: 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_003b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) try { CaricoQuest instance = Instance; if (instance?.EntryDropOff != null) { Vector3 val = ResolveDonWorldPos(); if (val == Vector3.zero) { val = instance._donPos; } if (val != Vector3.zero) { instance.EntryDropOff.POIPosition = val; } Sprite val2 = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val2 != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryDropOff, val2); } } } catch { } } public static void ClearInstanceForNext() { Instance = null; } } [QuestName("Il Circolo")] internal sealed class CircoloQuestId : IQuestIdentifier { } internal sealed class CircoloQuest : Quest { public const string QuestGuid = "Ndrangheta.circolo.marker"; private static string _pendingText = "Il Circolo"; internal static CircoloQuest Instance { get; private set; } protected override string Title => "Il Circolo"; protected override string Description => "The famiglia's own front. The men hold the door."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public CircoloQuest() { EntryMain = ((Quest)this).AddEntry(_pendingText, (Vector3?)null); Instance = this; Quest val = TryGetVanillaQuest(); if ((Object)(object)val != (Object)null) { try { val.TrackOnBegin = false; } catch { } } NDLog.Debug("[CIRCOLO] marker quest created."); } internal static void EnsureCreated(string text, Vector3 pos) { //IL_0016: 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) try { if (Instance != null) { SetText(text); MoveTo(pos); Instance.SuppressJournalAndHud(); return; } _pendingText = text ?? "Il Circolo"; QuestManager.CreateQuest("Ndrangheta.circolo.marker"); if (Instance == null) { return; } SetText(text); if (((Vector3)(ref pos)).sqrMagnitude > 1f) { Instance.EntryMain.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(Instance.EntryMain, val); } } Instance.SuppressJournalAndHud(); } catch (Exception ex) { NDLog.DebugWarn("CircoloQuest.EnsureCreated: " + ex.Message); } } internal static void SetText(string text) { try { if (Instance?.EntryMain != null && !string.IsNullOrEmpty(text)) { Instance.EntryMain.Title = text; } } catch { } } internal static void MoveTo(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if (Instance?.EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(Instance.EntryMain, pos); } } catch { } } public static void SuppressHud() { try { Instance?.SuppressJournalAndHud(); } catch { } } private void SuppressJournalAndHud() { try { Quest val = TryGetVanillaQuest(); if ((Object)(object)val == (Object)null) { return; } try { val.TrackOnBegin = false; } catch { } try { ((object)val).GetType().GetMethod("SetIsTracked", new Type[1] { typeof(bool) })?.Invoke(val, new object[1] { false }); } catch { } try { ((object)val).GetType().GetMethod("DestroyHUDUI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } try { ((object)val).GetType().GetMethod("DestroyJournalEntry", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } } catch { } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { PoiIconHelper.SetPoiVisible(Instance.EntryMain, visible: false); } catch { } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.ClearPOI(); } } catch { } try { QuestEntry entryMain2 = Instance.EntryMain; if (entryMain2 != null) { entryMain2.Complete(); } } catch { } Instance = null; NDLog.Debug("[CIRCOLO] marker quest cleared."); } internal static void ClearInstanceForReload() { Instance = null; } private Quest TryGetVanillaQuest() { try { Type type = ((object)this).GetType(); while (type != null) { PropertyInfo property = type.GetProperty("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object? value = property.GetValue(this); Quest val = (Quest)((value is Quest) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(Quest))) { object? value2 = fieldInfo.GetValue(this); Quest val2 = (Quest)((value2 is Quest) ? value2 : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } type = type.BaseType; } } catch { } return null; } } [QuestName("FamigliaOperation")] internal sealed class ClientBossMarkerQuestId : IQuestIdentifier { } internal sealed class ClientBossMarkerQuest : Quest { private static string _pendingLabel = ""; private static int _pendingKind; private string _label; private int _kind; private float _lastStampAt; private static Vector3 _lastPoi = Vector3.zero; internal static ClientBossMarkerQuest Instance { get; private set; } protected override string Title => "Famiglia Operation"; protected override string Description => string.IsNullOrEmpty(_label) ? "The famiglia has work in the city." : _label; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public ClientBossMarkerQuest() { _label = _pendingLabel; _kind = _pendingKind; EntryMain = ((Quest)this).AddEntry(string.IsNullOrEmpty(_pendingLabel) ? "Follow the marker" : _pendingLabel, (Vector3?)null); Instance = this; NDLog.Debug("[CLIENTBOSS] boss marker quest started: '" + _pendingLabel + "'"); } internal static void EnsureCreated(string label, Vector3 pos, int kind = 0) { //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_005f: Unknown result type (might be due to invalid IL or missing references) if (Instance != null) { return; } try { _pendingLabel = label ?? ""; _pendingKind = kind; _lastPoi = Vector3.zero; string text = $"Ndrangheta.clientboss.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text); Instance?.ApplyPoi(pos); } catch (Exception ex) { NDLog.DebugWarn("ClientBossMarkerQuest.EnsureCreated: " + ex.Message); } } internal static void UpdateLabelAndPoi(string label, Vector3 pos, int kind = 0) { //IL_0086: 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_0091: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (Instance == null || Instance.EntryMain == null) { return; } try { Instance._kind = kind; if (!string.IsNullOrEmpty(label) && !string.Equals(label, Instance._label, StringComparison.Ordinal)) { Instance._label = label; try { Instance.EntryMain.Title = label; } catch { } } if (!(((Vector3)(ref pos)).sqrMagnitude > 1f)) { return; } Vector3 val = pos - _lastPoi; if (((Vector3)(ref val)).sqrMagnitude > 1f) { if (((Vector3)(ref _lastPoi)).sqrMagnitude < 1f) { Instance.ApplyPoi(pos); } else { PoiIconHelper.MovePoi(Instance.EntryMain, pos); Instance.StampIcon(throttled: true); } _lastPoi = pos; } } catch (Exception ex) { NDLog.DebugWarn("ClientBossMarkerQuest.UpdateLabelAndPoi: " + ex.Message); } } private void ApplyPoi(Vector3 pos) { //IL_0034: 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) try { if (EntryMain == null || ((Vector3)(ref pos)).sqrMagnitude < 1f) { return; } if (_kind == 3) { PoiIconHelper.MovePoi(EntryMain, pos); } else { try { EntryMain.POIPosition = pos; } catch { } } StampIcon(throttled: false); } catch (Exception ex) { NDLog.DebugWarn("ClientBossMarkerQuest.ApplyPoi: " + ex.Message); } } private void StampIcon(bool throttled) { try { if (EntryMain != null && (!throttled || !(Time.time - _lastStampAt < 2f))) { _lastStampAt = Time.time; Sprite val = ((_kind == 3) ? (AssetLoader.LoadSprite("Ndrangheta.assets.veeper_icon.png") ?? AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png")) : AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png")); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(EntryMain, val); } } } catch { } } internal static void CompleteAndClear() { //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) if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } Instance = null; _lastPoi = Vector3.zero; NDLog.Debug("[CLIENTBOSS] boss marker quest cleared."); } } [QuestName("MeetTheDon")] internal sealed class ClientIntroQuestId : IQuestIdentifier { } internal sealed class ClientIntroQuest : Quest { private static bool _poiApplied; internal static ClientIntroQuest Instance { get; private set; } protected override string Title => "Meet the Don"; protected override string Description => "Don Salvatore is waiting at the Gazebo in Suburbia. Go and hear him out."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMeet { get; private set; } public ClientIntroQuest() { EntryMeet = ((Quest)this).AddEntry("Meet Don Salvatore in Suburbia", (Vector3?)null); Instance = this; NDLog.Debug("[CLIENTINTRO] meet-the-Don mirror quest started."); } internal static void EnsureCreated(Vector3 pos) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (Instance != null) { return; } try { _poiApplied = false; string text = $"Ndrangheta.clientintro.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text); Instance?.ApplyPoi(pos); } catch (Exception ex) { NDLog.DebugWarn("ClientIntroQuest.EnsureCreated: " + ex.Message); } } internal static void RefreshPoi(Vector3 pos) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (Instance == null) { return; } try { if (!_poiApplied) { Instance.ApplyPoi(pos); } } catch { } } private void ApplyPoi(Vector3 pos) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) try { if (EntryMeet != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { EntryMeet.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(EntryMeet, val); } _poiApplied = true; } } catch (Exception ex) { NDLog.DebugWarn("ClientIntroQuest.ApplyPoi: " + ex.Message); } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { QuestEntry entryMeet = Instance.EntryMeet; if (entryMeet != null) { entryMeet.Complete(); } } catch { } Instance = null; NDLog.Debug("[CLIENTINTRO] meet-the-Don mirror quest completed."); } internal static void ResetForSceneReload() { Instance = null; _poiApplied = false; } } [QuestName("FamiljaJob")] internal sealed class ClientJobMirrorQuestId : IQuestIdentifier { } internal sealed class ClientJobMirrorQuest : Quest { private static string _pendingCode = ""; private static string _pendingTarget = ""; private string _title; private string _desc; private readonly string _jobCode; private static int _lastStage = -1; private static string _lastEntryText = ""; private static Vector3 _lastPoi = Vector3.zero; internal static ClientJobMirrorQuest Instance { get; private set; } internal static string LastJobCode { get; private set; } = ""; protected override string Title => _title ?? "Famiglia Job"; protected override string Description => _desc ?? "Complete the active job for the famiglia."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } private string PoiIconRes { get { switch (_jobCode) { case "p": case "t": case "ca": return "Ndrangheta.assets.deaddrop_quest.png"; default: return "Ndrangheta.assets.don_icon.png"; } } } public ClientJobMirrorQuest() { _jobCode = _pendingCode; _title = BuildTitle(_pendingCode); _desc = BuildDesc(_pendingCode, _pendingTarget); EntryMain = ((Quest)this).AddEntry(BuildEntryText(_pendingCode, _pendingTarget), (Vector3?)null); LastJobCode = _pendingCode; Instance = this; NDLog.Debug("[CLIENTJOB] mirror quest started: job=" + _pendingCode + " target=" + _pendingTarget); } internal static void EnsureCreated(string jobCode, string target, Vector3 pos) { //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_0080: Unknown result type (might be due to invalid IL or missing references) if (Instance != null) { return; } try { _pendingCode = jobCode ?? ""; _pendingTarget = target ?? ""; _lastStage = -1; _lastEntryText = ""; _lastPoi = Vector3.zero; string text = $"Ndrangheta.clientjob.{_pendingCode}.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text); Instance?.ApplyPoi(pos); } catch (Exception ex) { NDLog.DebugWarn("ClientJobMirrorQuest.EnsureCreated: " + ex.Message); } } private void ApplyPoi(Vector3 pos) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) try { if (EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(EntryMain, pos); Sprite val = AssetLoader.LoadSprite(PoiIconRes); Sprite compassIcon = null; if (_jobCode == "c" || _jobCode == "lc") { compassIcon = AssetLoader.LoadSprite("Ndrangheta.assets.contratto_target_compass.png"); } if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(EntryMain, val, compassIcon); } } } catch (Exception ex) { NDLog.DebugWarn("ClientJobMirrorQuest.ApplyPoi: " + ex.Message); } } internal static void CompleteAndClear() { //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) if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } Instance = null; LastJobCode = ""; _lastStage = -1; _lastEntryText = ""; _lastPoi = Vector3.zero; NDLog.Debug("[CLIENTJOB] mirror quest completed."); } internal static void UpdateStage(int stage, string jobCode, Vector3 gazeboPos, string hostEntryText, Vector3 hostEntryPoi) { //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_00d4: 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_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) //IL_00c3: 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_0128: 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_012f: 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) if (Instance == null || Instance.EntryMain == null) { return; } try { string text = ((!string.IsNullOrEmpty(hostEntryText)) ? hostEntryText : StageEntryText(stage, jobCode)); bool flag = stage != _lastStage; if (!string.IsNullOrEmpty(text) && !string.Equals(text, _lastEntryText, StringComparison.Ordinal)) { Instance.EntryMain.Title = text; _lastEntryText = text; NDLog.Debug($"[CLIENTJOB] step mirror -> stage={stage} '{text}'."); } Vector3 val = hostEntryPoi; if (((Vector3)(ref val)).sqrMagnitude < 1f && (stage == 3 || stage == 8 || stage == 6)) { val = gazeboPos; } if (((Vector3)(ref val)).sqrMagnitude > 1f) { Vector3 val2 = val - _lastPoi; if (((Vector3)(ref val2)).sqrMagnitude > 1f) { if (((Vector3)(ref _lastPoi)).sqrMagnitude < 1f) { Instance.ApplyPoi(val); } else { PoiIconHelper.MovePoi(Instance.EntryMain, val); } _lastPoi = val; } } if (flag) { _lastStage = stage; } } catch (Exception ex) { NDLog.DebugWarn("ClientJobMirrorQuest.UpdateStage: " + ex.Message); } } private static string StageEntryText(int stage, string code) { return (PizzoJobManager.Phase)stage switch { PizzoJobManager.Phase.AwaitPickup => "Pick up the goods", PizzoJobManager.Phase.AwaitTrasportoDeliver => "Deliver the package to the drop", PizzoJobManager.Phase.AwaitDropOff => "Bring the Don his cut (any of you)", PizzoJobManager.Phase.AwaitKill => null, PizzoJobManager.Phase.AwaitContrattoReturn => "Return the revolver to the stash & report to Don", PizzoJobManager.Phase.AwaitCaricoDeliver => "Deliver the shipment", PizzoJobManager.Phase.AwaitCaricoDropOff => "Report to Don at the gazebo", PizzoJobManager.Phase.AwaitLuckyHit => "Lucky is on the job — stand by", _ => null, }; } internal static string BuildClientSms(string jobCode, string target) { return BuildDesc(jobCode, target); } private static string BuildTitle(string code) { return code switch { "c" => "Contratto", "lc" => "Lucky's Contratto", "p" => "Pizzo", "t" => "Trasporto", "ca" => "Carico", _ => "Famiglia Job", }; } private static string BuildDesc(string code, string target) { return code switch { "c" => (string.IsNullOrEmpty(target) ? "The famiglia has marked a target. Handle it." : ("The famiglia has marked " + target + ". Handle it.")) + " There's a revolver in the famiglia stash at the gazebo if you want clean iron — optional.", "lc" => string.IsNullOrEmpty(target) ? "Lucky has been dispatched. Watch his back." : ("Lucky has been sent after " + target + "."), "p" => "Collect the envelope and deliver the cut to Don Salvatore.", "t" => "Transport the package through the city for the famiglia.", "ca" => "Transport the goods and return your cut to the Gazebo.", _ => "Complete the active job for the famiglia.", }; } private static string BuildEntryText(string code, string target) { return code switch { "c" => string.IsNullOrEmpty(target) ? "Eliminate the target" : ("Eliminate " + target), "lc" => string.IsNullOrEmpty(target) ? "Lucky eliminates the target" : ("Lucky eliminates " + target), "p" => "Collect the envelope", "t" => "Transport the package", "ca" => "Transport the goods", _ => "Complete the job", }; } } [QuestName("Contratto")] internal sealed class ContrattoQuestId : IQuestIdentifier { } internal sealed class ContrattoQuest : Quest { public static string CurrentJobGuid; public const string TargetCompassIconResource = "Ndrangheta.assets.contratto_target_compass.png"; private string _titleText; private string _descriptionText; private Vector3 _donPos; private Vector3 _targetPos; protected override string Title => _titleText ?? "Contratto"; protected override string Description => _descriptionText ?? "The famiglia has marked a target. Handle it, then come back to the stash."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryKill { get; private set; } public QuestEntry EntryReturn { get; private set; } internal static ContrattoQuest Instance { get; private set; } public ContrattoQuest() { EntryKill = ((Quest)this).AddEntry("Eliminate the target", (Vector3?)null); EntryReturn = ((Quest)this).AddEntry("Drop the revolver back at the Famiglia stash or take your money directly from it", (Vector3?)null); Instance = this; NDLog.Debug("ContrattoQuest constructed."); } public void Apply(string targetName, Vector3 targetPos, int luckyMethod = 0) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_00fc: 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_0109: 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_0079: 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) _titleText = LoreStrings.ContrattoTitle(targetName); _descriptionText = LoreStrings.ContrattoDescription(targetName); try { if (EntryKill != null) { switch (luckyMethod) { case 1: EntryKill.Title = LoreStrings.ContrattoEntryBeatdown(targetName); break; case 2: EntryKill.Title = LoreStrings.ContrattoEntryHit(targetName); break; default: EntryKill.Title = LoreStrings.ContrattoEntryKill(targetName); break; } _targetPos = targetPos; EntryKill.POIPosition = targetPos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); Sprite compassIcon = AssetLoader.LoadSprite("Ndrangheta.assets.contratto_target_compass.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(EntryKill, val, compassIcon); } } if (EntryReturn != null) { EntryReturn.Title = "Collect your cut at the Famiglia stash (Gazebo) — returning the revolver is optional"; Vector3 val2 = ResolveDonWorldPos(); if (val2 != Vector3.zero) { _donPos = val2; EntryReturn.POIPosition = val2; Sprite val3 = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val3 != (Object)null) { PoiIconHelper.ApplyAsync(EntryReturn, val3); } } else { try { EntryReturn.ClearPOI(); } catch { } } } } catch (Exception ex) { NDLog.Warn("ContrattoQuest.Apply: " + ex.Message); } EnsureFirstEntryActive(); } private static Vector3 ResolveDonWorldPos() { //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_0069: 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_0021: 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_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) try { if (TerritoryHandover.HandoverActive) { if (DonSalvatoreNPC.ResolveGazeboPosition(out var pos)) { return pos; } return Vector3.zero; } NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).transform != (Object)null) { return ((Component)cachedGameNpc).transform.position; } } catch { } return Vector3.zero; } public static void EnsureCreated() { try { if (Instance == null && QuestManager.GetQuestByName("Contratto") == null) { CurrentJobGuid = $"Ndrangheta.contratto.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(CurrentJobGuid); NDLog.Debug("ContrattoQuest created."); } } catch (Exception ex) { NDLog.Warn("ContrattoQuest.EnsureCreated: " + ex.Message); } } public static void CompleteKill() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 try { ContrattoQuest instance = Instance; if (instance?.EntryKill != null && (int)instance.EntryKill.State != 2) { instance.EntryKill.Complete(); } if (instance?.EntryReturn != null && (int)instance.EntryReturn.State == 0) { instance.EntryReturn.Begin(); } ReapplyReturnIcon(); } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void CompleteReturn() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { ContrattoQuest instance = Instance; if (instance?.EntryReturn != null && (int)instance.EntryReturn.State != 2) { instance.EntryReturn.Complete(); } } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void EnsureFirstEntryActive() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { ContrattoQuest instance = Instance; if (instance?.EntryKill != null && (int)instance.EntryKill.State == 0) { instance.EntryKill.Begin(); } } catch { } } public static void ClearInstanceForNext() { Instance = null; } private static void ReapplyReturnIcon() { //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_0023: 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_003b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) try { ContrattoQuest instance = Instance; if (instance?.EntryReturn != null) { Vector3 val = ResolveDonWorldPos(); if (val == Vector3.zero) { val = instance._donPos; } if (val != Vector3.zero) { instance.EntryReturn.POIPosition = val; } Sprite val2 = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val2 != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryReturn, val2); } } } catch { } } public static void ReapplyKillTarget(Vector3 pos) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0033: 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_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_0053: Unknown result type (might be due to invalid IL or missing references) try { ContrattoQuest instance = Instance; if (instance?.EntryKill != null && (int)instance.EntryKill.State != 2 && !(pos == Vector3.zero)) { instance._targetPos = pos; instance.EntryKill.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); Sprite compassIcon = AssetLoader.LoadSprite("Ndrangheta.assets.contratto_target_compass.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryKill, val, compassIcon); } } } catch { } } public static void TrackKillTargetPosition(Vector3 pos) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0031: 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_0042: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0073: Unknown result type (might be due to invalid IL or missing references) try { ContrattoQuest instance = Instance; if (instance?.EntryKill != null && (int)instance.EntryKill.State != 2 && !(pos == Vector3.zero)) { Vector3 val = pos - instance._targetPos; if (!(((Vector3)(ref val)).sqrMagnitude < 4f)) { instance._targetPos = pos; PoiIconHelper.MovePoi(instance.EntryKill, pos); } } } catch { } } } [QuestName("I Depositi")] internal sealed class DepositoMarkerQuestId : IQuestIdentifier { } internal sealed class DepositoMarkerQuest : Quest { public const string QuestGuid = "Ndrangheta.depositi.marker"; private readonly QuestEntry[] _entries = (QuestEntry[])(object)new QuestEntry[3]; private readonly bool[] _iconApplied = new bool[3]; internal static DepositoMarkerQuest Instance { get; private set; } protected override string Title => "I Depositi"; protected override string Description => "The famiglia's hidden storage rooms."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public DepositoMarkerQuest() { for (int i = 0; i < 3; i++) { _entries[i] = ((Quest)this).AddEntry(RealEstateManager.SpotNames[i], (Vector3?)null); } Instance = this; Quest val = TryGetVanillaQuest(); if ((Object)(object)val != (Object)null) { try { val.TrackOnBegin = false; } catch { } } NDLog.Debug("[DEPOSITO] marker quest created."); } internal static void Sync(int lagerMask) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Invalid comparison between Unknown and I4 //IL_00fb: 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_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_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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_0151: 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_00d7: Invalid comparison between Unknown and I4 try { lagerMask &= 7; if (lagerMask == 0) { if (Instance != null) { CompleteAndClear(); } return; } if (Instance == null) { QuestManager.CreateQuest("Ndrangheta.depositi.marker"); } DepositoMarkerQuest instance = Instance; if (instance == null) { return; } for (int i = 0; i < 3; i++) { QuestEntry val = instance._entries[i]; if (val == null) { continue; } if ((lagerMask & (1 << i)) == 0) { try { val.ClearPOI(); } catch { } try { if ((int)val.State == 1) { val.SetState((QuestState)0); } } catch { } instance._iconApplied[i] = false; continue; } try { if ((int)val.State != 1) { val.Begin(); } } catch { } try { Vector3 val2 = RealEstateManager.SpotCandidates[i]; Vector3 val3 = val.POIPosition; if (((Vector3)(ref val3)).sqrMagnitude < 1f) { val.POIPosition = val2; } else { val3 = val.POIPosition - val2; if (((Vector3)(ref val3)).sqrMagnitude > 4f) { PoiIconHelper.MovePoi(val, val2); } } if (!instance._iconApplied[i]) { instance._iconApplied[i] = true; Sprite val4 = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val4 != (Object)null) { PoiIconHelper.ApplyAsync(val, val4); } } } catch { } } instance.SuppressJournalAndHud(); } catch (Exception ex) { NDLog.DebugWarn("DepositoMarkerQuest.Sync: " + ex.Message); } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { for (int i = 0; i < 3; i++) { QuestEntry val = Instance._entries[i]; if (val != null) { try { PoiIconHelper.SetPoiVisible(val, visible: false); } catch { } try { val.ClearPOI(); } catch { } try { val.Complete(); } catch { } } } } catch { } Instance = null; NDLog.Debug("[DEPOSITO] marker quest cleared."); } internal static void ClearInstanceForReload() { Instance = null; } public static void SuppressHud() { try { Instance?.SuppressJournalAndHud(); } catch { } } private void SuppressJournalAndHud() { try { Quest val = TryGetVanillaQuest(); if ((Object)(object)val == (Object)null) { return; } try { val.TrackOnBegin = false; } catch { } try { ((object)val).GetType().GetMethod("SetIsTracked", new Type[1] { typeof(bool) })?.Invoke(val, new object[1] { false }); } catch { } try { ((object)val).GetType().GetMethod("DestroyHUDUI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } try { ((object)val).GetType().GetMethod("DestroyJournalEntry", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } } catch { } } private Quest TryGetVanillaQuest() { try { Type type = ((object)this).GetType(); while (type != null) { PropertyInfo property = type.GetProperty("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object? value = property.GetValue(this); Quest val = (Quest)((value is Quest) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(Quest))) { object? value2 = fieldInfo.GetValue(this); Quest val2 = (Quest)((value2 is Quest) ? value2 : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } type = type.BaseType; } } catch { } return null; } } [QuestName("Faida")] internal sealed class FaidaMarkerQuestId : IQuestIdentifier { } internal sealed class FaidaMarkerQuest : Quest { internal const string DealPoiIconResource = "Ndrangheta.assets.veeper_icon.png"; private static string _pendingText = "Faida"; internal static FaidaMarkerQuest Instance { get; private set; } protected override string Title => "Faida"; protected override string Description => "The Benzies are moving a shipment. Get to the deal and take it from them."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public FaidaMarkerQuest() { EntryMain = ((Quest)this).AddEntry(_pendingText, (Vector3?)null); Instance = this; NDLog.Debug("[FAIDA] marker quest created."); } internal static void EnsureCreated(string text, Vector3 pos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { if (Instance != null) { SetText(text); MoveTo(pos); return; } _pendingText = text ?? "Faida"; string text2 = $"Ndrangheta.faida.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text2); if (Instance != null && ((Vector3)(ref pos)).sqrMagnitude > 1f) { Instance.EntryMain.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.veeper_icon.png") ?? AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(Instance.EntryMain, val); } } } catch (Exception ex) { NDLog.DebugWarn("FaidaMarkerQuest.EnsureCreated: " + ex.Message); } } internal static void SetText(string text) { try { if (Instance?.EntryMain != null && !string.IsNullOrEmpty(text)) { Instance.EntryMain.Title = text; } } catch { } } internal static void MoveTo(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if (Instance?.EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(Instance.EntryMain, pos); } } catch { } } internal static void SetPoiVisible(bool visible) { try { if (Instance?.EntryMain != null) { PoiIconHelper.SetPoiVisible(Instance.EntryMain, visible); } } catch { } } internal static void CompleteAndClear(bool fanfare = false) { if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } if (fanfare) { try { ((Quest)Instance).Complete(); } catch { } } Instance = null; NDLog.Debug(fanfare ? "[FAIDA] marker quest completed (fanfare)." : "[FAIDA] marker quest cleared."); } } [QuestName("Informanti")] internal sealed class InformantiMarkerQuestId : IQuestIdentifier { } internal sealed class InformantiMarkerQuest : Quest { private static string _pendingText = "Informanti"; internal static InformantiMarkerQuest Instance { get; private set; } protected override string Title => "Informanti"; protected override string Description => "An informant left word. Follow the marker."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public InformantiMarkerQuest() { EntryMain = ((Quest)this).AddEntry(_pendingText, (Vector3?)null); Instance = this; NDLog.Debug("[INFORMANTI] marker quest created."); } internal static void EnsureCreated(string text, Vector3 pos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { if (Instance != null) { SetText(text); MoveTo(pos); return; } _pendingText = text ?? "Informanti"; string text2 = $"Ndrangheta.informanti.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text2); if (Instance != null && ((Vector3)(ref pos)).sqrMagnitude > 1f) { Instance.EntryMain.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(Instance.EntryMain, val); } } } catch (Exception ex) { NDLog.DebugWarn("InformantiMarkerQuest.EnsureCreated: " + ex.Message); } } internal static void SetText(string text) { try { if (Instance?.EntryMain != null && !string.IsNullOrEmpty(text)) { Instance.EntryMain.Title = text; } } catch { } } internal static void MoveTo(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if (Instance?.EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(Instance.EntryMain, pos); } } catch { } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } Instance = null; NDLog.Debug("[INFORMANTI] marker quest cleared."); } } [QuestName("Meet the Don")] internal sealed class IntroQuestId : IQuestIdentifier { } internal sealed class IntroQuest : Quest { public const string QuestGuid = "Ndrangheta.intro"; private bool _iconApplied; protected override string Title => "Meet the Don"; protected override string Description => "Don Salvatore — capo of an 'Ndrangheta cell out of Calabria — wants a sit-down at the Gazebo in Suburbia. Show some respect. If you got the spine, he might take you on for trials."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMeet { get; private set; } internal static IntroQuest Instance { get; private set; } public IntroQuest() { EntryMeet = ((Quest)this).AddEntry("Meet Don Salvatore in Suburbia", (Vector3?)null); Instance = this; NDLog.Debug("IntroQuest constructed."); } public static void RefreshPoi() { //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_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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0082: 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_009e: Unknown result type (might be due to invalid IL or missing references) try { IntroQuest instance = Instance; if (instance == null || instance.EntryMeet == null) { return; } Vector3 val = ResolveDonPos(); if (((Vector3)(ref val)).sqrMagnitude < 100f) { return; } Vector3 val2 = instance.EntryMeet.POIPosition; bool flag = ((Vector3)(ref val2)).sqrMagnitude < 1f; if (flag) { instance.EntryMeet.POIPosition = val; } else { val2 = instance.EntryMeet.POIPosition - val; if (((Vector3)(ref val2)).sqrMagnitude > 0.25f) { PoiIconHelper.MovePoi(instance.EntryMeet, val); } } if (!instance._iconApplied && flag) { Sprite val3 = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val3 != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryMeet, val3); } instance._iconApplied = true; NDLog.Debug("IntroQuest POI icon scheduled (post-position-set)."); } } catch { } } private static Vector3 ResolveDonPos() { //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_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_0079: 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_0048: 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_0087: Unknown result type (might be due to invalid IL or missing references) try { NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).transform != (Object)null) { Vector3 position = ((Component)cachedGameNpc).transform.position; if (((Vector3)(ref position)).sqrMagnitude >= 100f) { return position; } } } catch { } if (DonSalvatoreNPC.TryGetSpawnPosition(out var pos) && ((Vector3)(ref pos)).sqrMagnitude >= 100f) { return pos; } return Vector3.zero; } private static NPC TryResolveDonS1ApiNpc() { try { return NPC.Get(); } catch { return null; } } public static void EnsureStarted() { //IL_0023: 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) try { if (Instance == null && QuestManager.GetQuestByName("Meet the Don") == null) { Vector3 val = ResolveDonPos(); if (!(((Vector3)(ref val)).sqrMagnitude < 100f)) { QuestManager.CreateQuest("Ndrangheta.intro"); NDLog.Debug("IntroQuest created."); RefreshPoi(); } } } catch (Exception ex) { NDLog.Warn("IntroQuest.EnsureStarted: " + ex.Message); } } public static void CompleteOnPlayerProximity() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 try { IntroQuest instance = Instance; if (instance?.EntryMeet != null && (int)instance.EntryMeet.State != 2) { instance.EntryMeet.Complete(); NDLog.Info("IntroQuest completed — player met the Don."); } } catch (Exception ex) { NDLog.Warn("IntroQuest.CompleteOnPlayerProximity: " + ex.Message); } } } [QuestName("Don Salvatore")] internal sealed class PersistentDonPresenceQuestId : IQuestIdentifier { } internal sealed class PersistentDonPresenceQuest : Quest { public const string QuestGuid = "Ndrangheta.don.presence"; private int _iconApplyAttempts; private float _nextIconApplyAt; protected override string Title => "Don Salvatore"; protected override string Description => "Don Salvatore holds court at the Gazebo in Suburbia. Pay your respects whenever the famiglia calls."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); public QuestEntry EntryPresence { get; private set; } internal static PersistentDonPresenceQuest Instance { get; private set; } public PersistentDonPresenceQuest() { EntryPresence = ((Quest)this).AddEntry("At the Gazebo", (Vector3?)null); Instance = this; Quest val = TryGetVanillaQuest(); if ((Object)(object)val != (Object)null) { try { val.TrackOnBegin = false; } catch { } } NDLog.Debug("PersistentDonPresenceQuest constructed."); } public static void EnsureStarted() { //IL_0023: 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) try { if (Instance == null && QuestManager.GetQuestByName("Don Salvatore") == null) { Vector3 val = ResolveDonPos(); if (!(((Vector3)(ref val)).sqrMagnitude < 100f)) { QuestManager.CreateQuest("Ndrangheta.don.presence"); NDLog.Debug("PersistentDonPresenceQuest created."); RefreshPoi(); } } } catch (Exception ex) { NDLog.Warn("PersistentDonPresenceQuest.EnsureStarted: " + ex.Message); } } public static void CompleteAndClear() { if (Instance == null) { return; } try { QuestEntry entryPresence = Instance.EntryPresence; if (entryPresence != null) { entryPresence.Complete(); } } catch { } Instance = null; NDLog.Debug("PersistentDonPresenceQuest cleared (boss phase — Don gone)."); } public static void RefreshPoi() { //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_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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0082: 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_009e: Unknown result type (might be due to invalid IL or missing references) try { PersistentDonPresenceQuest instance = Instance; if (instance == null || instance.EntryPresence == null) { return; } Vector3 val = ResolveDonPos(); if (((Vector3)(ref val)).sqrMagnitude < 100f) { return; } Vector3 val2 = instance.EntryPresence.POIPosition; bool flag = ((Vector3)(ref val2)).sqrMagnitude < 1f; if (flag) { instance.EntryPresence.POIPosition = val; } else { val2 = instance.EntryPresence.POIPosition - val; if (((Vector3)(ref val2)).sqrMagnitude > 0.25f) { PoiIconHelper.MovePoi(instance.EntryPresence, val); } } if (instance._iconApplyAttempts < 5 && (flag || Time.realtimeSinceStartup >= instance._nextIconApplyAt)) { Sprite val3 = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val3 != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryPresence, val3); instance._iconApplyAttempts++; instance._nextIconApplyAt = Time.realtimeSinceStartup + 15f; NDLog.Debug($"PersistentDonPresenceQuest POI icon scheduled (attempt {instance._iconApplyAttempts}/5)."); } } instance.SuppressJournalAndHud(); PoiIconHelper.ForceMapVisible(instance.EntryPresence); } catch { } } private static Vector3 ResolveDonPos() { //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_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_0079: 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_0048: 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_0087: Unknown result type (might be due to invalid IL or missing references) try { NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).transform != (Object)null) { Vector3 position = ((Component)cachedGameNpc).transform.position; if (((Vector3)(ref position)).sqrMagnitude >= 100f) { return position; } } } catch { } if (DonSalvatoreNPC.TryGetSpawnPosition(out var pos) && ((Vector3)(ref pos)).sqrMagnitude >= 100f) { return pos; } return Vector3.zero; } private Quest TryGetVanillaQuest() { try { Type type = ((object)this).GetType(); while (type != null) { PropertyInfo property = type.GetProperty("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object? value = property.GetValue(this); Quest val = (Quest)((value is Quest) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(Quest))) { object? value2 = fieldInfo.GetValue(this); Quest val2 = (Quest)((value2 is Quest) ? value2 : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } type = type.BaseType; } } catch { } return null; } private void SuppressJournalAndHud() { try { Quest val = TryGetVanillaQuest(); if ((Object)(object)val == (Object)null) { return; } try { val.TrackOnBegin = false; } catch { } try { ((object)val).GetType().GetMethod("SetIsTracked", new Type[1] { typeof(bool) })?.Invoke(val, new object[1] { false }); } catch { } try { ((object)val).GetType().GetMethod("DestroyHUDUI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } try { ((object)val).GetType().GetMethod("DestroyJournalEntry", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } } catch { } } } internal static class PizzoJobManager { public enum Phase { Idle, AwaitPickup, AwaitTrasportoDeliver, AwaitDropOff, Cooldown, AwaitKill, AwaitContrattoReturn, AwaitCaricoDeliver, AwaitCaricoDropOff, AwaitLuckyHit } public enum JobType { Pizzo, Trasporto, Contratto, Carico } public sealed class ActiveJob { public JobType Type; public string TargetName; public string TargetShopHint; public string DropName; public Vector3 DropPos; public string DropGuid; public string DropBName; public Vector3 DropBPos; public string DropBGuid; public int EnvelopeAmount; public int CutAmount; public int RewardAmount; public bool IsCurfew; public string ContrattoTargetName; public string ContrattoTargetCategory; public string CaricoItemId; public string CaricoItemDisplayName; public int CaricoQuantity; public int CaricoBonusBricks; public bool CaricoHeavenly; public string CaricoBonusItemId; public string CaricoBonusDisplayName; public string LuckyTargetName; public string LuckyTargetCategory; public string LuckyTargetRegion; public int LuckyMethod; public bool LuckyDispatched; } [Serializable] public sealed class JobSnapshot { public int Phase; public int JobType; public int CompletedCount; public float CooldownRemaining; public bool CashSpawned; public string TargetName; public string TargetShopHint; public string DropName; public string DropGuid; public float DropPosX; public float DropPosY; public float DropPosZ; public string DropBName; public string DropBGuid; public float DropBPosX; public float DropBPosY; public float DropBPosZ; public int EnvelopeAmount; public int CutAmount; public int RewardAmount; public bool IsCurfew; public string ContrattoTargetName; public string ContrattoTargetCategory; public string CaricoItemId; public string CaricoItemDisplayName; public int CaricoQuantity; public int CaricoBonusBricks; public int SchemaVersion; public string LuckyTargetName; public string LuckyTargetCategory; public string LuckyTargetRegion; public int LuckyMethod; public bool LuckyDispatched; public int DropoffBaseline = -1; } public const int PIZZO_SCHEMA = 1; public const int TRASPORTO_SCHEMA = 2; public const int CONTRATTO_SCHEMA = 1; public const int CARICO_SCHEMA = 1; public const float PickupRadius = 3.5f; public const float DropOffRadius = 4.5f; private const float HEARTBEAT_INTERVAL = 2f; private static float _hbTimer; private static bool _cashSpawned; public static NPC ActiveContrattoTarget; private const float FAIL_AFTER_FIRST_DAMAGE_SEC = 10f; private const float FAIL_AFTER_KO_SEC = 5f; private static float _damageStartedAt = -1f; private static float _koStartedAt = -1f; private const float RESOLVE_TIMEOUT_SEC = 30f; private static float _resolveDeadline = -1f; private static string _clientDropoffBy; private static int _dropoffStashBaseline = -1; private static float _dropoffDiagAt; private static bool _cashSeenInDrop; private static float _cashSeenDeadline; private static Random _rng = new Random(); private static float _tickWarnMuteUntil; private const int MAX_DROP_CASH = 5000; public static int EnvelopeAmount => RankManager.CurrentEnvelopeAmount; public static int CutAmount => RankManager.CurrentCutAmount; public static Phase CurrentPhase { get; private set; } = Phase.Idle; public static ActiveJob Current { get; private set; } public static float CooldownReadyAtRealtime { get; private set; } public static int CompletedCount { get; private set; } public static int ContrattiCompletedCount { get; private set; } public static int CoopPaySeq { get; private set; } public static int CoopPayAmount { get; private set; } public static string CoopPayExclude { get; private set; } = ""; internal static int SchemaForType(JobType t) { return t switch { JobType.Trasporto => 2, JobType.Contratto => 1, JobType.Carico => 1, _ => 1, }; } public static void LoadContrattiCount(int count) { ContrattiCompletedCount = count; } private static bool TryGetDropoffPoint(out Vector3 pos) { //IL_0002: 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_004c: 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) pos = Vector3.zero; try { if (TerritoryHandover.HandoverActive) { return DonSalvatoreNPC.ResolveGazeboPosition(out pos); } NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc == (Object)null || (Object)(object)((Component)cachedGameNpc).transform == (Object)null) { return false; } pos = ((Component)cachedGameNpc).transform.position; return true; } catch { return false; } } public static void EmitCoopPayoutExternal(int amount, string exclude, string label) { EmitCoopPayout(amount, exclude, label); } private static void EmitCoopPayout(int amount, string exclude, string label) { try { if (amount > 0 && LuckyNetSync.IsInLobby) { CoopPaySeq++; CoopPayAmount = amount; CoopPayExclude = exclude ?? ""; if (CoopPayExclude != "h") { PayoutHelper.AddCash(amount, "Famiglia coop share (" + label + ")"); } NDLog.Info($"[COOPPAY] seq={CoopPaySeq} amount=${amount} exclude='{CoopPayExclude}' ({label})."); } } catch (Exception ex) { NDLog.DebugWarn("EmitCoopPayout: " + ex.Message); } } public static void NotifyClientDropoff(string jobCode, string who) { try { if ((CurrentPhase == Phase.AwaitDropOff || CurrentPhase == Phase.AwaitCaricoDropOff || CurrentPhase == Phase.AwaitContrattoReturn) && _clientDropoffBy == null) { _clientDropoffBy = (string.IsNullOrEmpty(who) ? "client" : who); NDLog.Debug($"[CLIENTACT] dropoff accepted from '{_clientDropoffBy}' (job='{jobCode}', phase={CurrentPhase})."); } } catch { } } public static void ResetForSceneReload() { _hbTimer = 0f; CurrentPhase = Phase.Idle; Current = null; _clientDropoffBy = null; _dropoffStashBaseline = -1; CooldownReadyAtRealtime = 0f; _cashSpawned = false; ActiveContrattoTarget = null; _damageStartedAt = -1f; _koStartedAt = -1f; _resolveDeadline = -1f; try { DonMessaging.RemoveDeclineButton(); } catch { } try { PizzoQuest.ClearInstanceForNext(); } catch { } try { TrasportoQuest.ClearInstanceForNext(); } catch { } try { ContrattoQuest.ClearInstanceForNext(); } catch { } try { CaricoQuest.ClearInstanceForNext(); } catch { } } public static void Tick(float deltaTime) { _hbTimer -= deltaTime; if (_hbTimer > 0f) { return; } _hbTimer = 2f; try { switch (CurrentPhase) { case Phase.Idle: Tick_Idle(); break; case Phase.AwaitPickup: Tick_AwaitPickup(); break; case Phase.AwaitTrasportoDeliver: Tick_AwaitTrasportoDeliver(); break; case Phase.AwaitDropOff: Tick_AwaitDropOff(); break; case Phase.AwaitKill: Tick_AwaitKill(); break; case Phase.AwaitContrattoReturn: Tick_AwaitContrattoReturn(); break; case Phase.AwaitCaricoDeliver: Tick_AwaitCaricoDeliver(); break; case Phase.AwaitCaricoDropOff: Tick_AwaitCaricoDropOff(); break; case Phase.AwaitLuckyHit: Tick_AwaitLuckyHit(); break; case Phase.Cooldown: Tick_Cooldown(); break; } } catch (Exception ex) { if (Time.time >= _tickWarnMuteUntil) { _tickWarnMuteUntil = Time.time + 30f; NDLog.Warn($"PizzoJobManager.Tick ({CurrentPhase}): {ex.Message}"); } else { NDLog.DebugWarn($"PizzoJobManager.Tick ({CurrentPhase}): {ex.Message}"); } } } private static void Tick_Idle() { if (RecruitmentState.Recruited && !TerritoryHandover.HandoverActive && !(Time.timeSinceLevelLoad < CooldownReadyAtRealtime)) { if (CooldownReadyAtRealtime == 0f) { CooldownReadyAtRealtime = Time.timeSinceLevelLoad + 8f; } if (!(Time.timeSinceLevelLoad < CooldownReadyAtRealtime)) { StartNewJob(); } } } private static void CleanupOrphanQuests() { string[] array = new string[4] { "Il Pizzo", "Trasporto", "Contratto", "Carico" }; try { List quests = Quest.Quests; if (quests != null) { List list = new List(); for (int i = 0; i < quests.Count; i++) { Quest val; try { val = quests[i]; } catch { continue; } if ((Object)(object)val == (Object)null) { continue; } string text = null; try { text = val.Title; } catch { } if (string.IsNullOrEmpty(text)) { continue; } for (int j = 0; j < array.Length; j++) { if (text.Equals(array[j], StringComparison.OrdinalIgnoreCase) || text.StartsWith(array[j] + " ", StringComparison.OrdinalIgnoreCase) || text.StartsWith(array[j] + " —", StringComparison.Ordinal) || text.StartsWith(array[j] + " -", StringComparison.OrdinalIgnoreCase)) { list.Add(val); break; } } } foreach (Quest item in list) { try { item.Cancel(true); } catch { } try { item.End(); } catch { } } if (list.Count > 0) { NDLog.Debug($"CleanupOrphanQuests: cancelled {list.Count} orphan(s)."); } } } catch (Exception ex) { NDLog.DebugWarn("CleanupOrphanQuests vanilla-scan: " + ex.Message); } string[] array2 = array; foreach (string text2 in array2) { int num = 8; while (num-- > 0) { try { Quest questByName = QuestManager.GetQuestByName(text2); if (questByName == null) { break; } try { questByName.Cancel(); } catch { } try { questByName.End(); } catch { } continue; } catch { } break; } } try { PizzoQuest.ClearInstanceForNext(); } catch { } try { TrasportoQuest.ClearInstanceForNext(); } catch { } try { ContrattoQuest.ClearInstanceForNext(); } catch { } try { CaricoQuest.ClearInstanceForNext(); } catch { } } private static void StartNewJob() { BattesimoController.Stage currentStage = BattesimoController.CurrentStage; if (currentStage == BattesimoController.Stage.Awaiting || currentStage == BattesimoController.Stage.Bleeding) { RetrySoon("Battesimo in progress — pausing new jobs."); return; } CleanupOrphanQuests(); Rank currentRank = RankManager.CurrentRank; bool flag = BattesimoController.CurrentStage == BattesimoController.Stage.Completed; ConsentController.State currentState = ConsentController.CurrentState; bool flag2 = currentState == ConsentController.State.Unasked || currentState == ConsentController.State.Active; bool flag3 = flag && flag2; bool flag4 = CaricoJobPicker.IsUnlocked(currentRank); switch ((JobType)(flag3 ? 2 : ((currentRank != Rank.Picciotto) ? ((!flag4 || CompletedCount % 2 != 1) ? 1 : 3) : 0))) { case JobType.Contratto: StartContrattoJob(); break; case JobType.Trasporto: StartTrasportoJob(); break; case JobType.Carico: StartCaricoJob(); break; default: StartPizzoJob(); break; } } private static void RetrySoon(string reason) { NDLog.Warn("StartNewJob soft-retry in 30s: " + reason); CooldownReadyAtRealtime = Time.timeSinceLevelLoad + 30f; CurrentPhase = Phase.Cooldown; NdranghetaSaveData.Instance?.PushNow(); } private static void StartContrattoJob() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_018e: Unknown result type (might be due to invalid IL or missing references) ContrattoTargetPicker.Choice choice = ContrattoTargetPicker.PickRandom(_rng); if (choice == null || (Object)(object)choice.Npc == (Object)null) { RetrySoon("StartContrattoJob: no target available"); return; } int num = (int)((float)RankManager.CurrentInfo.EnvelopeAmount * 2f); int num2 = (int)((float)RankManager.CurrentInfo.CutAmount * 1.5f); Current = new ActiveJob { Type = JobType.Contratto, EnvelopeAmount = num, CutAmount = num2, ContrattoTargetName = choice.DisplayName, ContrattoTargetCategory = choice.Category }; ActiveContrattoTarget = choice.Npc; _cashSpawned = false; _damageStartedAt = -1f; _koStartedAt = -1f; try { WeaponSpawner.ClearRevolverFromStash(); } catch { } WeaponSpawner.SpawnRevolverInStash(); string category = choice.Category; string text = category; DonMessaging.SendDon(LoreStrings.ContrattoOrderSms(categoryHint: (text == "cop") ? "A badge got too close to the family's books — finish them." : ((!(text == "own_dealer")) ? "A shopkeeper has been a problem. End it." : "One of your dealers is talking to people who shouldn't hear. The 'Ndrina has decided."), greeting: RankManager.CurrentGreeting, targetName: choice.DisplayName, env: num, playerShare: num - num2)); DonMessaging.RegisterDeclineButton(CancelCurrentJob); ContrattoQuest.EnsureCreated(); Vector3 targetPos = (((Object)(object)((Component)choice.Npc).transform != (Object)null) ? ((Component)choice.Npc).transform.position : Vector3.zero); ContrattoQuest.Instance?.Apply(choice.DisplayName, targetPos); CurrentPhase = Phase.AwaitKill; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Contratto job started: target='{choice.DisplayName}' category={choice.Category} env=${num}"); } private static void Tick_AwaitKill() { //IL_0234: 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) if (Current == null) { CurrentPhase = Phase.Idle; return; } NPC val = ActiveContrattoTarget; if ((Object)(object)val == (Object)null) { try { val = NPCManager.GetNPC(LookupNpcIdByDisplayName(Current.ContrattoTargetName) ?? ""); } catch { } if ((Object)(object)val == (Object)null) { if (_resolveDeadline > 0f && Time.realtimeSinceStartup > _resolveDeadline) { NDLog.Warn($"Tick_AwaitKill: target '{Current.ContrattoTargetName}' not resolvable after {30f:F0}s — discarding job."); DiscardActiveJob(); } return; } ActiveContrattoTarget = val; _resolveDeadline = -1f; try { if ((Object)(object)((Component)val).transform != (Object)null) { ContrattoQuest.ReapplyKillTarget(((Component)val).transform.position); } } catch { } } try { NPCHealth health = val.Health; if ((Object)(object)health != (Object)null && !health.IsDead) { float realtimeSinceStartup = Time.realtimeSinceStartup; if (_damageStartedAt < 0f && health.Health < health.MaxHealth) { _damageStartedAt = realtimeSinceStartup; NDLog.Debug("Contratto: target damage started — 10s window opened."); } if (_koStartedAt < 0f && health.IsKnockedOut) { _koStartedAt = realtimeSinceStartup; NDLog.Debug("Contratto: target knocked out — 5s window opened."); } bool flag = _damageStartedAt > 0f && realtimeSinceStartup - _damageStartedAt >= 10f; bool flag2 = _koStartedAt > 0f && realtimeSinceStartup - _koStartedAt >= 5f; if (flag || flag2) { FailContratto(flag2 ? "you knocked them out but didn't finish — that's not how the famiglia works." : "you bloodied them and walked away. That's worse than not trying at all."); return; } } } catch (Exception ex) { NDLog.DebugWarn("Auto-failure check: " + ex.Message); } try { if ((Object)(object)((Component)val).transform != (Object)null) { ContrattoQuest.TrackKillTargetPosition(((Component)val).transform.position); } } catch { } if (KillDetector.IsDead(val)) { ContrattoQuest.CompleteKill(); DonMessaging.SendDon(LoreStrings.ContrattoKillAckSms(Current.EnvelopeAmount - Current.CutAmount)); CurrentPhase = Phase.AwaitContrattoReturn; NdranghetaSaveData.Instance?.PushNow(); NDLog.Debug("Contratto: target eliminated."); } } private static void FailContratto(string reason) { try { WeaponSpawner.ClearRevolverFromStash(); DonMessaging.RemoveDeclineButton(); DonMessaging.SendDon(LoreStrings.ContrattoFailedSms(reason)); ActiveContrattoTarget = null; _damageStartedAt = -1f; _koStartedAt = -1f; Current = null; _cashSpawned = false; try { ContrattoQuest.ClearInstanceForNext(); } catch { } CooldownReadyAtRealtime = Time.timeSinceLevelLoad + 60f; CurrentPhase = Phase.Cooldown; NdranghetaSaveData.Instance?.PushNow(); NDLog.Debug("Contratto auto-failed."); } catch (Exception ex) { NDLog.Warn("FailContratto: " + ex.Message); } } internal static void StartFamigliaContrattoFromChat() { //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (Current != null) { NDLog.DebugWarn("StartFamigliaContrattoFromChat: a job is already active, ignoring."); return; } CleanupOrphanQuests(); ContrattoTargetPicker.Choice choice = ContrattoTargetPicker.PickRandom(_rng); if (choice == null || (Object)(object)choice.Npc == (Object)null) { DonMessaging.SendDon("La famiglia has no marks for you right now. Try again later."); LuckyChatController.OpenMainMenu(); return; } int num = (int)((float)RankManager.CurrentInfo.EnvelopeAmount * 2f); int num2 = (int)((float)RankManager.CurrentInfo.CutAmount * 1.5f); Current = new ActiveJob { Type = JobType.Contratto, EnvelopeAmount = num, CutAmount = num2, ContrattoTargetName = choice.DisplayName, ContrattoTargetCategory = choice.Category }; ActiveContrattoTarget = choice.Npc; _cashSpawned = false; _damageStartedAt = -1f; _koStartedAt = -1f; try { WeaponSpawner.ClearRevolverFromStash(); } catch { } WeaponSpawner.SpawnRevolverInStash(); string category = choice.Category; string text = category; DonMessaging.SendDon(LoreStrings.FamigliaContrattoOrderSms(categoryHint: (text == "cop") ? "A badge got too close to the family's books — finish them." : ((!(text == "own_dealer")) ? "A shopkeeper has been a problem. End it." : "One of your dealers is talking to people who shouldn't hear. The 'Ndrina has decided."), targetName: choice.DisplayName, env: num, playerShare: num - num2)); DonMessaging.RegisterDeclineButton(CancelCurrentJob); ContrattoQuest.EnsureCreated(); Vector3 targetPos = (((Object)(object)((Component)choice.Npc).transform != (Object)null) ? ((Component)choice.Npc).transform.position : Vector3.zero); ContrattoQuest.Instance?.Apply(choice.DisplayName, targetPos); CurrentPhase = Phase.AwaitKill; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info("Famiglia contratto started: target='" + choice.DisplayName + "' category=" + choice.Category); } internal static void StartContrattoBossFromChat(LuckyTargetPicker.Choice pick, int method) { //IL_0125: 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_012a: 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) if (pick != null && !((Object)(object)pick.Npc == (Object)null)) { if (Current != null) { NDLog.DebugWarn("StartContrattoBossFromChat: a job is already active, ignoring."); return; } CleanupOrphanQuests(); int num = (int)((float)RankManager.CurrentInfo.EnvelopeAmount * 2f); int num2 = (int)((float)RankManager.CurrentInfo.CutAmount * 1.5f); int reward = num - num2; Current = new ActiveJob { Type = JobType.Contratto, EnvelopeAmount = num, CutAmount = num2, ContrattoTargetName = pick.DisplayName, ContrattoTargetCategory = pick.Category, LuckyTargetName = pick.DisplayName, LuckyTargetCategory = pick.Category, LuckyTargetRegion = ((object)Unsafe.As(ref pick.Region)/*cast due to .constrained prefix*/).ToString(), LuckyMethod = method, LuckyDispatched = true }; ActiveContrattoTarget = pick.Npc; _cashSpawned = false; _damageStartedAt = -1f; _koStartedAt = -1f; ContrattoQuest.EnsureCreated(); Transform targetTransform = pick.TargetTransform; Vector3 targetPos = (((Object)(object)targetTransform != (Object)null) ? targetTransform.position : Vector3.zero); ContrattoQuest.Instance?.Apply(pick.DisplayName, targetPos, method); LuckyController.Dispatch(pick.Npc, pick.PlayerTarget, method, reward, pick.DisplayName); CurrentPhase = Phase.AwaitLuckyHit; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Contratto boss dispatched: target='{pick.DisplayName}' method={method}"); } } internal static bool StartSmugglingFromChat(bool weapons) { //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_0128: 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_021c: 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) if (!SessionGate.IsAuthority) { return false; } if (Current != null) { NDLog.DebugWarn("StartSmugglingFromChat: a job is already active, ignoring."); return false; } CleanupOrphanQuests(); if (!PizzoDropPicker.PickTwoDistinct(_rng, out var a, out var b)) { DonMessaging.SendDon("No drop spots free right now. Try again in a bit."); LuckyChatController.OpenMainMenu(); return false; } CaricoJobPicker.Pick pick = (weapons ? new CaricoJobPicker.Pick { ItemId = "pumpshotgun", DisplayName = "Pump Shotgun", Quantity = 4, BonusBricks = 0, CashReward = 4000, HeavenlyQuality = false } : new CaricoJobPicker.Pick { ItemId = "cocaine", DisplayName = "Brick Cocaine", Quantity = 4, BonusBricks = 2, CashReward = 4500, HeavenlyQuality = true }); Current = new ActiveJob { Type = JobType.Carico, DropName = a.Name, DropPos = a.Position, DropGuid = a.DropGuid, DropBName = b.Name, DropBPos = b.Position, DropBGuid = b.DropGuid, EnvelopeAmount = 0, CutAmount = 0, RewardAmount = pick.CashReward, CaricoItemId = pick.ItemId, CaricoHeavenly = pick.HeavenlyQuality, CaricoBonusItemId = pick.BonusItemId, CaricoBonusDisplayName = pick.BonusDisplayName, CaricoItemDisplayName = pick.DisplayName, CaricoQuantity = pick.Quantity, CaricoBonusBricks = pick.BonusBricks }; _cashSpawned = false; DonMessaging.SendDon(LoreStrings.CaricoOrderSms(RankManager.CurrentGreeting, pick.DisplayName, pick.ItemId, pick.Quantity, a.Name, b.Name, pick.CashReward, pick.BonusBricks)); CaricoQuest.EnsureCreated(); CaricoQuest.Instance?.Apply(pick.DisplayName, pick.ItemId, pick.Quantity, a.Name, a.Position, b.Name, b.Position, pick.CashReward); DonMessaging.RegisterDeclineButton(CancelCurrentJob); CurrentPhase = Phase.AwaitPickup; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Smuggling (chat) started: item='{pick.ItemId}' qty={pick.Quantity} A='{a.Name}' B='{b.Name}'"); return true; } internal static bool StartProtectionFromChat() { //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_0179: Unknown result type (might be due to invalid IL or missing references) if (!SessionGate.IsAuthority) { return false; } if (Current != null) { NDLog.DebugWarn("StartProtectionFromChat: a job is already active, ignoring."); return false; } CleanupOrphanQuests(); PizzoTargets.Target target = PizzoTargets.PickRandom(_rng); PizzoDropPicker.DropChoice dropChoice = PizzoDropPicker.PickRandom(_rng); if (target == null || dropChoice == null) { DonMessaging.SendDon("No collection lined up right now. Try again in a bit."); LuckyChatController.OpenMainMenu(); return false; } Current = new ActiveJob { Type = JobType.Pizzo, TargetName = target.DisplayName, TargetShopHint = target.ShopHint, DropName = dropChoice.Name, DropPos = dropChoice.Position, DropGuid = dropChoice.DropGuid, EnvelopeAmount = EnvelopeAmount, CutAmount = CutAmount }; _cashSpawned = false; if (TerritoryHandover.HandoverActive) { DonMessaging.SendDon(LoreStrings.PizzoOrderSmsBoss(target.DisplayName, target.ShopHint, EnvelopeAmount, CutAmount, dropChoice.Name)); } else { string currentGreeting = RankManager.CurrentGreeting; string trialTag = LoreStrings.TrialTag(RankManager.CurrentRank, LoreStrings.JobTrialKind.Normal); DonMessaging.SendDon(LoreStrings.PizzoOrderSms(currentGreeting, trialTag, target.DisplayName, target.ShopHint, EnvelopeAmount, CutAmount, dropChoice.Name)); } PizzoQuest.EnsureCreated(); PizzoQuest.Instance?.Apply(target.DisplayName, dropChoice.Name, dropChoice.Position, CutAmount); DonMessaging.RegisterDeclineButton(CancelCurrentJob); CurrentPhase = Phase.AwaitPickup; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info("Protection (chat) started: target='" + target.DisplayName + "' drop='" + dropChoice.Name + "'"); return true; } private static void Tick_AwaitLuckyHit() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (Current == null) { CurrentPhase = Phase.Idle; return; } try { NPC activeContrattoTarget = ActiveContrattoTarget; if ((Object)(object)activeContrattoTarget != (Object)null && (Object)(object)((Component)activeContrattoTarget).transform != (Object)null) { ContrattoQuest.TrackKillTargetPosition(((Component)activeContrattoTarget).transform.position); } } catch { } if (!LuckyController.TickHit(out var reward)) { if (!LuckyController.IsDispatching) { if (LuckyController.ConsumeLuckyDownAbort()) { DonMessaging.SendDon(LoreStrings.LuckyDownSms(Current.LuckyTargetName ?? "the mark")); NDLog.Warn("Lucky job aborted (Lucky down/KO) — rolling back without reward."); } else { NDLog.Warn("Lucky job aborted (target not neutralized) — rolling back without reward."); } DiscardActiveJob(); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } return; } int reward2 = LuckyController.DepositRewardInGazebo(reward); try { ContrattoQuest.CompleteKill(); } catch { } try { ContrattoQuest.CompleteReturn(); } catch { } string text = ((Current.LuckyMethod == 1) ? LoreStrings.LuckyBeatdownDoneSms(Current.LuckyTargetName ?? "the mark", reward2) : LoreStrings.LuckyKilledSms(Current.LuckyTargetName ?? "the mark", reward2)); DonMessaging.SendDon(text); CompletedCount++; ContrattiCompletedCount++; RankManager.CheckPromotion(CompletedCount); CooldownReadyAtRealtime = Time.timeSinceLevelLoad + (float)ModConfig.JobCooldownSeconds; Current = null; ActiveContrattoTarget = null; _cashSpawned = false; CurrentPhase = Phase.Cooldown; try { ContrattoQuest.ClearInstanceForNext(); } catch { } NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Lucky boss-contratto complete. Total={CompletedCount}, contratti={ContrattiCompletedCount}"); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static string LookupNpcIdByDisplayName(string displayName) { if (string.IsNullOrEmpty(displayName)) { return null; } PizzoTargets.Target target = PizzoTargets.FindByName(displayName); if (target != null) { return target.NpcId; } return displayName.ToLowerInvariant().Replace(' ', '_'); } private static void Tick_AwaitContrattoReturn() { //IL_007c: 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) if (Current == null) { CurrentPhase = Phase.Idle; _clientDropoffBy = null; return; } if (_clientDropoffBy == null) { if (!TryGetDropoffPoint(out var pos)) { return; } Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null) { return; } float num = HorizontalDistanceSq(((Component)local).transform.position, pos); if (num > 20.25f) { return; } } int num2 = Current.EnvelopeAmount - Current.CutAmount; bool flag = false; if (RealEstateManager.VillaOwned) { flag = PayoutHelper.AddOnlineBalance(num2, "Famiglia reward (Contratto)"); } if (!flag) { List deadDrops = DeadDrop.DeadDrops; if (deadDrops != null) { for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val = deadDrops[i]; string text = null; try { text = val?.DeadDropName; } catch { } if (!string.IsNullOrEmpty(text) && text.IndexOf("Gazebo", StringComparison.OrdinalIgnoreCase) >= 0) { DeadDropCashHelper.SpawnCashInDrop(val, num2); break; } } } } ContrattoQuest.CompleteReturn(); WeaponSpawner.ClearRevolverFromStash(); DonMessaging.RemoveDeclineButton(); DonMessaging.SendDon(flag ? LoreStrings.ContrattoCompleteSmsOnline(num2) : LoreStrings.ContrattoCompleteSms(num2)); CompletedCount++; ContrattiCompletedCount++; RankManager.CheckPromotion(CompletedCount); ConsentController.OnContrattoCompleted(); TerritoryHandover.OnContrattoCompleted(ContrattiCompletedCount); CooldownReadyAtRealtime = Time.timeSinceLevelLoad + (float)ModConfig.JobCooldownSeconds; Current = null; ActiveContrattoTarget = null; _cashSpawned = false; _damageStartedAt = -1f; _koStartedAt = -1f; _clientDropoffBy = null; CurrentPhase = Phase.Cooldown; try { ContrattoQuest.ClearInstanceForNext(); } catch { } NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Contratto job complete. Total={CompletedCount}"); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static void StartPizzoJob() { //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_013c: Unknown result type (might be due to invalid IL or missing references) PizzoTargets.Target target = PizzoTargets.PickRandom(_rng); if (target == null) { return; } PizzoDropPicker.DropChoice dropChoice = PizzoDropPicker.PickRandom(_rng); if (dropChoice == null) { NDLog.Warn("StartPizzoJob: no DeadDrop."); return; } Current = new ActiveJob { Type = JobType.Pizzo, TargetName = target.DisplayName, TargetShopHint = target.ShopHint, DropName = dropChoice.Name, DropPos = dropChoice.Position, DropGuid = dropChoice.DropGuid, EnvelopeAmount = EnvelopeAmount, CutAmount = CutAmount }; _cashSpawned = false; if (TerritoryHandover.HandoverActive) { DonMessaging.SendDon(LoreStrings.PizzoOrderSmsBoss(target.DisplayName, target.ShopHint, EnvelopeAmount, CutAmount, dropChoice.Name)); } else { string currentGreeting = RankManager.CurrentGreeting; string trialTag = LoreStrings.TrialTag(RankManager.CurrentRank, LoreStrings.JobTrialKind.Normal); DonMessaging.SendDon(LoreStrings.PizzoOrderSms(currentGreeting, trialTag, target.DisplayName, target.ShopHint, EnvelopeAmount, CutAmount, dropChoice.Name)); } PizzoQuest.EnsureCreated(); PizzoQuest.Instance?.Apply(target.DisplayName, dropChoice.Name, dropChoice.Position, CutAmount); DonMessaging.RegisterDeclineButton(CancelCurrentJob); CurrentPhase = Phase.AwaitPickup; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info("Pizzo job started: target='" + target.DisplayName + "' drop='" + dropChoice.Name + "'"); } private static void StartTrasportoJob() { //IL_0122: 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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0201: 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) if (!PizzoDropPicker.PickTwoDistinct(_rng, out var a, out var b)) { RetrySoon("StartTrasportoJob: not enough DeadDrops"); return; } bool flag = CurfewHelper.IsCurfewActive(); int num = RankManager.CurrentInfo.TrasportoEnvelope; int num2 = RankManager.CurrentInfo.TrasportoCut; int num3 = RankManager.CurrentInfo.TrasportoReward; if (flag) { num = (int)((float)num * 2f); num2 = (int)((float)num2 * 2f); num3 = (int)((float)num3 * 2f); } if (num > 5000) { int num4 = num; int num5 = num2; if (num4 > 0) { num2 = (int)((float)num2 * 5000f / (float)num4); } num = 5000; NDLog.Debug($"Trasporto cash capped: env {num4} -> {num}, cut {num5} -> {num2} (DeadDrop max $5000)."); } Current = new ActiveJob { Type = JobType.Trasporto, TargetName = "", TargetShopHint = "", DropName = a.Name, DropPos = a.Position, DropGuid = a.DropGuid, DropBName = b.Name, DropBPos = b.Position, DropBGuid = b.DropGuid, EnvelopeAmount = num, CutAmount = num2, RewardAmount = num3, IsCurfew = flag }; _cashSpawned = false; string currentGreeting = RankManager.CurrentGreeting; string trialTag = LoreStrings.TrialTag(RankManager.CurrentRank, LoreStrings.JobTrialKind.Heavier); int bAmount = num - num2; int donAmount = num2; string text = (flag ? LoreStrings.CurfewTrasportoOrderSms(currentGreeting, num, a.Name, bAmount, b.Name, donAmount, num3) : LoreStrings.TrasportoOrderSms(currentGreeting, trialTag, num, a.Name, bAmount, b.Name, donAmount, num3)); DonMessaging.SendDon(text); TrasportoQuest.EnsureCreated(); TrasportoQuest.Instance?.Apply(a.Name, a.Position, b.Name, b.Position, num, num2, num3); DonMessaging.RegisterDeclineButton(CancelCurrentJob); CurrentPhase = Phase.AwaitPickup; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Trasporto job started: A='{a.Name}' B='{b.Name}' env=${num} cut=${num2} curfew={flag}"); } private static void StartCaricoJob() { //IL_0082: 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_00a6: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) if (!PizzoDropPicker.PickTwoDistinct(_rng, out var a, out var b)) { RetrySoon("StartCaricoJob: not enough DeadDrops"); return; } CaricoJobPicker.Pick pick = CaricoJobPicker.PickForRank(RankManager.CurrentRank, _rng); if (pick == null || pick.Quantity <= 0) { NDLog.Warn("StartCaricoJob: no resolvable contraband for current rank — fallback to Trasporto."); StartTrasportoJob(); return; } Current = new ActiveJob { Type = JobType.Carico, DropName = a.Name, DropPos = a.Position, DropGuid = a.DropGuid, DropBName = b.Name, DropBPos = b.Position, DropBGuid = b.DropGuid, EnvelopeAmount = 0, CutAmount = 0, RewardAmount = pick.CashReward, CaricoItemId = pick.ItemId, CaricoHeavenly = pick.HeavenlyQuality, CaricoBonusItemId = pick.BonusItemId, CaricoBonusDisplayName = pick.BonusDisplayName, CaricoItemDisplayName = pick.DisplayName, CaricoQuantity = pick.Quantity, CaricoBonusBricks = pick.BonusBricks }; _cashSpawned = false; string currentGreeting = RankManager.CurrentGreeting; DonMessaging.SendDon(LoreStrings.CaricoOrderSms(currentGreeting, pick.DisplayName, pick.ItemId, pick.Quantity, a.Name, b.Name, pick.CashReward, pick.BonusBricks)); CaricoQuest.EnsureCreated(); CaricoQuest.Instance?.Apply(pick.DisplayName, pick.ItemId, pick.Quantity, a.Name, a.Position, b.Name, b.Position, pick.CashReward); DonMessaging.RegisterDeclineButton(CancelCurrentJob); CurrentPhase = Phase.AwaitPickup; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Carico job started: item='{pick.ItemId}' qty={pick.Quantity} A='{a.Name}' B='{b.Name}' reward=${pick.CashReward}"); } private static void CancelCurrentJob() { try { ActiveJob current = Current; if (current == null) { return; } if (_cashSpawned && !string.IsNullOrEmpty(current.DropGuid)) { try { DeadDrop val = DeadDropCashHelper.FindDropByGuid(current.DropGuid); if ((Object)(object)val != (Object)null) { if (current.Type == JobType.Carico && !string.IsNullOrEmpty(current.CaricoItemId)) { RewardSpawner.RemoveItemFromDrop(val, current.CaricoItemId); } else { WorldStorageEntity storage = val.Storage; List list = ((storage != null) ? ((StorageEntity)storage).ItemSlots : null); if (list != null) { for (int num = list.Count - 1; num >= 0; num--) { ItemSlot val2 = list[num]; ItemInstance val3 = ((val2 != null) ? val2.ItemInstance : null); if (val3 != null && GameCompat.CastObj((object)val3) != null) { try { val2.ClearStoredInstance(false); } catch { } } } } } } } catch (Exception ex) { NDLog.DebugWarn("Cancel cleanup: " + ex.Message); } } if (!TerritoryHandover.HandoverActive) { DonMessaging.SendDon("Capito. Job's off the table. I'll text you again in a minute."); } if (current.Type == JobType.Contratto) { WeaponSpawner.ClearRevolverFromStash(); ActiveContrattoTarget = null; _damageStartedAt = -1f; _koStartedAt = -1f; } Current = null; _cashSpawned = false; try { CleanupOrphanQuests(); } catch (Exception ex2) { NDLog.DebugWarn("Cancel cleanup quests: " + ex2.Message); } try { PizzoQuest.ClearInstanceForNext(); } catch { } try { TrasportoQuest.ClearInstanceForNext(); } catch { } try { ContrattoQuest.ClearInstanceForNext(); } catch { } try { CaricoQuest.ClearInstanceForNext(); } catch { } CooldownReadyAtRealtime = Time.timeSinceLevelLoad + 60f; CurrentPhase = Phase.Cooldown; NdranghetaSaveData.Instance?.PushNow(); NDLog.Debug("Job declined by player."); try { LuckyChatController.RefreshIfHandoverActive(); } catch (Exception ex3) { NDLog.DebugWarn("Lucky refresh after decline: " + ex3.Message); } } catch (Exception ex4) { NDLog.Warn("CancelCurrentJob: " + ex4.Message); } } private static void Tick_AwaitPickup() { if (Current == null) { CurrentPhase = Phase.Idle; return; } if (Current.Type == JobType.Carico) { if (!_cashSpawned) { DeadDrop val = DeadDropCashHelper.FindDropByGuid(Current.DropGuid); if ((Object)(object)val == (Object)null) { return; } int num = RewardSpawner.SpawnItemInDrop(val, Current.CaricoItemId, Current.CaricoQuantity, Current.CaricoHeavenly); if (num > 0) { if (num < Current.CaricoQuantity) { NDLog.Warn($"Carico pickup partial: {num}/{Current.CaricoQuantity} fit in '{Current.DropName}'. Adjusting quest target."); Current.CaricoQuantity = num; } _cashSpawned = true; NdranghetaSaveData.Instance?.PushNow(); } } else { DeadDrop val2 = DeadDropCashHelper.FindDropByGuid(Current.DropGuid); if (!((Object)(object)val2 == (Object)null) && RewardSpawner.GetTotalQuantityInDrop(val2, Current.CaricoItemId) <= 0) { CaricoQuest.CompletePickup(); DonMessaging.SendDon(LoreStrings.CaricoPickupAckSms(Current.CaricoQuantity, Current.CaricoItemDisplayName, Current.CaricoItemId, Current.DropBName)); CurrentPhase = Phase.AwaitCaricoDeliver; NdranghetaSaveData.Instance?.PushNow(); NDLog.Debug("Carico pickup complete."); } } return; } if (!_cashSpawned) { DeadDrop val3 = DeadDropCashHelper.FindDropByGuid(Current.DropGuid); if (!((Object)(object)val3 == (Object)null) && DeadDropCashHelper.SpawnCashInDrop(val3, Current.EnvelopeAmount)) { _cashSpawned = true; _cashSeenInDrop = false; _cashSeenDeadline = 0f; NdranghetaSaveData.Instance?.PushNow(); } return; } DeadDrop val4 = DeadDropCashHelper.FindDropByGuid(Current.DropGuid); if ((Object)(object)val4 == (Object)null) { return; } if (!_cashSeenInDrop) { if (DeadDropCashHelper.HasAnyCashInDrop(val4)) { _cashSeenInDrop = true; _cashSeenDeadline = 0f; } else if (_cashSeenDeadline <= 0f) { _cashSeenDeadline = Time.timeSinceLevelLoad + 10f; } else if (Time.timeSinceLevelLoad > _cashSeenDeadline) { NDLog.Warn("Pickup: envelope never appeared in '" + Current.DropName + "' — re-spawning (silent insert failure)."); _cashSpawned = false; _cashSeenDeadline = 0f; } } else if (!DeadDropCashHelper.HasAnyCashInDrop(val4)) { if (Current.Type == JobType.Trasporto) { TrasportoQuest.CompletePickup(); int bAmount = Current.EnvelopeAmount - Current.CutAmount; DonMessaging.SendDon(LoreStrings.TrasportoPickupAckSms(bAmount, Current.DropBName, Current.CutAmount)); CurrentPhase = Phase.AwaitTrasportoDeliver; } else { PizzoQuest.CompletePickup(); DonMessaging.SendDon(TerritoryHandover.HandoverActive ? LoreStrings.PizzoPickupAckSmsBoss(Current.CutAmount) : LoreStrings.PizzoPickupAckSms(Current.CutAmount)); _dropoffStashBaseline = -1; CurrentPhase = Phase.AwaitDropOff; } NdranghetaSaveData.Instance?.PushNow(); NDLog.Debug($"Pickup phase complete ({Current.Type})."); } } private static void Tick_AwaitTrasportoDeliver() { if (Current == null || Current.Type != JobType.Trasporto) { CurrentPhase = Phase.Idle; return; } DeadDrop val = DeadDropCashHelper.FindDropByGuid(Current.DropBGuid); if (!((Object)(object)val == (Object)null)) { int num = Current.EnvelopeAmount - Current.CutAmount; int totalCashInDrop = DeadDropCashHelper.GetTotalCashInDrop(val); if (totalCashInDrop >= num) { int num2 = DeadDropCashHelper.RemoveAllCashFromDrop(val); int num3 = Current.EnvelopeAmount - Current.CutAmount; TrasportoQuest.CompleteDeliver(); DonMessaging.SendDon(LoreStrings.TrasportoDeliverAckSms(Current.RewardAmount)); _dropoffStashBaseline = -1; CurrentPhase = Phase.AwaitDropOff; NdranghetaSaveData.Instance?.PushNow(); NDLog.Debug($"Trasporto B verified: removed ${num2} from B, awaiting gazebo-stash dropoff for ${num3}."); } } } private static void Tick_AwaitCaricoDeliver() { if (Current == null || Current.Type != JobType.Carico) { CurrentPhase = Phase.Idle; return; } DeadDrop val = DeadDropCashHelper.FindDropByGuid(Current.DropBGuid); if ((Object)(object)val == (Object)null) { return; } int caricoQuantity = Current.CaricoQuantity; int totalQuantityInDrop = RewardSpawner.GetTotalQuantityInDrop(val, Current.CaricoItemId); if (totalQuantityInDrop < caricoQuantity) { return; } int num = RewardSpawner.RemoveItemFromDrop(val, Current.CaricoItemId, caricoQuantity); CaricoQuest.CompleteDeliver(); CaricoQuest.CompleteDropOff(); int rewardAmount = Current.RewardAmount; if (rewardAmount > 0) { PayoutHelper.AddCash(rewardAmount, "Famiglia reward (Carico)"); } EmitCoopPayout(rewardAmount, "h", "Carico"); int num2 = 0; if (Current.CaricoBonusBricks > 0) { DeadDrop val2 = FindGazeboDrop(); if ((Object)(object)val2 != (Object)null) { string itemId = ((!string.IsNullOrEmpty(Current.CaricoBonusItemId)) ? Current.CaricoBonusItemId : Current.CaricoItemId); num2 = RewardSpawner.SpawnItemInDrop(val2, itemId, Current.CaricoBonusBricks, Current.CaricoHeavenly); } } string itemDisplayName = ((!string.IsNullOrEmpty(Current.CaricoBonusDisplayName)) ? Current.CaricoBonusDisplayName : Current.CaricoItemDisplayName); DonMessaging.SendDon(LoreStrings.CaricoCompleteSms(rewardAmount, num2, itemDisplayName)); DonMessaging.RemoveDeclineButton(); CompletedCount++; RankManager.CheckPromotion(CompletedCount); CooldownReadyAtRealtime = Time.timeSinceLevelLoad + (float)ModConfig.JobCooldownSeconds; Current = null; _cashSpawned = false; _clientDropoffBy = null; CurrentPhase = Phase.Cooldown; try { CaricoQuest.ClearInstanceForNext(); } catch { } NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Carico complete (stash dropoff, no gazebo report): removed {num}, reward=${rewardAmount} bonus={num2}. Total={CompletedCount}"); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static void Tick_AwaitCaricoDropOff() { if (Current == null || Current.Type != JobType.Carico) { CurrentPhase = Phase.Idle; _clientDropoffBy = null; return; } bool flag = _clientDropoffBy != null; int rewardAmount = Current.RewardAmount; if (!flag && rewardAmount > 0) { PayoutHelper.AddCash(rewardAmount, "Famiglia reward (Carico)"); } EmitCoopPayout(rewardAmount, flag ? _clientDropoffBy : "h", "Carico"); int num = 0; if (Current.CaricoBonusBricks > 0) { DeadDrop val = FindGazeboDrop(); if ((Object)(object)val != (Object)null) { string itemId = ((!string.IsNullOrEmpty(Current.CaricoBonusItemId)) ? Current.CaricoBonusItemId : Current.CaricoItemId); num = RewardSpawner.SpawnItemInDrop(val, itemId, Current.CaricoBonusBricks, Current.CaricoHeavenly); } } CaricoQuest.CompleteDropOff(); string itemDisplayName = ((!string.IsNullOrEmpty(Current.CaricoBonusDisplayName)) ? Current.CaricoBonusDisplayName : Current.CaricoItemDisplayName); DonMessaging.SendDon(LoreStrings.CaricoCompleteSms(rewardAmount, num, itemDisplayName)); DonMessaging.RemoveDeclineButton(); CompletedCount++; RankManager.CheckPromotion(CompletedCount); CooldownReadyAtRealtime = Time.timeSinceLevelLoad + (float)ModConfig.JobCooldownSeconds; Current = null; _cashSpawned = false; _clientDropoffBy = null; CurrentPhase = Phase.Cooldown; try { CaricoQuest.ClearInstanceForNext(); } catch { } NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Carico complete: reward=${rewardAmount} bonus={num}. Total={CompletedCount}"); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static DeadDrop FindGazeboDrop() { try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null) { return null; } for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val = deadDrops[i]; string text = null; try { text = val?.DeadDropName; } catch { } if (!string.IsNullOrEmpty(text) && text.IndexOf("Gazebo", StringComparison.OrdinalIgnoreCase) >= 0) { return val; } } } catch { } return null; } private static void Tick_AwaitDropOff() { if (Current == null) { CurrentPhase = Phase.Idle; _clientDropoffBy = null; _dropoffStashBaseline = -1; return; } DeadDrop val = FindGazeboDrop(); if ((Object)(object)val == (Object)null) { return; } int totalCashInDrop = DeadDropCashHelper.GetTotalCashInDrop(val); if (_dropoffStashBaseline < 0) { _dropoffStashBaseline = totalCashInDrop; NDLog.Debug($"Drop-off baseline captured: ${totalCashInDrop} already in gazebo stash ({Current.Type})."); return; } if (totalCashInDrop < _dropoffStashBaseline) { _dropoffStashBaseline = totalCashInDrop; NDLog.Debug($"Drop-off baseline lowered to ${totalCashInDrop} (player took cash out of gazebo stash, {Current.Type})."); } int cutAmount = Current.CutAmount; if (totalCashInDrop - _dropoffStashBaseline < cutAmount) { if (Time.time >= _dropoffDiagAt) { _dropoffDiagAt = Time.time + 5f; NDLog.Debug($"Drop-off waiting: gazebo=${totalCashInDrop}, baseline=${_dropoffStashBaseline}, still need +${cutAmount - (totalCashInDrop - _dropoffStashBaseline)} ({Current.Type})."); } return; } int num = DeadDropCashHelper.RemoveAllCashFromDrop(val); int num2 = num - cutAmount; if (num2 > 0) { DeadDropCashHelper.SpawnCashInDrop(val, num2); } _dropoffStashBaseline = -1; NDLog.Info($"Don's ${cutAmount} cut collected from gazebo stash ({Current.Type}); ${((num2 > 0) ? num2 : 0)} left for the player."); if (Current.Type == JobType.Trasporto) { int rewardAmount = Current.RewardAmount; if (rewardAmount > 0) { PayoutHelper.AddCash(rewardAmount, "Famiglia reward (Trasporto)"); } EmitCoopPayout(rewardAmount, "h", "Trasporto"); TrasportoQuest.CompleteDropOff(); DonMessaging.SendDon(LoreStrings.TrasportoCompleteSms(rewardAmount)); DonMessaging.RemoveDeclineButton(); CompletedCount++; RankManager.CheckPromotion(CompletedCount); CooldownReadyAtRealtime = Time.timeSinceLevelLoad + (float)ModConfig.JobCooldownSeconds; Current = null; _cashSpawned = false; _clientDropoffBy = null; CurrentPhase = Phase.Cooldown; try { TrasportoQuest.ClearInstanceForNext(); } catch { } NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Trasporto complete: paid ${rewardAmount} reward (stash dropoff). Total={CompletedCount}"); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } EmitCoopPayout(Current.EnvelopeAmount - Current.CutAmount, "", "Pizzo"); PizzoQuest.CompleteDropOff(); DonMessaging.SendDon(TerritoryHandover.HandoverActive ? "The cassa is settled, Boss. The famiglia eats because of you." : "Grazie. The family remembers. I'll text you again soon."); DonMessaging.RemoveDeclineButton(); CompletedCount++; RankManager.CheckPromotion(CompletedCount); CooldownReadyAtRealtime = Time.timeSinceLevelLoad + (float)ModConfig.JobCooldownSeconds; JobType type = Current.Type; Current = null; _cashSpawned = false; _clientDropoffBy = null; CurrentPhase = Phase.Cooldown; try { PizzoQuest.ClearInstanceForNext(); } catch { } NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Pizzo complete. Total={CompletedCount}, rank={RankManager.CurrentRank}, cooldown {ModConfig.JobCooldownSeconds}s."); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static void Tick_Cooldown() { if (!(Time.timeSinceLevelLoad < CooldownReadyAtRealtime)) { CurrentPhase = Phase.Idle; NDLog.Debug("Pizzo cooldown elapsed — back to Idle."); } } public static JobSnapshot CaptureSnapshot() { return new JobSnapshot { Phase = (int)CurrentPhase, JobType = (int)(Current?.Type ?? JobType.Pizzo), CompletedCount = CompletedCount, CooldownRemaining = Mathf.Max(0f, CooldownReadyAtRealtime - Time.timeSinceLevelLoad), CashSpawned = _cashSpawned, TargetName = Current?.TargetName, TargetShopHint = Current?.TargetShopHint, DropName = Current?.DropName, DropGuid = Current?.DropGuid, DropPosX = (Current?.DropPos.x ?? 0f), DropPosY = (Current?.DropPos.y ?? 0f), DropPosZ = (Current?.DropPos.z ?? 0f), DropBName = Current?.DropBName, DropBGuid = Current?.DropBGuid, DropBPosX = (Current?.DropBPos.x ?? 0f), DropBPosY = (Current?.DropBPos.y ?? 0f), DropBPosZ = (Current?.DropBPos.z ?? 0f), EnvelopeAmount = (Current?.EnvelopeAmount ?? 0), CutAmount = (Current?.CutAmount ?? 0), RewardAmount = (Current?.RewardAmount ?? 0), IsCurfew = (Current?.IsCurfew ?? false), ContrattoTargetName = Current?.ContrattoTargetName, ContrattoTargetCategory = Current?.ContrattoTargetCategory, CaricoItemId = Current?.CaricoItemId, CaricoItemDisplayName = Current?.CaricoItemDisplayName, CaricoQuantity = (Current?.CaricoQuantity ?? 0), CaricoBonusBricks = (Current?.CaricoBonusBricks ?? 0), SchemaVersion = ((Current != null) ? SchemaForType(Current.Type) : 0), LuckyTargetName = Current?.LuckyTargetName, LuckyTargetCategory = Current?.LuckyTargetCategory, LuckyTargetRegion = Current?.LuckyTargetRegion, LuckyMethod = (Current?.LuckyMethod ?? 0), LuckyDispatched = (Current?.LuckyDispatched ?? false), DropoffBaseline = _dropoffStashBaseline }; } public static void LoadFromSnapshot(JobSnapshot snap) { //IL_0705: Unknown result type (might be due to invalid IL or missing references) //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_06d4: 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_01e4: 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_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_07e7: Unknown result type (might be due to invalid IL or missing references) //IL_07fb: Unknown result type (might be due to invalid IL or missing references) //IL_0955: Unknown result type (might be due to invalid IL or missing references) //IL_08c8: Unknown result type (might be due to invalid IL or missing references) //IL_08dc: Unknown result type (might be due to invalid IL or missing references) //IL_065f: 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) try { CompletedCount = snap.CompletedCount; CooldownReadyAtRealtime = Time.timeSinceLevelLoad + snap.CooldownRemaining; _cashSpawned = snap.CashSpawned; _resolveDeadline = -1f; if (!Enum.IsDefined(typeof(Phase), snap.Phase)) { NDLog.Warn($"LoadFromSnapshot: unknown phase={snap.Phase} — discarding stale active job (code schema changed)."); DiscardActiveJob(); return; } CurrentPhase = (Phase)snap.Phase; if (snap.Phase == 1 || snap.Phase == 2 || snap.Phase == 3 || snap.Phase == 5 || snap.Phase == 6 || snap.Phase == 7 || snap.Phase == 8 || snap.Phase == 9) { if (!Enum.IsDefined(typeof(JobType), snap.JobType)) { NDLog.Warn($"LoadFromSnapshot: unknown jobType={snap.JobType} — discarding stale job."); DiscardActiveJob(); return; } JobType jobType = (JobType)snap.JobType; int num = SchemaForType(jobType); if (snap.SchemaVersion != 0 && snap.SchemaVersion != num) { NDLog.Warn($"LoadFromSnapshot: schema mismatch jobType={jobType} saved={snap.SchemaVersion} expected={num} — discarding stale job."); DiscardActiveJob(); return; } Current = new ActiveJob { Type = jobType, TargetName = snap.TargetName, TargetShopHint = snap.TargetShopHint, DropName = snap.DropName, DropGuid = snap.DropGuid, DropPos = new Vector3(snap.DropPosX, snap.DropPosY, snap.DropPosZ), DropBName = snap.DropBName, DropBGuid = snap.DropBGuid, DropBPos = new Vector3(snap.DropBPosX, snap.DropBPosY, snap.DropBPosZ), EnvelopeAmount = snap.EnvelopeAmount, CutAmount = snap.CutAmount, RewardAmount = snap.RewardAmount, IsCurfew = snap.IsCurfew, ContrattoTargetName = snap.ContrattoTargetName, ContrattoTargetCategory = snap.ContrattoTargetCategory, CaricoItemId = snap.CaricoItemId, CaricoItemDisplayName = snap.CaricoItemDisplayName, CaricoQuantity = snap.CaricoQuantity, CaricoBonusBricks = snap.CaricoBonusBricks, CaricoHeavenly = (RankManager.CurrentRank == Rank.Capodecina || RankManager.CurrentRank == Rank.Sottocapo), CaricoBonusItemId = ((RankManager.CurrentRank == Rank.Sottocapo) ? "cocaine" : null), CaricoBonusDisplayName = ((RankManager.CurrentRank == Rank.Sottocapo) ? "Cocaine" : null), LuckyTargetName = snap.LuckyTargetName, LuckyTargetCategory = snap.LuckyTargetCategory, LuckyTargetRegion = snap.LuckyTargetRegion, LuckyMethod = snap.LuckyMethod, LuckyDispatched = snap.LuckyDispatched }; if (PizzoDropPicker.TryResolveByGuid(snap.DropGuid, out var drop)) { Current.DropName = drop.Name; Current.DropPos = drop.Position; } if (jobType == JobType.Trasporto && PizzoDropPicker.TryResolveByGuid(snap.DropBGuid, out var drop2)) { Current.DropBName = drop2.Name; Current.DropBPos = drop2.Position; } if (jobType == JobType.Carico && PizzoDropPicker.TryResolveByGuid(snap.DropBGuid, out var drop3)) { Current.DropBName = drop3.Name; Current.DropBPos = drop3.Position; } if (jobType == JobType.Trasporto && Current.EnvelopeAmount > 5000) { int envelopeAmount = Current.EnvelopeAmount; int cutAmount = Current.CutAmount; if (envelopeAmount > 0) { Current.CutAmount = (int)((float)cutAmount * 5000f / (float)envelopeAmount); } Current.EnvelopeAmount = 5000; NDLog.Warn($"LoadFromSnapshot: Trasporto env {envelopeAmount} -> {Current.EnvelopeAmount}, " + $"cut {cutAmount} -> {Current.CutAmount} (drop-cap retrofit for old snapshot)."); } if (jobType == JobType.Carico && Current.CaricoQuantity > 5) { int caricoQuantity = Current.CaricoQuantity; Current.CaricoQuantity = 5; NDLog.Warn($"LoadFromSnapshot: Carico qty {caricoQuantity} -> {Current.CaricoQuantity} (DeadDrop-Cap retrofit)."); } if (snap.Phase != 9 && Current.DropPos == Vector3.zero) { NDLog.Warn("LoadFromSnapshot: drop A position zero (" + snap.DropName + ") — stale, discarding."); DiscardActiveJob(); return; } if (jobType == JobType.Trasporto && Current.DropBPos == Vector3.zero) { NDLog.Warn("LoadFromSnapshot: drop B position zero — stale Trasporto, discarding."); DiscardActiveJob(); return; } if (jobType == JobType.Carico && Current.DropBPos == Vector3.zero) { NDLog.Warn("LoadFromSnapshot: drop B position zero — stale Carico, discarding."); DiscardActiveJob(); return; } if (jobType == JobType.Carico && (string.IsNullOrEmpty(Current.CaricoItemId) || Current.CaricoQuantity <= 0)) { NDLog.Warn("LoadFromSnapshot: Carico missing item-id or quantity — discarding."); DiscardActiveJob(); return; } switch (jobType) { case JobType.Contratto: { ContrattoQuest.EnsureCreated(); Vector3 targetPos = Vector3.zero; try { NPC nPC = NPCManager.GetNPC(Current.ContrattoTargetName?.ToLowerInvariant() ?? ""); if ((Object)(object)nPC != (Object)null && (Object)(object)((Component)nPC).transform != (Object)null) { targetPos = ((Component)nPC).transform.position; ActiveContrattoTarget = nPC; } } catch { } if (snap.Phase == 9 && (Object)(object)ActiveContrattoTarget == (Object)null) { try { NPC val = LuckyTargetPicker.FindNpcByName(Current.LuckyTargetName); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform != (Object)null) { targetPos = ((Component)val).transform.position; ActiveContrattoTarget = val; } } catch { } } ContrattoQuest.Instance?.Apply(Current.ContrattoTargetName ?? "the mark", targetPos); if (snap.Phase == 6) { ContrattoQuest.CompleteKill(); } if (snap.Phase == 9 && (Object)(object)ActiveContrattoTarget != (Object)null) { int reward = Current.EnvelopeAmount - Current.CutAmount; LuckyController.Dispatch(ActiveContrattoTarget, null, Current.LuckyMethod, reward, Current.LuckyTargetName ?? "the mark"); } if (snap.Phase == 5 && (Object)(object)ActiveContrattoTarget == (Object)null) { _resolveDeadline = Time.realtimeSinceStartup + 30f; } break; } case JobType.Trasporto: TrasportoQuest.EnsureCreated(); TrasportoQuest.Instance?.Apply(Current.DropName, Current.DropPos, Current.DropBName, Current.DropBPos, Current.EnvelopeAmount, Current.CutAmount, Current.RewardAmount); if (snap.Phase == 2 || snap.Phase == 3) { TrasportoQuest.CompletePickup(); } if (snap.Phase == 3) { TrasportoQuest.CompleteDeliver(); _dropoffStashBaseline = snap.DropoffBaseline; } break; case JobType.Carico: CaricoQuest.EnsureCreated(); CaricoQuest.Instance?.Apply(Current.CaricoItemDisplayName ?? Current.CaricoItemId, Current.CaricoItemId, Current.CaricoQuantity, Current.DropName, Current.DropPos, Current.DropBName, Current.DropBPos, Current.RewardAmount); if (snap.Phase == 7 || snap.Phase == 8) { CaricoQuest.CompletePickup(); } if (snap.Phase == 8) { CaricoQuest.CompleteDeliver(); } break; default: PizzoQuest.EnsureCreated(); PizzoQuest.Instance?.Apply(Current.TargetName, Current.DropName, Current.DropPos, Current.CutAmount); if (snap.Phase == 3) { PizzoQuest.CompletePickup(); _dropoffStashBaseline = snap.DropoffBaseline; } break; } } else { Current = null; } if (Current != null && _cashSpawned && CurrentPhase == Phase.AwaitPickup && !string.IsNullOrEmpty(Current.DropGuid)) { try { DeadDrop val2 = DeadDropCashHelper.FindDropByGuid(Current.DropGuid); if ((Object)(object)val2 != (Object)null) { bool flag = false; if (!((Current.Type != JobType.Carico || string.IsNullOrEmpty(Current.CaricoItemId)) ? DeadDropCashHelper.HasAnyCashInDrop(val2) : (RewardSpawner.GetTotalQuantityInDrop(val2, Current.CaricoItemId) > 0))) { NDLog.Warn("LoadFromSnapshot: _cashSpawned=true but drop '" + Current.DropName + "' contains no '" + ((Current.Type == JobType.Carico) ? Current.CaricoItemId : "cash") + "' — re-arming spawn (prevents false auto-complete)."); _cashSpawned = false; } } } catch (Exception ex) { NDLog.DebugWarn("LoadFromSnapshot sanity-check: " + ex.Message); } } if (Current != null) { try { DonMessaging.RegisterDeclineButton(CancelCurrentJob); } catch (Exception ex2) { NDLog.DebugWarn("LoadFromSnapshot decline rebind: " + ex2.Message); } } else { try { DonMessaging.RemoveDeclineButton(); } catch { } } NDLog.Debug($"PizzoJobManager loaded snapshot: phase={CurrentPhase} count={CompletedCount} cooldown={snap.CooldownRemaining:F0}s cashSpawned={_cashSpawned}"); } catch (Exception ex3) { NDLog.Warn("LoadFromSnapshot failed: " + ex3.Message); } } private static float HorizontalDistanceSq(Vector3 a, Vector3 b) { //IL_0001: 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_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) float num = a.x - b.x; float num2 = a.z - b.z; return num * num + num2 * num2; } private static void DiscardActiveJob() { try { CleanupOrphanQuests(); } catch { } try { WeaponSpawner.ClearRevolverFromStash(); } catch { } try { DonMessaging.RemoveDeclineButton(); } catch { } Current = null; ActiveContrattoTarget = null; _cashSpawned = false; _damageStartedAt = -1f; _koStartedAt = -1f; _resolveDeadline = -1f; CurrentPhase = Phase.Cooldown; CooldownReadyAtRealtime = Time.timeSinceLevelLoad + 10f; try { NdranghetaSaveData.Instance?.PushNow(); } catch { } } } [QuestName("Il Pizzo")] internal sealed class PizzoQuestId : IQuestIdentifier { } internal sealed class PizzoQuest : Quest { public static string CurrentJobGuid; private string _titleText; private string _descriptionText; private Vector3 _donPos; protected override string Title => _titleText ?? "Il Pizzo"; protected override string Description => _descriptionText ?? "Collect protection money for the famiglia, then bring the boss his cut."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryPickup { get; private set; } public QuestEntry EntryDropOff { get; private set; } internal static PizzoQuest Instance { get; private set; } public PizzoQuest() { EntryPickup = ((Quest)this).AddEntry("Pick up the envelope", (Vector3?)null); EntryDropOff = ((Quest)this).AddEntry("Drop Don's cut at the Famiglia stash", (Vector3?)null); Instance = this; NDLog.Debug("PizzoQuest constructed."); } public void Apply(string targetName, string dropName, Vector3 dropPos, int cutAmount) { //IL_0043: 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_00aa: 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_00c0: 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) _titleText = LoreStrings.PizzoTitle(targetName); _descriptionText = LoreStrings.PizzoDescription(targetName, cutAmount); try { if (EntryPickup != null) { EntryPickup.Title = LoreStrings.PizzoEntryPickup(targetName, dropName); EntryPickup.POIPosition = dropPos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(EntryPickup, val); } } if (EntryDropOff != null) { EntryDropOff.Title = (TerritoryHandover.HandoverActive ? LoreStrings.PizzoEntryDropOffBoss(cutAmount) : LoreStrings.PizzoEntryDropOff(cutAmount)); Vector3 val2 = ResolveDropoffMarkerPos(); if (val2 != Vector3.zero) { _donPos = val2; EntryDropOff.POIPosition = val2; Sprite val3 = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val3 != (Object)null) { PoiIconHelper.ApplyAsync(EntryDropOff, val3); } } else { try { EntryDropOff.ClearPOI(); } catch { } } } } catch (Exception ex) { NDLog.Warn("PizzoQuest.Apply: " + ex.Message); } EnsureFirstEntryActive(); } private static Vector3 ResolveDonWorldPos() { //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_0069: 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_0021: 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_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) try { if (TerritoryHandover.HandoverActive) { if (DonSalvatoreNPC.ResolveGazeboPosition(out var pos)) { return pos; } return Vector3.zero; } NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).transform != (Object)null) { return ((Component)cachedGameNpc).transform.position; } } catch { } return Vector3.zero; } private static Vector3 ResolveDropoffMarkerPos() { //IL_0019: 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_000d: 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_0021: Unknown result type (might be due to invalid IL or missing references) try { if (SuburbiaPositions.TryResolveGazebo(out var pos)) { return pos; } } catch { } return ResolveDonWorldPos(); } public static void EnsureCreated() { try { if (Instance == null && QuestManager.GetQuestByName("Il Pizzo") == null) { CurrentJobGuid = $"Ndrangheta.pizzo.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(CurrentJobGuid); NDLog.Debug("PizzoQuest created."); } } catch (Exception ex) { NDLog.Warn("PizzoQuest.EnsureCreated: " + ex.Message); } } public static void CompletePickup() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 try { PizzoQuest instance = Instance; if (instance?.EntryPickup != null) { if ((int)instance.EntryPickup.State != 2) { instance.EntryPickup.Complete(); } if (instance.EntryDropOff != null && (int)instance.EntryDropOff.State == 0) { instance.EntryDropOff.Begin(); } ReapplyDropOffIcon(); NDLog.Debug("PizzoQuest pickup completed."); } } catch (Exception ex) { NDLog.Warn("CompletePickup: " + ex.Message); } } public static void EnsureFirstEntryActive() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { PizzoQuest instance = Instance; if (instance?.EntryPickup != null && (int)instance.EntryPickup.State == 0) { instance.EntryPickup.Begin(); } } catch { } } public static void CompleteDropOff() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 try { PizzoQuest instance = Instance; if (instance?.EntryDropOff != null && (int)instance.EntryDropOff.State != 2) { instance.EntryDropOff.Complete(); NDLog.Debug("PizzoQuest drop-off completed."); } } catch (Exception ex) { NDLog.Warn("CompleteDropOff: " + ex.Message); } } private static void ReapplyDropOffIcon() { //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_0023: 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_003b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) try { PizzoQuest instance = Instance; if (instance?.EntryDropOff != null) { Vector3 val = ResolveDropoffMarkerPos(); if (val == Vector3.zero) { val = instance._donPos; } if (val != Vector3.zero) { instance.EntryDropOff.POIPosition = val; } Sprite val2 = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val2 != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryDropOff, val2); } } } catch { } } public static void ClearInstanceForNext() { Instance = null; } } [QuestName("Kidnapping")] internal sealed class RapimentoMarkerQuestId : IQuestIdentifier { } internal sealed class RapimentoMarkerQuest : Quest { internal const string VanPoiIconResource = "Ndrangheta.assets.veeper_icon.png"; private static string _pendingText = "Kidnapping"; internal static RapimentoMarkerQuest Instance { get; private set; } protected override string Title => "Kidnapping"; protected override string Description => "Lure the mark to the van, drive them to the warehouse, and hand them over."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public RapimentoMarkerQuest() { EntryMain = ((Quest)this).AddEntry(_pendingText, (Vector3?)null); Instance = this; NDLog.Debug("[RAPIMENTO] marker quest created."); } internal static void EnsureCreated(string text, Vector3 pos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { if (Instance != null) { SetText(text); MoveTo(pos); return; } _pendingText = text ?? "Kidnapping"; string text2 = $"Ndrangheta.rapimento.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text2); if (Instance != null && ((Vector3)(ref pos)).sqrMagnitude > 1f) { Instance.EntryMain.POIPosition = pos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.veeper_icon.png") ?? AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(Instance.EntryMain, val); } } } catch (Exception ex) { NDLog.DebugWarn("RapimentoMarkerQuest.EnsureCreated: " + ex.Message); } } internal static void SetText(string text) { try { if (Instance?.EntryMain != null && !string.IsNullOrEmpty(text)) { Instance.EntryMain.Title = text; } } catch { } } internal static void MoveTo(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) try { if (Instance?.EntryMain != null && !(((Vector3)(ref pos)).sqrMagnitude < 1f)) { PoiIconHelper.MovePoi(Instance.EntryMain, pos); } } catch { } } internal static void SetPoiVisible(bool visible) { try { if (Instance?.EntryMain != null) { PoiIconHelper.SetPoiVisible(Instance.EntryMain, visible); } } catch { } } internal static void CompleteAndClear(bool fanfare = false) { if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } if (fanfare) { try { ((Quest)Instance).Complete(); } catch { } } Instance = null; NDLog.Debug(fanfare ? "[RAPIMENTO] marker quest completed (fanfare)." : "[RAPIMENTO] marker quest cleared."); } } [QuestName("FamigliaInterrogation")] internal sealed class TortureClientMirrorQuestId : IQuestIdentifier { } internal sealed class TortureClientMirrorQuest : Quest { private static string _pendingTitle = "Operation"; private static string _pendingLabel = ""; private string _title; private string _label; internal static TortureClientMirrorQuest Instance { get; private set; } protected override string Title => string.IsNullOrEmpty(_title) ? "Operation" : _title; protected override string Description => string.IsNullOrEmpty(_label) ? "Handle the mark." : _label; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryMain { get; private set; } public TortureClientMirrorQuest() { _title = _pendingTitle; _label = _pendingLabel; EntryMain = ((Quest)this).AddEntry(string.IsNullOrEmpty(_pendingLabel) ? "Handle the mark." : _pendingLabel, (Vector3?)null); Instance = this; NDLog.Debug("[CLIENTTORTURE] torture mirror quest started: '" + _pendingTitle + "' / '" + _pendingLabel + "'"); } internal static void EnsureCreated(string title, string label) { if (Instance != null) { return; } try { _pendingTitle = (string.IsNullOrEmpty(title) ? "Operation" : title); _pendingLabel = label ?? ""; string text = $"Ndrangheta.clienttorture.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(text); } catch (Exception ex) { NDLog.DebugWarn("TortureClientMirrorQuest.EnsureCreated: " + ex.Message); } } internal static void UpdateLabel(string label) { if (Instance == null || Instance.EntryMain == null) { return; } try { if (!string.IsNullOrEmpty(label) && !string.Equals(label, Instance._label, StringComparison.Ordinal)) { Instance._label = label; try { Instance.EntryMain.Title = label; return; } catch { return; } } } catch (Exception ex) { NDLog.DebugWarn("TortureClientMirrorQuest.UpdateLabel: " + ex.Message); } } internal static void CompleteAndClear() { if (Instance == null) { return; } try { QuestEntry entryMain = Instance.EntryMain; if (entryMain != null) { entryMain.Complete(); } } catch { } Instance = null; NDLog.Debug("[CLIENTTORTURE] torture mirror quest cleared."); } } [QuestName("Trasporto")] internal sealed class TrasportoQuestId : IQuestIdentifier { } internal sealed class TrasportoQuest : Quest { public static string CurrentJobGuid; private string _titleText; private string _descriptionText; private Vector3 _bPos; private Vector3 _donPos; protected override string Title => _titleText ?? "Trasporto"; protected override string Description => _descriptionText ?? "Move the cassa from one drop to another, then collect your share from the Don."; protected override bool AutoBegin => true; protected override Sprite QuestIcon => AssetLoader.LoadSprite("Ndrangheta.assets.don_quest.png"); public QuestEntry EntryPickup { get; private set; } public QuestEntry EntryDeliver { get; private set; } public QuestEntry EntryDropOff { get; private set; } internal static TrasportoQuest Instance { get; private set; } public TrasportoQuest() { EntryPickup = ((Quest)this).AddEntry("Pick up the cassa", (Vector3?)null); EntryDeliver = ((Quest)this).AddEntry("Deliver the cassa", (Vector3?)null); EntryDropOff = ((Quest)this).AddEntry("Collect your share from the Don", (Vector3?)null); Instance = this; NDLog.Debug("TrasportoQuest constructed."); } public void Apply(string aName, Vector3 aPos, string bName, Vector3 bPos, int envelope, int cut, int reward) { //IL_0053: 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_00a7: 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_0118: 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_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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) int bAmount = envelope - cut; _titleText = LoreStrings.TrasportoTitle(aName, bName); _descriptionText = LoreStrings.TrasportoDescription(aName, bName, envelope, bAmount, cut, reward); try { if (EntryPickup != null) { EntryPickup.Title = LoreStrings.TrasportoEntryPickup(aName, envelope); EntryPickup.POIPosition = aPos; Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(EntryPickup, val); } } if (EntryDeliver != null) { EntryDeliver.Title = LoreStrings.TrasportoEntryDeliver(bName, bAmount); _bPos = bPos; EntryDeliver.POIPosition = bPos; Sprite val2 = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val2 != (Object)null) { PoiIconHelper.ApplyAsync(EntryDeliver, val2); } } if (EntryDropOff != null) { EntryDropOff.Title = (TerritoryHandover.HandoverActive ? LoreStrings.TrasportoEntryDropOffBoss(cut) : LoreStrings.TrasportoEntryDropOff(cut)); Vector3 val3 = ResolveDropoffMarkerPos(); if (val3 != Vector3.zero) { _donPos = val3; EntryDropOff.POIPosition = val3; Sprite val4 = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val4 != (Object)null) { PoiIconHelper.ApplyAsync(EntryDropOff, val4); } } else { try { EntryDropOff.ClearPOI(); } catch { } } } } catch (Exception ex) { NDLog.Warn("TrasportoQuest.Apply: " + ex.Message); } EnsureFirstEntryActive(); } private static Vector3 ResolveDonWorldPos() { //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_0069: 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_0021: 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_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) try { if (TerritoryHandover.HandoverActive) { if (DonSalvatoreNPC.ResolveGazeboPosition(out var pos)) { return pos; } return Vector3.zero; } NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).transform != (Object)null) { return ((Component)cachedGameNpc).transform.position; } } catch { } return Vector3.zero; } private static Vector3 ResolveDropoffMarkerPos() { //IL_0019: 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_000d: 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_0021: Unknown result type (might be due to invalid IL or missing references) try { if (SuburbiaPositions.TryResolveGazebo(out var pos)) { return pos; } } catch { } return ResolveDonWorldPos(); } public static void EnsureCreated() { try { if (Instance == null && QuestManager.GetQuestByName("Trasporto") == null) { CurrentJobGuid = $"Ndrangheta.trasporto.{DateTime.UtcNow.Ticks}"; QuestManager.CreateQuest(CurrentJobGuid); NDLog.Debug("TrasportoQuest created."); } } catch (Exception ex) { NDLog.Warn("TrasportoQuest.EnsureCreated: " + ex.Message); } } public static void CompletePickup() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 try { TrasportoQuest instance = Instance; if (instance?.EntryPickup != null && (int)instance.EntryPickup.State != 2) { instance.EntryPickup.Complete(); } if (instance?.EntryDeliver != null && (int)instance.EntryDeliver.State == 0) { instance.EntryDeliver.Begin(); } ReapplyDeliverIcon(); } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void CompleteDeliver() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 try { TrasportoQuest instance = Instance; if (instance?.EntryDeliver != null && (int)instance.EntryDeliver.State != 2) { instance.EntryDeliver.Complete(); } if (instance?.EntryDropOff != null && (int)instance.EntryDropOff.State == 0) { instance.EntryDropOff.Begin(); } ReapplyDropOffIcon(); } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void CompleteDropOff() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { TrasportoQuest instance = Instance; if (instance?.EntryDropOff != null && (int)instance.EntryDropOff.State != 2) { instance.EntryDropOff.Complete(); } } catch (Exception ex) { NDLog.Warn(ex.Message); } } public static void EnsureFirstEntryActive() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { TrasportoQuest instance = Instance; if (instance?.EntryPickup != null && (int)instance.EntryPickup.State == 0) { instance.EntryPickup.Begin(); } } catch { } } private static void ReapplyDeliverIcon() { //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_0038: Unknown result type (might be due to invalid IL or missing references) try { TrasportoQuest instance = Instance; if (instance?.EntryDeliver != null) { if (instance._bPos != Vector3.zero) { instance.EntryDeliver.POIPosition = instance._bPos; } Sprite val = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryDeliver, val); } } } catch { } } private static void ReapplyDropOffIcon() { //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_0023: 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_003b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) try { TrasportoQuest instance = Instance; if (instance?.EntryDropOff != null) { Vector3 val = ResolveDropoffMarkerPos(); if (val == Vector3.zero) { val = instance._donPos; } if (val != Vector3.zero) { instance.EntryDropOff.POIPosition = val; } Sprite val2 = AssetLoader.LoadSprite("Ndrangheta.assets.deaddrop_quest.png"); if ((Object)(object)val2 != (Object)null) { PoiIconHelper.ApplyAsync(instance.EntryDropOff, val2); } } } catch { } } public static void ClearInstanceForNext() { Instance = null; } } } namespace Ndrangheta.Messaging { internal static class ClientActionNet { private const string KEY = "ndr.act"; private const float HOST_POLL_INTERVAL = 1f; private static int _seq; private static readonly List _pending = new List(); private const int MAX_PENDING = 24; private static readonly Dictionary _seenSeq = new Dictionary(); private static float _pollCd; public static bool SendAction(string action, string data) { try { SteamNetworkClient sharedClient = LuckyNetSync.SharedClient; if (sharedClient == null || !sharedClient.IsInLobby) { return false; } _seq++; string text = string.Format("{0}|{1}|{2}", _seq, action, (data ?? "").Replace("|", "").Replace("\n", "")); _pending.Add(text); while (_pending.Count > 24) { _pending.RemoveAt(0); } sharedClient.SetMyData("ndr.act", string.Join("\n", _pending)); NDLog.Debug("[CLIENTACT] sent: " + text); return true; } catch (Exception ex) { NDLog.DebugWarn("ClientActionNet.SendAction: " + ex.Message); return false; } } public static void TickHost(float dt) { //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) _pollCd -= dt; if (_pollCd > 0f) { return; } _pollCd = 1f; try { if (!SessionGate.IsAuthority) { return; } SteamNetworkClient sharedClient = LuckyNetSync.SharedClient; if (sharedClient == null || !sharedClient.IsInLobby || !sharedClient.IsHost) { return; } Dictionary dataForAllPlayers = sharedClient.GetDataForAllPlayers("ndr.act"); if (dataForAllPlayers == null) { return; } foreach (KeyValuePair item in dataForAllPlayers) { string value = item.Value; if (string.IsNullOrEmpty(value)) { continue; } string text = ((object)item.Key/*cast due to .constrained prefix*/).ToString(); _seenSeq.TryGetValue(text, out var value2); int num = value2; string[] array = value.Split(new char[1] { '\n' }); foreach (string text2 in array) { if (string.IsNullOrEmpty(text2)) { continue; } string[] array2 = text2.Split(new char[1] { '|' }); if (array2.Length >= 2 && int.TryParse(array2[0], out var result) && result > value2) { string action = array2[1]; string data = ((array2.Length > 2) ? array2[2] : ""); Dispatch(action, data, text); if (result > num) { num = result; } } } if (num > value2) { _seenSeq[text] = num; } } } catch (Exception ex) { NDLog.DebugWarn("ClientActionNet.TickHost: " + ex.Message); } } private static void Dispatch(string action, string data, string who) { try { switch (action) { case "dropoff": PizzoJobManager.NotifyClientDropoff(data, who); break; case "battattack": BattesimoController.NotifyAttack("client " + who); break; case "metdon": IntroController.NotifyClientMet(); break; case "consent": ConsentController.ApplyClientAnswer(string.Equals(data, "yes", StringComparison.OrdinalIgnoreCase)); break; case "readnote": InformantiManager.NotifyClientRead(); break; case "hq": NdranghetaFamily.HostTriggerHq(data, who); break; case "chat": LuckyChatController.HostTriggerChat(data, who); break; case "raprecruit": RapimentoManager.HostStartForClient(who, data); break; case "rapko": RapimentoManager.HostStartCarryForClient(who, data); break; case "carbombkill": CarBombManager.HostKillCar(data); break; case "income": { string[] array = (data ?? "").Split(new char[1] { '|' }); if (array.Length >= 2 && int.TryParse(array[1], out var result) && result > 0) { IncomeTracker.RecordCash(result, (array[0] == "q") ? "Famiglia coop share" : "Famiglia other"); } break; } default: NDLog.DebugWarn("ClientActionNet: unknown action '" + action + "' from " + who + "."); break; } } catch (Exception ex) { NDLog.DebugWarn("ClientActionNet.Dispatch(" + action + "): " + ex.Message); } } public static void Reset() { _seenSeq.Clear(); _pending.Clear(); _pollCd = 0f; } } public static class DonMessaging { public const string WelcomeText = "Heard you got nerve. Salvatore. Find me at the gazebo in Suburbia — if you got the stomach for our line of work, we'll talk."; public const string MeetGreetingText = "Sit. Listen. The 'Ndrina don't take strangers — you got to prove you got the spine before you wear our colors. Trials first: pizzo runs, smuggling. When the famiglia's satisfied, we talk about il battesimo. Until then you're picciotto, on probation. Keep your phone on."; public const string ClientPresenceText = "Salvatore. You ride with the famiglia now — keep your phone on, we call when there's work."; private static Action _declineAction; private static Action _il2cppDeclineAction; private static Action _yesAction; private static Action _il2cppYesAction; private static Action _noAction; private static Action _il2cppNoAction; private static readonly List _choiceTexts = new List(); private static readonly List _choiceActions = new List(); private static readonly List _il2cppChoiceActions = new List(); private static object _reexpandCo; public static NPC ResolveGameNpc() { try { if ((Object)(object)DonSalvatoreNPC.CachedGameNpc != (Object)null) { return DonSalvatoreNPC.CachedGameNpc; } return NPCManager.GetNPC("Ndrangheta_don_salvatore"); } catch { return null; } } public static MSGConversation ResolveConversation() { try { NPC obj = ResolveGameNpc(); return (obj != null) ? obj.MSGConversation : null; } catch { return null; } } public static bool TryUnlock() { try { NPC val = ResolveGameNpc(); if ((Object)(object)val == (Object)null) { return false; } if (!TryMessagesAppExists()) { return false; } NPCRelationData relationData = val.RelationData; if (relationData == null) { return false; } if (!relationData.Unlocked) { relationData.Unlock((EUnlockType)0, false); NDLog.Debug("Don unlocked in messaging system."); } return true; } catch (Exception ex) { NDLog.DebugWarn("DonMessaging.TryUnlock: " + ex.Message); return false; } } public static bool PatchAsSupplier() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 try { MSGConversation val = ResolveConversation(); if (val == null) { return false; } bool flag = true; try { List categories = val.Categories; if (categories != null) { for (int i = 0; i < categories.Count; i++) { if ((int)categories[i] == 1) { flag = false; break; } } } } catch { } if (flag) { List list = GameCompat.NewList(); list.Add((EConversationCategory)1); val.SetCategories(list); NDLog.Debug("Don conversation categorized as Supplier."); } try { val.SetIsKnown(true); } catch { } try { val.SetEntryVisibility(true); } catch { } RepositionContactsList(); return true; } catch (Exception ex) { NDLog.DebugWarn("PatchAsSupplier: " + ex.Message); return false; } } public static void RepositionContactsList() { try { if (!IsPhoneOpen()) { MessagesApp instance = PlayerSingleton.Instance; if ((Object)(object)instance != (Object)null) { instance.RepositionEntries(); } } } catch (Exception ex) { NDLog.DebugWarn("RepositionContactsList: " + ex.Message); } } public static bool SendDon(string text) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown try { MSGConversation val = ResolveConversation(); if (val == null) { return false; } bool flag = !IsPhoneOpen(); bool isAuthority = SessionGate.IsAuthority; try { val.SendMessage(new Message(text, (ESenderType)1, false, -1), flag, isAuthority); } catch (Exception ex) when (isAuthority) { NDLog.DebugWarn("SendDon network path failed, local fallback: " + ex.Message); val.SendMessage(new Message(text, (ESenderType)1, false, -1), flag, false); } NDLog.Debug($"Don SMS sent ({text.Length} chars, network={isAuthority})."); return true; } catch (Exception ex2) { NDLog.Warn("DonMessaging.SendDon: " + ex2.Message); return false; } } public static bool SendWelcomeIfNotYet() { if (RecruitmentState.WelcomeSmsSent) { return true; } try { if (GameCompat.IsGameLoading()) { return false; } } catch { } if (!TryUnlock()) { return false; } if (ConversationContains("Heard you got nerve. Salvatore. Find me at the gazebo in Suburbia — if you got the stomach for our line of work, we'll talk.".Substring(0, Math.Min(20, "Heard you got nerve. Salvatore. Find me at the gazebo in Suburbia — if you got the stomach for our line of work, we'll talk.".Length))) || ConversationHasDonMessage() || RecruitmentState.HasMetDon || RecruitmentState.Recruited) { RecruitmentState.WelcomeSmsSent = true; NDLog.Debug("Welcome already happened (history/progress) — flag set, no re-send."); return true; } if (!SendDon("Heard you got nerve. Salvatore. Find me at the gazebo in Suburbia — if you got the stomach for our line of work, we'll talk.")) { return false; } RecruitmentState.WelcomeSmsSent = true; NDLog.Debug("Welcome SMS sent."); return true; } public static bool SendMeetGreetingIfNotYet() { if (RecruitmentState.HasMetDon) { return true; } if (!SendDon("Sit. Listen. The 'Ndrina don't take strangers — you got to prove you got the spine before you wear our colors. Trials first: pizzo runs, smuggling. When the famiglia's satisfied, we talk about il battesimo. Until then you're picciotto, on probation. Keep your phone on.")) { return false; } RecruitmentState.HasMetDon = true; return true; } public static bool SendClientPresenceMessageIfNotYet() { try { if (!TryUnlock()) { return false; } if (ConversationHasAnyMessage()) { return true; } bool flag = SendDon("Salvatore. You ride with the famiglia now — keep your phone on, we call when there's work."); if (flag) { RepositionContactsList(); } return flag; } catch (Exception ex) { NDLog.DebugWarn("DonMessaging.SendClientPresenceMessageIfNotYet: " + ex.Message); return false; } } public static void RegisterDeclineButton(Action onDecline) { try { MSGConversation val = ResolveConversation(); if (val == null || onDecline == null) { return; } RemoveSendable(val, "Decline this job"); _declineAction = delegate { try { onDecline(); } catch (Exception ex3) { NDLog.Warn("Decline handler: " + ex3.Message); } finally { RemoveDeclineButton(); } }; SendableMessage val2 = null; try { val2 = val.CreateSendableMessage("Decline this job"); } catch (Exception ex) { NDLog.DebugWarn("CreateSendableMessage: " + ex.Message); return; } if (val2 != null) { _il2cppDeclineAction = GameCompat.ToGameAction(_declineAction); val2.onSent = _il2cppDeclineAction; NDLog.Debug("Decline button registered."); } } catch (Exception ex2) { NDLog.Warn("RegisterDeclineButton: " + ex2.Message); } } public static void RegisterYesNoButtons(string yesText, Action onYes, string noText, Action onNo) { try { MSGConversation val = ResolveConversation(); if (val == null || onYes == null || onNo == null) { return; } RemoveSendable(val, yesText); RemoveSendable(val, noText); _yesAction = delegate { try { onYes(); } finally { RemoveYesNoButtons(yesText, noText); } }; _noAction = delegate { try { onNo(); } finally { RemoveYesNoButtons(yesText, noText); } }; SendableMessage val2 = null; SendableMessage val3 = null; try { val2 = val.CreateSendableMessage(yesText); } catch (Exception ex) { NDLog.DebugWarn("YesBtn: " + ex.Message); } try { val3 = val.CreateSendableMessage(noText); } catch (Exception ex2) { NDLog.DebugWarn("NoBtn: " + ex2.Message); } if (val2 != null && val3 != null) { _il2cppYesAction = GameCompat.ToGameAction(_yesAction); _il2cppNoAction = GameCompat.ToGameAction(_noAction); val2.onSent = _il2cppYesAction; val3.onSent = _il2cppNoAction; NDLog.Debug("Yes/No buttons registered: '" + yesText + "' / '" + noText + "'"); } } catch (Exception ex3) { NDLog.Warn("RegisterYesNoButtons: " + ex3.Message); } } public static void RemoveYesNoButtons(string yesText, string noText) { try { MSGConversation val = ResolveConversation(); if (val == null) { return; } RemoveSendable(val, yesText); RemoveSendable(val, noText); } catch { } _yesAction = null; _il2cppYesAction = null; _noAction = null; _il2cppNoAction = null; } public static void RemoveDeclineButton() { try { MSGConversation val = ResolveConversation(); if (val != null) { RemoveSendable(val, "Decline this job"); _declineAction = null; _il2cppDeclineAction = null; } } catch { } } public static void RegisterChoiceButtons(IList texts, IList actions, bool expandAfter = true) { try { MSGConversation val = ResolveConversation(); if (val == null || texts == null || actions == null || texts.Count != actions.Count || texts.Count == 0) { return; } if (expandAfter) { try { MessageSenderInterface senderInterface = val.senderInterface; if ((Object)(object)senderInterface != (Object)null && IsPhoneOpen()) { senderInterface.SetVisibility((EVisibility)2); } } catch { } } ClearChoiceButtons(); for (int i = 0; i < texts.Count; i++) { string label = texts[i]; Action act = actions[i]; if (string.IsNullOrEmpty(label) || act == null) { continue; } RemoveSendable(val, label); Action action = delegate { try { ClearChoiceButtons(); } catch (Exception ex3) { NDLog.DebugWarn("Pre-clear '" + label + "': " + ex3.Message); } try { act(); } catch (Exception ex4) { NDLog.Warn("Choice handler '" + label + "': " + ex4.Message); } }; SendableMessage val2 = null; try { val2 = val.CreateSendableMessage(label); } catch (Exception ex) { NDLog.DebugWarn("CreateSendableMessage('" + label + "'): " + ex.Message); continue; } if (val2 != null) { Action action2 = GameCompat.ToGameAction(action); try { val2.disableDefaultSendBehaviour = true; } catch { } val2.onSelected = action2; _choiceTexts.Add(label); _choiceActions.Add(action); _il2cppChoiceActions.Add(action2); } } ScheduleSenderReexpand(val, expandAfter); NDLog.Debug($"Choice buttons registered: {_choiceTexts.Count}"); } catch (Exception ex2) { NDLog.Warn("RegisterChoiceButtons: " + ex2.Message); } } private static void ScheduleSenderReexpand(MSGConversation conv, bool expanded) { try { if (_reexpandCo != null) { try { MelonCoroutines.Stop(_reexpandCo); } catch { } _reexpandCo = null; } _reexpandCo = MelonCoroutines.Start(ReexpandNextFrame(conv, expanded)); } catch { } } private static IEnumerator ReexpandNextFrame(MSGConversation conv, bool expanded) { for (int frame = 0; frame < 6; frame++) { yield return null; bool phoneOpen = false; try { phoneOpen = IsPhoneOpen(); } catch { } if (!phoneOpen || frame < 1) { continue; } try { MessageSenderInterface si = conv?.senderInterface; if (!((Object)(object)si != (Object)null) || !((Object)(object)((Component)si).gameObject != (Object)null) || !((Component)si).gameObject.activeInHierarchy) { continue; } si.SetVisibility((EVisibility)((!expanded) ? 1 : 2)); try { RectTransform rt = si.SendablesContainer; if (expanded && (Object)(object)rt != (Object)null && ((Component)rt).gameObject.activeInHierarchy) { LayoutRebuilder.ForceRebuildLayoutImmediate(rt); } } catch { } } catch { } } _reexpandCo = null; } public static void CloseChoiceMenu() { try { if (_reexpandCo != null) { try { MelonCoroutines.Stop(_reexpandCo); } catch { } _reexpandCo = null; } ClearChoiceButtons(); MessageSenderInterface val = ResolveConversation()?.senderInterface; if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null && ((Component)val).gameObject.activeInHierarchy) { val.SetVisibility((EVisibility)1); } } catch (Exception ex) { NDLog.DebugWarn("CloseChoiceMenu: " + ex.Message); } } public static bool NeedsChoiceInterfaceRestore() { try { if (_choiceTexts.Count > 0) { return false; } if (_yesAction != null || _declineAction != null) { return false; } return ResolveConversation() != null; } catch { return false; } } public static void ClearChoiceButtons() { try { MSGConversation val = ResolveConversation(); if (val != null) { for (int i = 0; i < _choiceTexts.Count; i++) { try { RemoveSendable(val, _choiceTexts[i]); } catch { } } } } catch { } _choiceTexts.Clear(); _choiceActions.Clear(); _il2cppChoiceActions.Clear(); } private static void RemoveSendable(MSGConversation conv, string text) { if (conv == null || string.IsNullOrEmpty(text)) { return; } bool flag = false; try { List sendables = conv.Sendables; if (sendables != null) { for (int num = sendables.Count - 1; num >= 0; num--) { SendableMessage val = sendables[num]; if (val != null && val.Text == text) { sendables.RemoveAt(num); flag = true; } } } } catch { } if (!flag) { return; } try { conv.ClearResponses(false); } catch { } try { conv.SetResponseContainerVisible(false); } catch { } try { List responseRects = conv.responseRects; if (responseRects != null) { for (int num2 = responseRects.Count - 1; num2 >= 0; num2--) { RectTransform val2 = responseRects[num2]; if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } responseRects.Clear(); } } catch { } try { conv.currentResponses?.Clear(); } catch { } try { RectTransform responseContainer = conv.responseContainer; if ((Object)(object)responseContainer != (Object)null) { for (int num3 = ((Transform)responseContainer).childCount - 1; num3 >= 0; num3--) { Transform child = ((Transform)responseContainer).GetChild(num3); if ((Object)(object)child != (Object)null && (Object)(object)((Component)child).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)child).gameObject); } } } } catch { } try { MessageSenderInterface senderInterface = conv.senderInterface; if (!((Object)(object)senderInterface != (Object)null)) { return; } List sendableBubbles = senderInterface.sendableBubbles; if (sendableBubbles != null) { for (int num4 = sendableBubbles.Count - 1; num4 >= 0; num4--) { MessageBubble val3 = sendableBubbles[num4]; if ((Object)(object)val3 == (Object)null) { sendableBubbles.RemoveAt(num4); } else { string text2 = null; try { text2 = val3.text; } catch { } if (text2 != null && !(text2 != text)) { try { senderInterface.sendableMap?.Remove(val3); } catch { } try { if ((Object)(object)((Component)val3).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } } catch { } sendableBubbles.RemoveAt(num4); } } } } try { senderInterface.UpdateSendables(); } catch { } try { GameObject gameObject = ((Component)senderInterface).gameObject; if ((Object)(object)gameObject != (Object)null && gameObject.activeSelf) { gameObject.SetActive(false); gameObject.SetActive(true); } } catch { } } catch { } } private static bool TryMessagesAppExists() { try { return (Object)(object)PlayerSingleton.Instance != (Object)null; } catch { return false; } } public static bool IsPhoneOpen() { try { Phone instance = PlayerSingleton.Instance; return (Object)(object)instance != (Object)null && instance.IsOpen; } catch { return false; } } private static bool ConversationHasAnyMessage() { try { List list = ResolveConversation()?.messageHistory; return list != null && list.Count > 0; } catch { return false; } } private static bool ConversationHasDonMessage() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 try { List list = ResolveConversation()?.messageHistory; if (list == null) { return false; } for (int i = 0; i < list.Count; i++) { Message val = list[i]; if (val != null && (int)val.sender == 1) { return true; } } } catch { } return false; } private static bool ConversationContains(string snippet) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 try { MSGConversation val = ResolveConversation(); if (val == null) { return false; } List messageHistory = val.messageHistory; if (messageHistory == null) { return false; } for (int i = 0; i < messageHistory.Count; i++) { Message val2 = messageHistory[i]; if (val2 != null && (int)val2.sender == 1) { string text = val2.text; if (!string.IsNullOrEmpty(text) && text.Contains(snippet)) { return true; } } } } catch { } return false; } } internal static class LuckyNetSync { private const string KeyPrefix = "ndr_"; private const string StateKey = "lucky"; private static SteamNetworkClient _client; private static HostSyncVar _state; private static bool _init; private static int _lastRenderedSwing = -1; private static Vector3 _clientTargetPos; private static bool _clientHasTarget; private static Vector3 _clientVel; private const float CLIENT_FOLLOW_SPEED = 6f; private const float CLIENT_SMOOTH_TIME = 0.12f; private const float CLIENT_WARP_THRESHOLD = 20f; private static string _lastPublished = null; public static bool ClientCombatActive { get; private set; } public static bool Available => _init && _client != null; internal static SteamNetworkClient SharedClient => _client; public static bool IsInLobby { get { try { return Available && _client.IsInLobby; } catch { return false; } } } public static bool IsHost { get { try { return Available && _client.IsHost; } catch { return false; } } } public static string LocalIdString { get { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) try { return Available ? ((object)_client.LocalPlayerId/*cast due to .constrained prefix*/).ToString() : ""; } catch { return ""; } } } public static void Initialize() { //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_0079: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (_init) { return; } try { _client = new SteamNetworkClient(); if (!_client.Initialize()) { _client = null; return; } try { _client.OnVersionMismatch += OnVersionMismatch; } catch { } NetworkSyncOptions val = new NetworkSyncOptions { KeyPrefix = "ndr_", AutoSync = true, SyncOnPlayerJoin = true, MaxSyncsPerSecond = 0 }; _state = _client.CreateHostSyncVar("lucky", "", val, (ISyncValidator)null); _state.OnValueChanged += OnStateChanged; _init = true; NDLog.Debug("LuckyNetSync: SteamNetworkClient initialized (HostSyncVar transport)."); } catch { _client = null; } } public static void Tick() { if (!_init) { Initialize(); } } public static void PublishState(bool active, int method, int swingSeq, Vector3 pos = default(Vector3)) { if (!Available || !IsInLobby || !IsHost || _state == null) { return; } try { CultureInfo invariantCulture = CultureInfo.InvariantCulture; string text = (active ? string.Format("1|{0}|{1}|{2}|{3}|{4}", method, swingSeq, pos.x.ToString("0.0", invariantCulture), pos.y.ToString("0.0", invariantCulture), pos.z.ToString("0.0", invariantCulture)) : ""); if (!string.Equals(text, _lastPublished, StringComparison.Ordinal)) { _lastPublished = text; _state.Value = text; } } catch (Exception ex) { NDLog.DebugWarn("LuckyNetSync.PublishState: " + ex.Message); } } private static void OnStateChanged(string oldValue, string newValue) { try { if (!IsHost) { ApplyRemoteState(newValue); } } catch (Exception ex) { NDLog.DebugWarn("LuckyNetSync.OnStateChanged: " + ex.Message); } } private static void ApplyRemoteState(string encoded) { //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) //IL_00e6: 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_0087: 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_00a6: 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) ClientCombatActive = !string.IsNullOrEmpty(encoded); NPC npc = LuckyNPC.GetNpc(); if ((Object)(object)npc == (Object)null) { return; } if (string.IsNullOrEmpty(encoded)) { LuckyWeaponVisual.Clear(npc); _lastRenderedSwing = -1; _clientHasTarget = false; _clientVel = Vector3.zero; } else { if (!TryParse(encoded, out var method, out var swingSeq, out var pos)) { return; } if (((Vector3)(ref pos)).sqrMagnitude > 1f) { _clientTargetPos = pos; bool flag = !_clientHasTarget; try { if (!flag) { Vector3 val = ((Component)npc).transform.position - pos; if (((Vector3)(ref val)).sqrMagnitude > 400f) { flag = true; } } } catch { } _clientHasTarget = true; if (flag) { try { ((Component)npc).transform.position = pos; } catch { } } } LuckyWeaponVisual.EquipOnAvatar(npc, method); if (method == 2) { EnsureClientVelocityTracker(npc); } if (swingSeq > _lastRenderedSwing) { _lastRenderedSwing = swingSeq; if (swingSeq > 0) { LuckyWeaponVisual.TriggerAttack(npc); } } } } public static void ClientTick(float dt) { //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_0051: 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_0057: 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_0085: 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_009b: 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) if (IsHost || !_clientHasTarget) { return; } try { NPC npc = LuckyNPC.GetNpc(); if ((Object)(object)npc == (Object)null || (Object)(object)((Component)npc).transform == (Object)null) { return; } Vector3 position = ((Component)npc).transform.position; Vector3 val = position - _clientTargetPos; if (((Vector3)(ref val)).sqrMagnitude < 0.0004f) { _clientVel = Vector3.zero; return; } ((Component)npc).transform.position = Vector3.SmoothDamp(position, _clientTargetPos, ref _clientVel, 0.12f, 6f, dt); try { SmoothedVelocityCalculator val2 = (((Object)(object)npc.Movement != (Object)null) ? npc.Movement.VelocityCalculator : null); if ((Object)(object)val2 != (Object)null) { val2.SampleLength = 0.6f; } } catch { } } catch { } } private static void EnsureClientVelocityTracker(NPC lucky) { try { CombatBehaviour val = ((lucky == null) ? null : lucky.Behaviour?.CombatBehaviour); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.TargetVelocityTracker != (Object)null)) { SmoothedVelocityCalculator targetVelocityTracker = ((Component)lucky).gameObject.AddComponent(); val.TargetVelocityTracker = targetVelocityTracker; NDLog.Debug("LuckyNetSync: client TargetVelocityTracker injected (firearm NRE fix)."); } } catch (Exception ex) { NDLog.DebugWarn("EnsureClientVelocityTracker: " + ex.Message); } } private static bool TryParse(string s, out int method, out int swingSeq, out Vector3 pos) { //IL_0008: 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_0099: Unknown result type (might be due to invalid IL or missing references) method = 0; swingSeq = 0; pos = default(Vector3); try { string[] array = s.Split(new char[1] { '|' }); if (array.Length < 3) { return false; } int.TryParse(array[1], out method); int.TryParse(array[2], out swingSeq); CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (array.Length >= 6 && float.TryParse(array[3], NumberStyles.Float, invariantCulture, out var result) && float.TryParse(array[4], NumberStyles.Float, invariantCulture, out var result2) && float.TryParse(array[5], NumberStyles.Float, invariantCulture, out var result3)) { pos = new Vector3(result, result2, result3); } return true; } catch { return false; } } private static void OnVersionMismatch(object sender, VersionMismatchEventArgs e) { NDLog.Warn("LuckyNetSync: SteamNetworkLib version mismatch between players — visual sync may be unreliable. Everyone should run the same mod/lib build."); } public static void Dispose() { try { if (_state != null) { _state.OnValueChanged -= OnStateChanged; _state.Dispose(); } } catch { } try { if (_client != null) { _client.OnVersionMismatch -= OnVersionMismatch; _client.Dispose(); } } catch { } _state = null; _client = null; _init = false; _lastRenderedSwing = -1; _lastPublished = null; ClientCombatActive = false; } } internal static class QuestNetSync { private const string StateKey = "quest"; private static HostSyncVar _state; private static string _lastPublished = null; private static string _lastApplied = null; private static bool _skipLogged; private static int _refreshTick; private static int _publishTick; public static bool RemoteDonReady { get; private set; } public static bool RemoteRecruited { get; private set; } public static bool RemoteHasMetDon { get; private set; } public static bool HasRemoteState { get; private set; } public static string RemoteJobCode { get; private set; } = ""; public static string RemoteJobTarget { get; private set; } = ""; public static string RemoteJobTargetPos { get; private set; } = ""; public static int RemoteJobStage { get; private set; } public static int RemoteJobCut { get; private set; } public static int RemoteJobReward { get; private set; } public static string RemoteEntryText { get; private set; } = ""; public static string RemoteEntryPoi { get; private set; } = ""; public static int RemotePaySeq { get; private set; } public static int RemotePayAmount { get; private set; } public static string RemotePayExclude { get; private set; } = ""; public static int RemoteBattesimoStage { get; private set; } public static bool RemoteHandover { get; private set; } public static int RemoteEstate { get; private set; } public static int RemoteFearPoints { get; private set; } public static int RemoteFaidaPoints { get; private set; } public static int RemoteTriadPoints { get; private set; } public static string RemoteBossLabel { get; private set; } = ""; public static string RemoteBossPos { get; private set; } = ""; public static string RemoteKidnapVanGuid { get; private set; } = ""; public static bool RemoteRapRecruiting { get; private set; } public static bool RemoteConsentPending { get; private set; } public static int RemoteBossKind { get; private set; } public static int RemoteGuardPatrol { get; private set; } public static int RemoteRaidSeconds { get; private set; } public static long RemoteQuestIncome { get; private set; } public static long RemoteOtherIncome { get; private set; } public static bool RemoteOpDropActive { get; private set; } public static string RemoteOpDropPos { get; private set; } = ""; public static int RemoteOpDropReach { get; private set; } public static int RemoteOpVariant { get; private set; } public static bool RemoteSceneActive { get; private set; } public static string RemoteScenePlayerPos { get; private set; } = ""; public static string RemoteSceneReturnPos { get; private set; } = ""; public static int RemoteSceneReturnYaw { get; private set; } = 9999; public static int RemoteSceneBeginSeq { get; private set; } public static int RemoteSceneEndSeq { get; private set; } public static string RemoteVisualsRaw { get; private set; } = ""; public static string RemoteTeleportsRaw { get; private set; } = ""; public static int RemoteBrawlPhase { get; private set; } public static string RemoteFamigliaGoons { get; private set; } = ""; public static int RemoteSceneTimeLeft { get; private set; } public static bool RemoteSceneKoReached { get; private set; } public static int RemoteSfxSeq { get; private set; } public static string RemoteSfxName { get; private set; } = ""; public static int RemoteSfxVol100 { get; private set; } = 100; public static string RemoteSfxLoop { get; private set; } = ""; public static int RemoteReleasedSeq { get; private set; } public static int RemoteReleasedObjId { get; private set; } private static bool IsHost { get { try { SteamNetworkClient sharedClient = LuckyNetSync.SharedClient; return sharedClient != null && sharedClient.IsHost; } catch { return false; } } } private static bool IsInLobby { get { try { SteamNetworkClient sharedClient = LuckyNetSync.SharedClient; return sharedClient != null && sharedClient.IsInLobby; } catch { return false; } } } public static void Tick() { //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_0037: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (_state == null) { SteamNetworkClient sharedClient = LuckyNetSync.SharedClient; if (sharedClient == null) { return; } try { NetworkSyncOptions val = new NetworkSyncOptions { KeyPrefix = "ndr_", AutoSync = true, SyncOnPlayerJoin = true, MaxSyncsPerSecond = 0 }; _state = sharedClient.CreateHostSyncVar("quest", "", val, (ISyncValidator)null); _state.OnValueChanged += OnStateChanged; NDLog.Debug("QuestNetSync: HostSyncVar created on shared client (ndr_quest)."); } catch (Exception ex) { NDLog.DebugWarn("QuestNetSync init: " + ex.Message); return; } } if (!IsHost && ++_refreshTick >= 30) { _refreshTick = 0; try { _state.Refresh(); } catch { } } } public static void PublishState(bool donReady, bool recruited, bool hasMetDon, string jobCode = "", string jobTarget = "", string jobTargetPos = "", int jobStage = 0, int jobCut = 0, int jobReward = 0, string entryText = "", string entryPoi = "", int paySeq = 0, int payAmount = 0, string payExclude = "", int battStage = 0, bool handover = false, int estate = 0, int fearPoints = 0, int faidaPoints = 0, string bossLabel = "", string bossPos = "", string kidnapVanGuid = "", bool consentPending = false, int bossKind = 0, int guardPatrol = 0, int raidSeconds = 0, long questIncome = 0L, long otherIncome = 0L, bool rapRecruiting = false, bool opDropActive = false, string opDropPos = "", int opDropReach = 0, int opVariant = 0, bool sceneActive = false, string scenePlayerPos = "", string sceneReturnPos = "", int sceneReturnYaw = 9999, int sceneBeginSeq = 0, int sceneEndSeq = 0, string visObjs = "", string tpActions = "", int brawlPhase = 0, string famigliaGoons = "", int sceneTimeLeft = 0, bool sceneKo = false, int sfxSeq = 0, string sfxName = "", int sfxVol100 = 100, string sfxLoop = "", int releasedSeq = 0, int releasedObjId = 0, int triadPoints = 0) { if (_state == null || ++_publishTick < 15) { return; } _publishTick = 0; if (!IsInLobby || !IsHost) { if (!_skipLogged) { _skipLogged = true; NDLog.Debug($"[QUESTSYNC] host publish skipped (inLobby={IsInLobby}, isHost={IsHost})."); } return; } try { string text = (jobTarget ?? "").Replace("|", ""); string text2 = (jobTargetPos ?? "").Replace("|", ""); string text3 = (entryText ?? "").Replace("|", "/"); string text4 = (entryPoi ?? "").Replace("|", ""); string text5 = (payExclude ?? "").Replace("|", ""); string text6 = (bossLabel ?? "").Replace("|", "/"); string text7 = (bossPos ?? "").Replace("|", ""); string text8 = (kidnapVanGuid ?? "").Replace("|", ""); string text9 = (opDropPos ?? "").Replace("|", ""); string text10 = (scenePlayerPos ?? "").Replace("|", ""); string text11 = (sceneReturnPos ?? "").Replace("|", ""); string text12 = (visObjs ?? "").Replace("|", ""); string text13 = (tpActions ?? "").Replace("|", ""); string text14 = (famigliaGoons ?? "").Replace("|", ""); string text15 = (sfxName ?? "").Replace("|", ""); string text16 = (sfxLoop ?? "").Replace("|", ""); string text17 = string.Format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}|{10}|{11}|{12}|{13}|{14}|{15}|{16}|{17}|{18}|{19}|{20}|{21}|{22}|{23}|{24}|{25}|{26}|{27}|{28}|{29}|{30}|{31}|{32}|{33}|{34}|{35}|{36}|{37}|{38}|{39}|{40}|{41}|{42}|{43}|{44}|{45}|{46}|{47}|{48}|{49}|{50}|{51}", donReady ? 1 : 0, recruited ? 1 : 0, hasMetDon ? 1 : 0, jobCode ?? "", text, text2, jobStage, jobCut, jobReward, text3, text4, paySeq, payAmount, text5, battStage, handover ? 1 : 0, estate, fearPoints, faidaPoints, text6, text7, text8, consentPending ? 1 : 0, bossKind, guardPatrol, raidSeconds, questIncome, otherIncome, rapRecruiting ? 1 : 0, opDropActive ? 1 : 0, text9, opDropReach, opVariant, sceneActive ? 1 : 0, text10, text11, sceneReturnYaw, sceneBeginSeq, sceneEndSeq, text12, text13, brawlPhase, text14, sceneTimeLeft, sceneKo ? 1 : 0, sfxSeq, text15, sfxVol100, text16, releasedSeq, releasedObjId, triadPoints); if (!string.Equals(text17, _lastPublished, StringComparison.Ordinal)) { _lastPublished = text17; _state.Value = text17; NDLog.Debug("[QUESTSYNC] host published: " + text17); } } catch (Exception ex) { NDLog.DebugWarn("QuestNetSync.PublishState: " + ex.Message); } } private static void OnStateChanged(string oldValue, string newValue) { try { if (!IsHost && !string.Equals(newValue, _lastApplied, StringComparison.Ordinal)) { _lastApplied = newValue; ParseInto(newValue); } } catch (Exception ex) { NDLog.DebugWarn("QuestNetSync.OnStateChanged: " + ex.Message); } } private static void ParseInto(string s) { if (string.IsNullOrEmpty(s)) { bool num = (RemoteHasMetDon = false); RemoteRecruited = num; RemoteDonReady = num; RemoteJobCode = (RemoteJobTarget = (RemoteJobTargetPos = "")); RemoteJobStage = (RemoteJobCut = (RemoteJobReward = 0)); RemoteEntryText = (RemoteEntryPoi = (RemotePayExclude = "")); RemotePaySeq = (RemotePayAmount = 0); RemoteBattesimoStage = 0; RemoteHandover = false; RemoteEstate = 0; RemoteFearPoints = 0; RemoteFaidaPoints = 0; RemoteBossLabel = (RemoteBossPos = (RemoteKidnapVanGuid = "")); RemoteConsentPending = false; RemoteBossKind = 0; RemoteGuardPatrol = 0; RemoteRaidSeconds = 0; RemoteQuestIncome = (RemoteOtherIncome = 0L); RemoteRapRecruiting = false; RemoteOpDropActive = (RemoteSceneActive = false); RemoteOpDropPos = (RemoteScenePlayerPos = (RemoteSceneReturnPos = "")); RemoteOpDropReach = (RemoteOpVariant = (RemoteSceneBeginSeq = (RemoteSceneEndSeq = 0))); RemoteSceneReturnYaw = 9999; RemoteVisualsRaw = (RemoteTeleportsRaw = ""); RemoteBrawlPhase = 0; RemoteFamigliaGoons = ""; RemoteSceneTimeLeft = 0; RemoteSceneKoReached = false; RemoteSfxSeq = 0; RemoteSfxName = ""; RemoteSfxVol100 = 100; RemoteSfxLoop = ""; RemoteReleasedSeq = 0; RemoteReleasedObjId = 0; RemoteTriadPoints = 0; HasRemoteState = false; return; } try { string[] array = s.Split(new char[1] { '|' }); RemoteDonReady = array.Length != 0 && array[0] == "1"; RemoteRecruited = array.Length > 1 && array[1] == "1"; RemoteHasMetDon = array.Length > 2 && array[2] == "1"; RemoteJobCode = ((array.Length > 3) ? array[3] : ""); RemoteJobTarget = ((array.Length > 4) ? array[4] : ""); RemoteJobTargetPos = ((array.Length > 5) ? array[5] : ""); RemoteJobStage = ((array.Length > 6 && int.TryParse(array[6], out var result)) ? result : 0); RemoteJobCut = ((array.Length > 7 && int.TryParse(array[7], out result)) ? result : 0); RemoteJobReward = ((array.Length > 8 && int.TryParse(array[8], out result)) ? result : 0); RemoteEntryText = ((array.Length > 9) ? array[9] : ""); RemoteEntryPoi = ((array.Length > 10) ? array[10] : ""); RemotePaySeq = ((array.Length > 11 && int.TryParse(array[11], out result)) ? result : 0); RemotePayAmount = ((array.Length > 12 && int.TryParse(array[12], out result)) ? result : 0); RemotePayExclude = ((array.Length > 13) ? array[13] : ""); RemoteBattesimoStage = ((array.Length > 14 && int.TryParse(array[14], out result)) ? result : 0); RemoteHandover = array.Length > 15 && array[15] == "1"; RemoteEstate = ((array.Length > 16 && int.TryParse(array[16], out result)) ? result : 0); RemoteFearPoints = ((array.Length > 17 && int.TryParse(array[17], out result)) ? result : 0); RemoteFaidaPoints = ((array.Length > 18 && int.TryParse(array[18], out result)) ? result : 0); RemoteBossLabel = ((array.Length > 19) ? array[19] : ""); RemoteBossPos = ((array.Length > 20) ? array[20] : ""); RemoteKidnapVanGuid = ((array.Length > 21) ? array[21] : ""); RemoteConsentPending = array.Length > 22 && array[22] == "1"; RemoteBossKind = ((array.Length > 23 && int.TryParse(array[23], out result)) ? result : 0); RemoteGuardPatrol = ((array.Length > 24 && int.TryParse(array[24], out result)) ? result : 0); RemoteRaidSeconds = ((array.Length > 25 && int.TryParse(array[25], out result)) ? result : 0); RemoteQuestIncome = ((array.Length > 26 && long.TryParse(array[26], out var result2)) ? result2 : 0); RemoteOtherIncome = ((array.Length > 27 && long.TryParse(array[27], out result2)) ? result2 : 0); RemoteRapRecruiting = array.Length > 28 && array[28] == "1"; RemoteOpDropActive = array.Length > 29 && array[29] == "1"; RemoteOpDropPos = ((array.Length > 30) ? array[30] : ""); RemoteOpDropReach = ((array.Length > 31 && int.TryParse(array[31], out result)) ? result : 0); RemoteOpVariant = ((array.Length > 32 && int.TryParse(array[32], out result)) ? result : 0); RemoteSceneActive = array.Length > 33 && array[33] == "1"; RemoteScenePlayerPos = ((array.Length > 34) ? array[34] : ""); RemoteSceneReturnPos = ((array.Length > 35) ? array[35] : ""); RemoteSceneReturnYaw = ((array.Length > 36 && int.TryParse(array[36], out result)) ? result : 9999); RemoteSceneBeginSeq = ((array.Length > 37 && int.TryParse(array[37], out result)) ? result : 0); RemoteSceneEndSeq = ((array.Length > 38 && int.TryParse(array[38], out result)) ? result : 0); RemoteVisualsRaw = ((array.Length > 39) ? array[39] : ""); RemoteTeleportsRaw = ((array.Length > 40) ? array[40] : ""); RemoteBrawlPhase = ((array.Length > 41 && int.TryParse(array[41], out result)) ? result : 0); RemoteFamigliaGoons = ((array.Length > 42) ? array[42] : ""); RemoteSceneTimeLeft = ((array.Length > 43 && int.TryParse(array[43], out result)) ? result : 0); RemoteSceneKoReached = array.Length > 44 && array[44] == "1"; RemoteSfxSeq = ((array.Length > 45 && int.TryParse(array[45], out result)) ? result : 0); RemoteSfxName = ((array.Length > 46) ? array[46] : ""); RemoteSfxVol100 = ((array.Length > 47 && int.TryParse(array[47], out result)) ? result : 100); RemoteSfxLoop = ((array.Length > 48) ? array[48] : ""); RemoteReleasedSeq = ((array.Length > 49 && int.TryParse(array[49], out result)) ? result : 0); RemoteReleasedObjId = ((array.Length > 50 && int.TryParse(array[50], out result)) ? result : 0); RemoteTriadPoints = ((array.Length > 51 && int.TryParse(array[51], out result)) ? result : 0); HasRemoteState = true; NDLog.Debug($"[QUESTSYNC] client received: donReady={RemoteDonReady} recruited={RemoteRecruited} metDon={RemoteHasMetDon} job={RemoteJobCode} target={RemoteJobTarget}"); } catch { } } public static void Dispose() { try { if (_state != null) { _state.OnValueChanged -= OnStateChanged; _state.Dispose(); } } catch { } _state = null; _lastPublished = null; _lastApplied = null; _skipLogged = false; bool num = (HasRemoteState = false); RemoteHasMetDon = num; RemoteRecruited = num; RemoteDonReady = num; RemoteJobCode = (RemoteJobTarget = (RemoteJobTargetPos = "")); RemoteJobStage = (RemoteJobCut = (RemoteJobReward = 0)); RemoteEntryText = (RemoteEntryPoi = (RemotePayExclude = "")); RemotePaySeq = (RemotePayAmount = 0); RemoteBattesimoStage = 0; RemoteHandover = false; RemoteEstate = 0; RemoteFearPoints = 0; RemoteFaidaPoints = 0; RemoteBossLabel = (RemoteBossPos = (RemoteKidnapVanGuid = "")); RemoteConsentPending = false; RemoteBossKind = 0; RemoteGuardPatrol = 0; RemoteRaidSeconds = 0; RemoteQuestIncome = (RemoteOtherIncome = 0L); RemoteRapRecruiting = false; RemoteOpDropActive = (RemoteSceneActive = false); RemoteOpDropPos = (RemoteScenePlayerPos = (RemoteSceneReturnPos = "")); RemoteOpDropReach = (RemoteOpVariant = (RemoteSceneBeginSeq = (RemoteSceneEndSeq = 0))); RemoteSceneReturnYaw = 9999; RemoteVisualsRaw = (RemoteTeleportsRaw = ""); RemoteBrawlPhase = 0; RemoteFamigliaGoons = ""; RemoteTriadPoints = 0; } } } namespace Ndrangheta.NPCs { public sealed class DonSalvatoreNPC : NPC { public const string NpcId = "Ndrangheta_don_salvatore"; public const string DonFirstName = "Don"; public const string DonLastName = "Salvatore"; public const string DonQuestIconResource = "Ndrangheta.assets.don_quest.png"; public const string DonPoiIconResource = "Ndrangheta.assets.don_icon.png"; public const string DeadDropQuestIconResource = "Ndrangheta.assets.deaddrop_quest.png"; private static Vector3 _resolvedSpawnPos; private static readonly Vector3 HiddenParkPos = new Vector3(0f, -2000f, 0f); private static bool _spawnPosResolved; private static bool _spawnPosFromGazebo; private static Vector3 _sceneOverridePos; private static float _sceneOverrideYaw; private static bool _pacifismLoggedOnce; private static MethodInfo _removePanickedMi; private static bool _removePanickedResolved; private static bool _regionLoggedOnce; private static readonly Color OutfitBlack = new Color(0.07f, 0.07f, 0.08f); private static readonly Color ShirtRed = new Color(0.42f, 0.04f, 0.05f); private static readonly Color GoldChain = new Color(0.92f, 0.78f, 0.2f); private static readonly Color FallbackSkin = Color32.op_Implicit(new Color32((byte)220, (byte)188, (byte)158, byte.MaxValue)); private static readonly Color FallbackEye = Color.white; private static readonly Color HairBlack = new Color(0.05f, 0.04f, 0.04f); private static readonly Color HatBlack = new Color(0.08f, 0.07f, 0.08f); public static DonSalvatoreNPC Instance { get; private set; } public static NPC CachedGameNpc { get; private set; } public static bool SceneOverrideActive { get; private set; } public override bool IsPhysical => true; public static bool TryGetSpawnPosition(out Vector3 pos) { //IL_0002: 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) pos = _resolvedSpawnPos; return _spawnPosResolved; } public static bool ResolveGazeboPosition(out Vector3 pos) { //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) try { EnsureSpawnPositionResolved(); } catch { } pos = _resolvedSpawnPos; return _spawnPosResolved && _spawnPosFromGazebo; } public static void ResetForDemotion() { Instance = null; CachedGameNpc = null; SceneOverrideActive = false; } public static void WarpToScene(Vector3 pos, float yaw) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_016a: 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_0015: 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_00f9: 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_0029: 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 { if (!SessionGate.IsAuthority) { return; } try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(pos, ref val, 8f, -1)) { pos = ((NavMeshHit)(ref val)).position; } } catch { } _sceneOverridePos = pos; _sceneOverrideYaw = yaw; SceneOverrideActive = true; NPC val2 = CachedGameNpc ?? NPCManager.GetNPC("Ndrangheta_don_salvatore"); if ((Object)(object)val2 == (Object)null) { CachedGameNpc = null; NDLog.DebugWarn("[GANGWAR] Don not resolvable for scene warp."); return; } CachedGameNpc = val2; try { if ((Object)(object)((Component)val2).gameObject != (Object)null && !((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(true); } } catch { } try { if ((Object)(object)((Component)val2).transform != (Object)null) { ((Component)val2).transform.position = pos; ((Component)val2).transform.rotation = Quaternion.Euler(0f, yaw, 0f); } } catch { } try { if ((Object)(object)val2.Movement != (Object)null) { val2.Movement.Warp(pos); } } catch { } try { val2.SetVisible(true, true); } catch { } try { EnforcePacifism(val2); } catch { } NDLog.Debug($"[GANGWAR] Don warped to arena @ ({pos.x:F1},{pos.y:F1},{pos.z:F1})."); } catch (Exception ex) { NDLog.DebugWarn("DonSalvatoreNPC.WarpToScene: " + ex.Message); } } public static void RestoreFromScene() { SceneOverrideActive = false; } public static void TickWatchdog() { //IL_01b3: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_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) //IL_00e1: 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_00e4: 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) //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) if (!SessionGate.IsAuthority) { return; } try { NPC val = CachedGameNpc; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { val = NPCManager.GetNPC("Ndrangheta_don_salvatore"); if ((Object)(object)val != (Object)null) { CachedGameNpc = val; } } if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } EnforcePacifism(val); float num = -15f; Vector3 val2; if (SceneOverrideActive) { val2 = _sceneOverridePos; num = _sceneOverrideYaw; } else if (TerritoryHandover.HandoverActive) { val2 = HiddenParkPos; } else { if (!_spawnPosResolved) { return; } val2 = _resolvedSpawnPos; } Vector3 position = ((Component)val).transform.position; Vector3 val3 = position - val2; if (((Vector3)(ref val3)).sqrMagnitude <= 9f) { return; } try { NPCScheduleManager componentInChildren = ((Component)val).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } if ((Object)(object)val.Movement != (Object)null) { try { val.Movement.PauseMovement(); } catch { } try { val.Movement.SetAgentEnabled(false); } catch { } } NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } ((Component)val).transform.position = val2; ((Component)val).transform.rotation = Quaternion.Euler(0f, num, 0f); NDLog.Debug($"Don re-parked at ({val2.x:F1},{val2.y:F1},{val2.z:F1})" + (TerritoryHandover.HandoverActive ? " (hidden — boss phase)." : " (gazebo).")); } catch (Exception ex) { NDLog.DebugWarn("DonSalvatoreNPC.TickWatchdog: " + ex.Message); } } public DonSalvatoreNPC() { Instance = this; try { GameObject gameObject = ((NPC)this).gameObject; NPC val = ((gameObject != null) ? gameObject.GetComponent() : null); if ((Object)(object)val != (Object)null) { CachedGameNpc = val; } } catch { } } protected override void ConfigurePrefab(NPCPrefabBuilder builder) { //IL_001c: 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) EnsureSpawnPositionResolved(); builder.WithIdentity("Ndrangheta_don_salvatore", "Don", "Salvatore").WithSpawnPosition(_resolvedSpawnPos, Quaternion.Euler(0f, -15f, 0f)); } private static void EnsureSpawnPositionResolved() { //IL_00aa: 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_0013: 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) if (_spawnPosFromGazebo) { return; } try { _resolvedSpawnPos = SuburbiaPositions.ResolveSpawnPosition(out var source); _spawnPosResolved = true; _spawnPosFromGazebo = source?.StartsWith("Gazebo") ?? false; NDLog.Debug($"Spawn position resolved from {source}: ({_resolvedSpawnPos.x:F1},{_resolvedSpawnPos.y:F1},{_resolvedSpawnPos.z:F1})"); } catch (Exception ex) { if (!_spawnPosResolved) { _resolvedSpawnPos = new Vector3(92.4f, 4.3f, -130.2f); _spawnPosResolved = true; } NDLog.Warn("ResolveSpawnPosition: " + ex.Message); } } protected override void OnCreated() { ((NPC)this).OnCreated(); NDLog.Debug("DonSalvatoreNPC OnCreated — starting setup coroutine"); MelonCoroutines.Start(SetupCoroutine()); } private IEnumerator SetupCoroutine() { float timeout = 12f; float elapsed = 0f; bool aiDisabled = false; while (elapsed < timeout && !aiDisabled) { aiDisabled = TryDisableNPCSystems(); if (!aiDisabled) { elapsed += Time.deltaTime; yield return null; } } if (!aiDisabled) { NDLog.Error("Don NPC never registered in NPCManager — setup aborted"); yield break; } float louisWait = 0f; while (!LouisAvatarCloner.TryCaptureSnapshot() && louisWait < 10f) { louisWait += Time.deltaTime; yield return null; } ApplyAvatar(); NDLog.Debug("Don Salvatore setup complete."); } private bool TryDisableNPCSystems() { //IL_002f: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_008e: 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_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) try { NPC nPC = NPCManager.GetNPC("Ndrangheta_don_salvatore"); if ((Object)(object)nPC == (Object)null) { return false; } CachedGameNpc = nPC; EnsureSpawnPositionResolved(); Vector3 val = _resolvedSpawnPos; NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(val, ref val2, 1.5f, -1)) { val = ((NavMeshHit)(ref val2)).position; } ((Component)nPC).transform.position = val; ((Component)nPC).transform.rotation = Quaternion.Euler(0f, -15f, 0f); NDLog.Debug($"Don positioned at ({val.x:F1},{val.y:F1},{val.z:F1}) [exact gazebo, 1.5m-snap max]"); SetMessagingRegion(nPC, "setup"); NPCScheduleManager componentInChildren = ((Component)nPC).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } if ((Object)(object)nPC.Movement != (Object)null) { try { nPC.Movement.PauseMovement(); } catch { } try { nPC.Movement.SetAgentEnabled(false); } catch { } } NavMeshAgent component = ((Component)nPC).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } VisionCone componentInChildren2 = ((Component)nPC).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null) { ((Behaviour)componentInChildren2).enabled = false; } EnforcePacifism(nPC); NDLog.Debug("Don NPC: Schedule/Movement/NavMesh/Vision off; Behaviour+Avatar intact"); return true; } catch (Exception ex) { NDLog.DebugWarn("TryDisableNPCSystems: " + ex.Message); return false; } } private static void EnforcePacifism(NPC npc) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)npc == (Object)null) { return; } try { NPCResponses responses = npc.Responses; NPCResponses_Civilian val = (NPCResponses_Civilian)(object)((responses is NPCResponses_Civilian) ? responses : null); if ((Object)(object)val != (Object)null) { ((NPCResponses)val).npc.NPCData.Behaviour.CanCallPolice = false; val.OverrideThreatResponses = true; val.ThreatResponseOverride = (EAttackResponse)0; } else if (!_pacifismLoggedOnce) { NDLog.DebugWarn("EnforcePacifism: Responses is not Civilian (" + (((object)npc.Responses)?.GetType().Name ?? "null") + ")."); } try { npc.NPCData.Behaviour.DefaultAggression = 0f; } catch { } NPCBehaviour behaviour = npc.Behaviour; if ((Object)(object)behaviour != (Object)null) { try { CallPoliceBehaviour callPoliceBehaviour = behaviour.CallPoliceBehaviour; if ((Object)(object)callPoliceBehaviour != (Object)null && ((Behaviour)callPoliceBehaviour).Enabled) { ((Behaviour)callPoliceBehaviour).Disable_Server(); } } catch { } try { FleeBehaviour fleeBehaviour = behaviour.FleeBehaviour; if ((Object)(object)fleeBehaviour != (Object)null && ((Behaviour)fleeBehaviour).Enabled) { ((Behaviour)fleeBehaviour).Disable_Server(); } } catch { } try { CoweringBehaviour coweringBehaviour = behaviour.CoweringBehaviour; if ((Object)(object)coweringBehaviour != (Object)null && ((Behaviour)coweringBehaviour).Enabled) { ((Behaviour)coweringBehaviour).Disable_Server(); } } catch { } } bool flag = false; try { flag = npc.IsPanicked; } catch { } if (flag) { ClearPanic(npc); } if (!_pacifismLoggedOnce) { _pacifismLoggedOnce = true; NDLog.Debug("Don pacifism enforced (no panic, no police, no flee/fight)."); } } catch (Exception ex) { NDLog.DebugWarn("EnforcePacifism: " + ex.Message); } } private static void ClearPanic(NPC npc) { try { if (!_removePanickedResolved) { _removePanickedResolved = true; _removePanickedMi = typeof(NPC).GetMethod("RemovePanicked", BindingFlags.Instance | BindingFlags.NonPublic); if (_removePanickedMi == null) { NDLog.DebugWarn("ClearPanic: RemovePanicked() not found via reflection."); } } _removePanickedMi?.Invoke(npc, null); } catch (Exception ex) { NDLog.DebugWarn("ClearPanic: " + ex.Message); } } private static void SetMessagingRegion(NPC npc, string source) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)npc == (Object)null) { return; } try { if ((int)npc.Region != 4) { npc.Region = (EMapRegion)4; if (!_regionLoggedOnce) { NDLog.Debug("Don NPC.Region set to Suburbia (" + source + ")"); _regionLoggedOnce = true; } } } catch { } } private void ApplyAvatar() { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0299: 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) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0307: 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_01dd: 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_026c: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: 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) if (((NPC)this).Appearance == null) { NDLog.Warn("Appearance API unavailable — Avatar unchanged"); return; } LouisAvatarCloner.LouisSnapshot lastSnapshot = LouisAvatarCloner.LastSnapshot; bool valid = lastSnapshot.Valid; try { if (valid) { ((NPC)this).Appearance.Set((object)Color32.op_Implicit(lastSnapshot.SkinColor)); ((NPC)this).Appearance.Set((object)lastSnapshot.EyeBallTint); ((NPC)this).Appearance.Set((object)lastSnapshot.PupilDilation); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowScale); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowThickness); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowRestingHeight); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowRestingAngle); ((NPC)this).Appearance.Set((object)lastSnapshot.Gender); } else { NDLog.Warn("Louis snapshot missing — falling back to neutral male defaults"); ((NPC)this).Appearance.Set((object)FallbackSkin); ((NPC)this).Appearance.Set((object)FallbackEye); ((NPC)this).Appearance.Set((object)0f); } ((NPC)this).Appearance.Set((object)1.05f); ((NPC)this).Appearance.Set((object)0.5f); ((NPC)this).Appearance.Set((object)"Avatar/Hair/tony/Tony"); ((NPC)this).Appearance.Set((object)HairBlack); if (valid && lastSnapshot.FaceLayerPaths != null) { for (int i = 0; i < lastSnapshot.FaceLayerPaths.Length; i++) { string text = lastSnapshot.FaceLayerPaths[i]; if (!string.IsNullOrEmpty(text)) { Color val = ((i < lastSnapshot.FaceLayerColors.Length) ? lastSnapshot.FaceLayerColors[i] : Color.white); try { ((NPC)this).Appearance.WithFaceLayer(text, val); } catch (Exception ex) { NDLog.DebugWarn("FaceLayer '" + text + "': " + ex.Message); } } } } else { ((NPC)this).Appearance.WithFaceLayer("Avatar/Layers/Face/Face_Neutral", Color.white); ((NPC)this).Appearance.WithFaceLayer("Avatar/Layers/Face/FacialHair_Goatee", HairBlack); } ((NPC)this).Appearance.WithBodyLayer("Avatar/Layers/Bottom/Jeans", OutfitBlack); ((NPC)this).Appearance.WithBodyLayer("Avatar/Layers/Top/Buttonup", ShirtRed); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Chest/Blazer/Blazer", OutfitBlack); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Neck/GoldChain/GoldChain", GoldChain); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Feet/CombatBoots/CombatBoots", OutfitBlack); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Head/PorkpieHat/PorkpieHat", HatBlack); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Head/LegendSunglasses/LegendSunglasses", OutfitBlack); NDLog.Debug($"Don avatar applied (familyDNA={valid}, outfit=boots+hat+glasses)"); } catch (Exception ex2) { NDLog.Error("ApplyAvatar failed: " + ex2.Message); } } } public abstract class GuardNPC : NPC { public const int VILLA_SLOTS = 7; public const int TORTURE_SLOT_L = 7; public const int TORTURE_SLOT_R = 8; public const int COUNT = 9; private static readonly Vector3 HiddenSpawn = new Vector3(0f, -2000f, 0f); private static readonly NPC[] _gameNpc = (NPC[])(object)new NPC[9]; private static readonly bool[] _deployed = new bool[9]; private static readonly Color OutfitBlack = new Color(0.07f, 0.07f, 0.08f); private static readonly Color JacketDark = new Color(0.12f, 0.12f, 0.14f); private static readonly Color[] HairTones = (Color[])(object)new Color[3] { new Color(0.06f, 0.05f, 0.05f), new Color(0.1f, 0.07f, 0.05f), new Color(0.18f, 0.13f, 0.09f) }; private static readonly Color[] SkinTones = (Color[])(object)new Color[4] { Color32.op_Implicit(new Color32((byte)214, (byte)178, (byte)145, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)196, (byte)156, (byte)120, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)168, (byte)126, (byte)96, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)232, (byte)198, (byte)170, byte.MaxValue)) }; private static readonly string[] Hairs = new string[3] { "Avatar/Hair/tony/Tony", "Avatar/Hair/bowlcut/BowlCut", "Avatar/Hair/buzzcut/BuzzCut" }; private const float CLIENT_POST_REASSERT = 0.08f; private static readonly Vector3[] _staticReq = (Vector3[])(object)new Vector3[9]; private static readonly Vector3[] _staticPost = (Vector3[])(object)new Vector3[9]; private static readonly float[] _staticYaw = new float[9]; private static readonly bool[] _staticSet = new bool[9]; private static readonly Vector3[] _walkTarget = (Vector3[])(object)new Vector3[9]; private static readonly bool[] _walkHasTarget = new bool[9]; private static readonly Vector3[][] _walkCorners = new Vector3[9][]; private static readonly int[] _walkCorner = new int[9]; private const float WALK_CORNER_REACH = 0.4f; private const float CLIENT_WALK_SPEED = 1.9f; private const float CLIENT_VELOCITY_SAMPLE_LENGTH = 0.6f; protected abstract int Slot { get; } public override bool IsPhysical => true; public static string SlotId(int slot) { return $"Ndrangheta_guard_{slot}"; } public static string SlotFirstName(int slot) { return "Guardia"; } protected override void ConfigurePrefab(NPCPrefabBuilder builder) { //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) builder.WithIdentity(SlotId(Slot), SlotFirstName(Slot), (string)null).WithSpawnPosition(HiddenSpawn, Quaternion.identity); } protected override void OnCreated() { ((NPC)this).OnCreated(); int slot = Slot; NDLog.Debug($"GuardNPC[{slot}] OnCreated"); MelonCoroutines.Start(SetupCoroutine(slot)); } private IEnumerator SetupCoroutine(int slot) { float elapsed = 0f; float timeout = 12f; bool ready = false; while (elapsed < timeout && !ready) { ready = TryParkAndDisable(slot); if (!ready) { elapsed += Time.deltaTime; yield return null; } } if (!ready) { NDLog.Warn($"GuardNPC[{slot}] never registered in NPCManager — setup aborted."); yield break; } ApplyAvatar(slot); NDLog.Debug($"GuardNPC[{slot}] setup complete (parked hidden, mortal, schedule off)."); } private bool TryParkAndDisable(int slot) { //IL_002f: 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_004e: Unknown result type (might be due to invalid IL or missing references) try { NPC nPC = NPCManager.GetNPC(SlotId(slot)); if ((Object)(object)nPC == (Object)null) { return false; } _gameNpc[slot] = nPC; ((Component)nPC).transform.position = HiddenSpawn; ((Component)nPC).transform.rotation = Quaternion.identity; try { nPC.Region = (EMapRegion)5; } catch { } DisableSchedule(nPC); if ((Object)(object)nPC.Movement != (Object)null) { try { nPC.Movement.PauseMovement(); } catch { } try { nPC.Movement.SetAgentEnabled(false); } catch { } try { ((Behaviour)nPC.Movement).enabled = false; } catch { } } NavMeshAgent component = ((Component)nPC).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } VisionCone componentInChildren = ((Component)nPC).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } return true; } catch (Exception ex) { NDLog.DebugWarn($"GuardNPC[{slot}].TryParkAndDisable: {ex.Message}"); return false; } } private void ApplyAvatar(int slot) { //IL_0029: 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_00cb: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0156: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) if (((NPC)this).Appearance == null) { return; } try { ((NPC)this).Appearance.Set((object)SkinTones[slot % SkinTones.Length]); ((NPC)this).Appearance.Set((object)Color.white); ((NPC)this).Appearance.Set((object)0f); ((NPC)this).Appearance.Set((object)(1.02f + (float)(slot % 3) * 0.02f)); ((NPC)this).Appearance.Set((object)0.55f); ((NPC)this).Appearance.Set((object)Hairs[slot % Hairs.Length]); ((NPC)this).Appearance.Set((object)HairTones[slot % HairTones.Length]); ((NPC)this).Appearance.WithFaceLayer("Avatar/Layers/Face/Face_Neutral", Color.white); if (slot % 2 == 0) { ((NPC)this).Appearance.WithFaceLayer("Avatar/Layers/Face/FacialHair_Goatee", HairTones[slot % HairTones.Length]); } ((NPC)this).Appearance.WithBodyLayer("Avatar/Layers/Bottom/Jeans", OutfitBlack); ((NPC)this).Appearance.WithBodyLayer("Avatar/Layers/Top/Buttonup", OutfitBlack); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Chest/Blazer/Blazer", JacketDark); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Feet/CombatBoots/CombatBoots", OutfitBlack); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Head/LegendSunglasses/LegendSunglasses", OutfitBlack); NDLog.Debug($"GuardNPC[{slot}] avatar applied (guardia look)."); } catch (Exception ex) { NDLog.Warn($"GuardNPC[{slot}].ApplyAvatar: {ex.Message}"); } } public static void CreateAll() { if (!SessionGate.IsAuthority) { return; } for (int i = 0; i < 9; i++) { try { if (!((Object)(object)NPCManager.GetNPC(SlotId(i)) != (Object)null)) { switch (i) { case 0: new Guard0NPC(); break; case 1: new Guard1NPC(); break; case 2: new Guard2NPC(); break; case 3: new Guard3NPC(); break; case 4: new Guard4NPC(); break; case 5: new Guard5NPC(); break; case 6: new Guard6NPC(); break; case 7: new Guard7NPC(); break; case 8: new Guard8NPC(); break; } NDLog.Debug($"GuardNPC[{i}] instantiated."); } } catch (Exception ex) { NDLog.Warn($"GuardNPC[{i}] spawn: {ex.Message}"); } } } public static void ResetCaches() { for (int i = 0; i < 9; i++) { _gameNpc[i] = null; _deployed[i] = false; _staticSet[i] = false; _walkHasTarget[i] = false; _walkCorners[i] = null; } } public static NPC Resolve(int slot) { if (slot < 0 || slot >= 9) { return null; } NPC val = _gameNpc[slot]; if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null) { return val; } try { val = NPCManager.GetNPC(SlotId(slot)); } catch { val = null; } if ((Object)(object)val != (Object)null) { _gameNpc[slot] = val; } return val; } public static bool Exists(int slot) { return (Object)(object)Resolve(slot) != (Object)null; } public static bool IsDeployed(int slot) { return slot >= 0 && slot < 9 && _deployed[slot]; } public static bool IsDownOrKO(int slot) { try { NPC val = Resolve(slot); NPCHealth val2 = ((val != null) ? val.Health : null); return (Object)(object)val2 != (Object)null && (val2.IsDead || val2.IsKnockedOut); } catch { return false; } } public static void ClientHoldHidden(int slot) { try { ClearStaticPost(slot); ClearWalk(slot); NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } ClientStopLocalSim(val); try { val.SetVisible(false, false); } catch { } } catch { } } public static void ClientPark(int slot) { try { ClearStaticPost(slot); ClearWalk(slot); NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } ClientStopLocalSim(val); try { val.SetVisible(false, false); } catch { } } catch { } } public static void ClientPlaceStatic(int slot, Vector3 pos, float yaw) { //IL_0143: 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_005d: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00f3: 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_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_0080: 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) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00c3: 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_00aa: 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_011b: Unknown result type (might be due to invalid IL or missing references) try { if (slot < 0 || slot >= 9) { return; } NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } ClientStopLocalSim(val); Vector3 val2; if (_staticSet[slot]) { val2 = _staticReq[slot] - pos; if (!(((Vector3)(ref val2)).sqrMagnitude > 0.04f)) { goto IL_00db; } } Vector3 val3 = pos; NavMeshHit val4 = default(NavMeshHit); if (NavMesh.SamplePosition(pos + Vector3.up * 1.5f, ref val4, 6f, -1)) { val3 = ((NavMeshHit)(ref val4)).position; } _staticReq[slot] = pos; _staticPost[slot] = val3; _staticYaw[slot] = yaw; _staticSet[slot] = true; goto IL_00db; IL_00db: Vector3 val5 = _staticPost[slot]; val2 = ((Component)val).transform.position - val5; if (((Vector3)(ref val2)).sqrMagnitude <= 0.0064f) { return; } try { ((Component)val).transform.position = val5; } catch { } try { ((Component)val).transform.rotation = Quaternion.Euler(0f, _staticYaw[slot], 0f); } catch { } } catch { } } private static void ClearStaticPost(int slot) { if (slot >= 0 && slot < 9) { _staticSet[slot] = false; } } private static void ClientStopLocalSim(NPC npc) { try { if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.PauseMovement(); } catch { } try { npc.Movement.SetAgentEnabled(false); } catch { } } NavMeshAgent component = ((Component)npc).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } } catch { } } public static void ClientReleaseAgent(int slot) { try { ClearWalk(slot); NPC val = Resolve(slot); if ((Object)(object)val == (Object)null) { return; } NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if (!((Object)(object)component != (Object)null) || !((Behaviour)component).enabled) { return; } try { if (component.isOnNavMesh) { component.isStopped = true; if (component.hasPath) { component.ResetPath(); } } } catch { } try { ((Behaviour)component).enabled = false; } catch { } } catch { } } public static void ClientDrive(int slot, Vector3 placeAt, Vector3 target, bool holding) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0125: 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_00b8: 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_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_00ca: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) try { NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component == (Object)null) { return; } try { if ((Object)(object)val.Movement != (Object)null && !((Behaviour)val.Movement).enabled) { ((Behaviour)val.Movement).enabled = true; } } catch { } if (!((Behaviour)component).enabled) { Vector3 val2; if (((Component)val).transform.position.y < -100f) { val2 = placeAt; NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(placeAt + Vector3.up * 1.5f, ref val3, 8f, -1)) { val2 = ((NavMeshHit)(ref val3)).position; } try { ((Component)val).transform.position = val2; } catch { } } else { val2 = ((Component)val).transform.position; NavMeshHit val4 = default(NavMeshHit); if (NavMesh.SamplePosition(val2 + Vector3.up * 1.5f, ref val4, 4f, -1)) { val2 = ((NavMeshHit)(ref val4)).position; } } try { ((Behaviour)component).enabled = true; } catch { } try { component.updatePosition = true; component.updateRotation = true; } catch { } try { component.speed = 1.9f; component.angularSpeed = 240f; component.acceleration = 16f; component.stoppingDistance = 0.4f; } catch { } try { if (component.isOnNavMesh) { component.Warp(val2); } } catch { } try { SmoothedVelocityCalculator val5 = (((Object)(object)val.Movement != (Object)null) ? val.Movement.VelocityCalculator : null); if ((Object)(object)val5 != (Object)null) { if (!((Behaviour)val5).enabled) { ((Behaviour)val5).enabled = true; } try { val5.SampleLength = 0.6f; } catch { } val5.FlushBuffer(); } } catch { } } else { try { SmoothedVelocityCalculator val6 = (((Object)(object)val.Movement != (Object)null) ? val.Movement.VelocityCalculator : null); if ((Object)(object)val6 != (Object)null) { if (!((Behaviour)val6).enabled) { ((Behaviour)val6).enabled = true; } try { val6.SampleLength = 0.6f; } catch { } } } catch { } } if (!component.isOnNavMesh) { return; } if (holding) { try { component.isStopped = true; } catch { } try { if (component.hasPath) { component.ResetPath(); } return; } catch { return; } } try { component.isStopped = false; } catch { } if (component.hasPath) { Vector3 val7 = component.destination - target; if (!(((Vector3)(ref val7)).sqrMagnitude > 0.25f)) { return; } } try { component.SetDestination(target); } catch { } } catch { } } public static void ClientWalkTo(int slot, Vector3 target, float faceYaw, bool faceWhenArrived) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: 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_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0201: 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_0210: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_0239: 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_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: 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_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Invalid comparison between Unknown and I4 //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: 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_02b5: 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_03af: 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_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) try { if (slot < 0 || slot >= 9) { return; } NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } Transform transform = ((Component)val).transform; NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { try { if (component.isOnNavMesh) { component.isStopped = true; if (component.hasPath) { component.ResetPath(); } } } catch { } try { ((Behaviour)component).enabled = false; } catch { } } try { if ((Object)(object)val.Movement != (Object)null && !((Behaviour)val.Movement).enabled) { ((Behaviour)val.Movement).enabled = true; } } catch { } try { SmoothedVelocityCalculator val2 = (((Object)(object)val.Movement != (Object)null) ? val.Movement.VelocityCalculator : null); if ((Object)(object)val2 != (Object)null && !((Behaviour)val2).enabled) { ((Behaviour)val2).enabled = true; } } catch { } if (transform.position.y < -100f) { Vector3 position = target; NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(target + Vector3.up * 1.5f, ref val3, 10f, -1)) { position = ((NavMeshHit)(ref val3)).position; } try { transform.position = position; } catch { } _walkHasTarget[slot] = false; } if (_walkHasTarget[slot]) { Vector3 val4 = _walkTarget[slot] - target; if (!(((Vector3)(ref val4)).sqrMagnitude > 0.25f) && _walkCorners[slot] != null) { goto IL_02c3; } } try { val.SetVisible(true, false); } catch { } Vector3 val5 = target; NavMeshHit val6 = default(NavMeshHit); if (NavMesh.SamplePosition(target + Vector3.up * 1.5f, ref val6, 4f, -1)) { val5 = ((NavMeshHit)(ref val6)).position; } NavMeshPath val7 = new NavMeshPath(); if (NavMesh.CalculatePath(transform.position, val5, -1, val7) && (int)val7.status != 2 && val7.corners != null && val7.corners.Length != 0) { _walkCorners[slot] = val7.corners; } else { _walkCorners[slot] = (Vector3[])(object)new Vector3[1] { val5 }; } _walkCorner[slot] = ((_walkCorners[slot].Length > 1) ? 1 : 0); _walkTarget[slot] = target; _walkHasTarget[slot] = true; goto IL_02c3; IL_02c3: Vector3[] array = _walkCorners[slot]; if (array == null || array.Length == 0) { return; } int num = Mathf.Clamp(_walkCorner[slot], 0, array.Length - 1); Vector3 val8 = array[num]; Vector3 val9 = val8 - transform.position; val9.y = 0f; float magnitude = ((Vector3)(ref val9)).magnitude; if (magnitude <= 0.4f) { if (num >= array.Length - 1) { if (faceWhenArrived) { try { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0f, faceYaw, 0f), 6f * Time.deltaTime); return; } catch { return; } } } else { _walkCorner[slot] = num + 1; } return; } float num2 = 1.9f * Time.deltaTime; try { transform.position = Vector3.MoveTowards(transform.position, val8, num2); } catch { } try { Vector3 val10 = val9 / Mathf.Max(magnitude, 0.0001f); transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(val10), 12f * Time.deltaTime); } catch { } } catch { } } private static void ClearWalk(int slot) { if (slot >= 0 && slot < 9) { _walkHasTarget[slot] = false; _walkCorners[slot] = null; } } public static Vector3 SnapOr(Vector3 p) { //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_000d: 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_003a: 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_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_003e: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(p + Vector3.up * 1.5f, ref val, 8f, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return p; } public static bool HostWalkTo(int slot, Vector3 target, float reach, float faceYaw, bool faceWhenArrived) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0391: 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_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03af: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0172: 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_01d0: 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_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Invalid comparison between Unknown and I4 //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: 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) //IL_0237: 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_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) try { if (slot < 0 || slot >= 9) { return false; } NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return false; } Transform transform = ((Component)val).transform; NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { try { if (component.isOnNavMesh) { component.isStopped = true; if (component.hasPath) { component.ResetPath(); } } } catch { } try { ((Behaviour)component).enabled = false; } catch { } } try { if ((Object)(object)val.Movement != (Object)null) { if (!((Behaviour)val.Movement).enabled) { ((Behaviour)val.Movement).enabled = true; } val.Movement.ResumeMovement(); } } catch { } try { SmoothedVelocityCalculator val2 = (((Object)(object)val.Movement != (Object)null) ? val.Movement.VelocityCalculator : null); if ((Object)(object)val2 != (Object)null && !((Behaviour)val2).enabled) { ((Behaviour)val2).enabled = true; } } catch { } if (transform.position.y < -100f) { try { transform.position = SnapOr(target); } catch { } _walkHasTarget[slot] = false; } if (_walkHasTarget[slot]) { Vector3 val3 = _walkTarget[slot] - target; if (!(((Vector3)(ref val3)).sqrMagnitude > 0.25f) && _walkCorners[slot] != null) { goto IL_0269; } } Vector3 val4 = SnapOr(target); NavMeshPath val5 = new NavMeshPath(); if (NavMesh.CalculatePath(transform.position, val4, -1, val5) && (int)val5.status != 2 && val5.corners != null && val5.corners.Length != 0) { _walkCorners[slot] = val5.corners; } else { _walkCorners[slot] = (Vector3[])(object)new Vector3[1] { val4 }; } _walkCorner[slot] = ((_walkCorners[slot].Length > 1) ? 1 : 0); _walkTarget[slot] = target; _walkHasTarget[slot] = true; goto IL_0269; IL_0269: Vector3[] array = _walkCorners[slot]; if (array == null || array.Length == 0) { return false; } int num = Mathf.Clamp(_walkCorner[slot], 0, array.Length - 1); Vector3 val6 = array[num]; Vector3 val7 = val6 - transform.position; val7.y = 0f; float magnitude = ((Vector3)(ref val7)).magnitude; bool flag = num >= array.Length - 1; float num2 = (flag ? Mathf.Max(0.4f, reach) : 0.4f); if (magnitude <= num2) { if (flag) { if (faceWhenArrived) { try { transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0f, faceYaw, 0f), 6f * Time.deltaTime); } catch { } } return true; } _walkCorner[slot] = num + 1; return false; } float num3 = 1.9f * Time.deltaTime; try { transform.position = Vector3.MoveTowards(transform.position, val6, num3); } catch { } try { Vector3 val8 = val7 / Mathf.Max(magnitude, 0.0001f); transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(val8), 12f * Time.deltaTime); } catch { } return false; } catch { return false; } } public static void HostHoldPost(int slot, Vector3 pos, float yaw) { //IL_0100: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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) try { if (slot < 0 || slot >= 9) { return; } NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } ClearWalk(slot); NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { try { if (component.isOnNavMesh) { component.isStopped = true; if (component.hasPath) { component.ResetPath(); } } } catch { } try { ((Behaviour)component).enabled = false; } catch { } } try { if ((Object)(object)val.Movement != (Object)null) { if (!((Behaviour)val.Movement).enabled) { ((Behaviour)val.Movement).enabled = true; } val.Movement.ResumeMovement(); } } catch { } Vector3 val2 = SnapOr(pos); Vector3 val3 = ((Component)val).transform.position - val2; if (((Vector3)(ref val3)).sqrMagnitude > 1f) { try { ((Component)val).transform.position = val2; } catch { } } try { ((Component)val).transform.rotation = Quaternion.Euler(0f, yaw, 0f); } catch { } KeepCalm(slot); } catch { } } public static void TickHiddenWatchdog() { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0091: Unknown result type (might be due to invalid IL or missing references) if (!SessionGate.IsAuthority) { return; } bool flag = false; try { flag = RealEstateManager.VillaOwned; } catch { } for (int i = 0; i < 9; i++) { if (_deployed[i] || (i < 7 && flag)) { continue; } try { NPC val = Resolve(i); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } Vector3 val2 = ((Component)val).transform.position - HiddenSpawn; if (((Vector3)(ref val2)).sqrMagnitude <= 9f) { continue; } EnsureAlive(val); if ((Object)(object)val.Movement != (Object)null) { try { val.Movement.PauseMovement(); } catch { } try { val.Movement.SetAgentEnabled(false); } catch { } try { ((Behaviour)val.Movement).enabled = false; } catch { } } NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } Warp(val, HiddenSpawn); ((Component)val).transform.rotation = Quaternion.identity; } catch { } } } public static bool Deploy(int slot, Vector3 pos, float yaw) { //IL_0034: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0063: Unknown result type (might be due to invalid IL or missing references) try { NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return false; } EnsureAlive(val); NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(pos + Vector3.up * 1.5f, ref val2, 8f, -1)) { pos = ((NavMeshHit)(ref val2)).position; } Warp(val, pos); ((Component)val).transform.rotation = Quaternion.Euler(0f, yaw, 0f); DisableSchedule(val); if ((Object)(object)val.Movement != (Object)null) { try { ((Behaviour)val.Movement).enabled = true; } catch { } try { val.Movement.SetAgentEnabled(true); } catch { } try { val.Movement.ResumeMovement(); } catch { } try { val.Movement.MoveSpeedMultiplier = 1f; } catch { } } NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; } ArmWithShotgun(val); KeepCalm(slot); _deployed[slot] = true; return true; } catch (Exception ex) { NDLog.DebugWarn($"GuardNPC[{slot}].Deploy: {ex.Message}"); return false; } } public static void Retire(int slot) { //IL_0030: 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) try { _deployed[slot] = false; NPC val = Resolve(slot); if ((Object)(object)val == (Object)null) { return; } StandDown(slot); EnsureAlive(val); Warp(val, HiddenSpawn); ((Component)val).transform.rotation = Quaternion.identity; if ((Object)(object)val.Movement != (Object)null) { try { val.Movement.PauseMovement(); } catch { } try { val.Movement.SetAgentEnabled(false); } catch { } try { ((Behaviour)val.Movement).enabled = false; } catch { } } NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } } catch (Exception ex) { NDLog.DebugWarn($"GuardNPC[{slot}].Retire: {ex.Message}"); } } public static bool DeployStationary(int slot, Vector3 pos, float yaw, bool invincible = false) { //IL_0002: 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) if (!Deploy(slot, pos, yaw)) { return false; } try { NPC val = Resolve(slot); if ((Object)(object)val != (Object)null) { if ((Object)(object)val.Movement != (Object)null) { try { val.Movement.Stop(); } catch { } try { val.Movement.PauseMovement(); } catch { } } try { if ((Object)(object)((Component)val).transform != (Object)null) { ((Component)val).transform.rotation = Quaternion.Euler(0f, yaw, 0f); } } catch { } if (invincible) { try { if ((Object)(object)val.Health != (Object)null) { val.NPCData.Health.Invincible = true; } } catch { } } } } catch (Exception ex) { NDLog.DebugWarn($"GuardNPC[{slot}].DeployStationary: {ex.Message}"); } return true; } public static void HoldPost(int slot, Vector3 pos, float yaw) { //IL_002d: 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_005c: 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) try { NPC val = Resolve(slot); if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { if (Vector3.Distance(((Component)val).transform.position, pos) > 1.5f) { Warp(val, pos); } ((Component)val).transform.rotation = Quaternion.Euler(0f, yaw, 0f); KeepCalm(slot); } } catch { } } public static void SetInvincible(int slot, bool value) { try { NPC val = Resolve(slot); if ((Object)(object)val != (Object)null && (Object)(object)val.Health != (Object)null) { val.NPCData.Health.Invincible = value; } } catch { } } public static bool Engage(int slot, NPC target) { try { NPC val = Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)target == (Object)null) { return false; } CombatBehaviour val2 = val.Behaviour?.CombatBehaviour; if ((Object)(object)val2 == (Object)null) { return false; } NetworkObject val3 = (((Object)(object)((Component)target).gameObject != (Object)null) ? ((Component)target).gameObject.GetComponent() : null); if ((Object)(object)val3 == (Object)null) { return false; } ArmWithShotgun(val); val2.SetTargetAndEnable_Server(val3); return true; } catch (Exception ex) { NDLog.DebugWarn($"GuardNPC[{slot}].Engage: {ex.Message}"); return false; } } public static void StandDown(int slot) { try { NPC val = Resolve(slot); CombatBehaviour val2 = ((val == null) ? null : val.Behaviour?.CombatBehaviour); if ((Object)(object)val2 == (Object)null) { return; } try { ((Behaviour)val2).Deactivate(); } catch { } try { ((Behaviour)val2).Disable(); } catch { } } catch { } } public static void KeepCalm(int slot) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) try { NPC val = Resolve(slot); if ((Object)(object)val == (Object)null) { return; } NPCBehaviour behaviour = val.Behaviour; if ((Object)(object)behaviour != (Object)null) { TryKill((Behaviour)(object)behaviour.CoweringBehaviour); TryKill((Behaviour)(object)behaviour.HeavyFlinchBehaviour); TryKill((Behaviour)(object)behaviour.FleeBehaviour); } if (slot == 7 || slot == 8) { try { NPCResponses responses = val.Responses; NPCResponses_Civilian val2 = (NPCResponses_Civilian)(object)((responses is NPCResponses_Civilian) ? responses : null); if ((Object)(object)val2 != (Object)null) { ((NPCResponses)val2).npc.NPCData.Behaviour.CanCallPolice = false; val2.OverrideThreatResponses = true; val2.ThreatResponseOverride = (EAttackResponse)0; } } catch { } try { if ((Object)(object)behaviour != (Object)null) { CallPoliceBehaviour callPoliceBehaviour = behaviour.CallPoliceBehaviour; if ((Object)(object)callPoliceBehaviour != (Object)null && ((Behaviour)callPoliceBehaviour).Enabled) { ((Behaviour)callPoliceBehaviour).Disable_Server(); } } } catch { } try { val.NPCData.Behaviour.DefaultAggression = 0f; } catch { } } bool flag = false; try { flag = val.IsPanicked; } catch { } if (!flag) { return; } try { typeof(NPC).GetMethod("RemovePanicked", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(val, null); } catch { } } catch { } } private static void ArmWithShotgun(NPC npc) { try { CombatBehaviour val = ((npc == null) ? null : npc.Behaviour?.CombatBehaviour); if ((Object)(object)val == (Object)null) { return; } val.SetDefaultWeapon(LuckyWeaponVisual.LoadAvatarWeaponByPath("Avatar/Equippables/PumpShotgun")); val.GiveUpRange = 200f; try { val.DefaultSearchTime = 9999f; } catch { } try { val.SetWeapon("Avatar/Equippables/PumpShotgun"); } catch { } } catch { } } private static void DisableSchedule(NPC npc) { try { NPCScheduleManager componentInChildren = ((Component)npc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } } private static void EnsureAlive(NPC npc) { try { NPCHealth health = npc.Health; if ((Object)(object)health == (Object)null || (!health.IsDead && !health.IsKnockedOut)) { return; } try { health.Revive(); } catch { } try { health.RestoreHealth(); } catch { } } catch { } } private static void Warp(NPC npc, Vector3 pos) { //IL_0066: 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_0047: Unknown result type (might be due to invalid IL or missing references) try { NavMeshAgent component = ((Component)npc).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { component.Warp(pos); return; } if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.Warp(pos); return; } catch { } } } catch { } try { ((Component)npc).transform.position = pos; } catch { } } private static void TryKill(Behaviour b) { if ((Object)(object)b == (Object)null) { return; } try { b.Disable(); } catch { } try { ((Behaviour)b).enabled = false; } catch { } } } public sealed class Guard0NPC : GuardNPC { protected override int Slot => 0; } public sealed class Guard1NPC : GuardNPC { protected override int Slot => 1; } public sealed class Guard2NPC : GuardNPC { protected override int Slot => 2; } public sealed class Guard3NPC : GuardNPC { protected override int Slot => 3; } public sealed class Guard4NPC : GuardNPC { protected override int Slot => 4; } public sealed class Guard5NPC : GuardNPC { protected override int Slot => 5; } public sealed class Guard6NPC : GuardNPC { protected override int Slot => 6; } public sealed class Guard7NPC : GuardNPC { protected override int Slot => 7; } public sealed class Guard8NPC : GuardNPC { protected override int Slot => 8; } public sealed class LuckyNPC : NPC { public const string NpcId = "Ndrangheta_lucky"; public const string FirstName = "Lucky"; public const string LastName = "Mancuso"; private static readonly Vector3 HiddenSpawn = new Vector3(0f, -2000f, 0f); private static readonly Vector3 HitOffsetFromTarget = new Vector3(1.2f, 0f, -1.2f); private static readonly Color OutfitBlack = new Color(0.07f, 0.07f, 0.08f); private static readonly Color JacketDark = new Color(0.12f, 0.12f, 0.14f); private static readonly Color HairDark = new Color(0.06f, 0.05f, 0.05f); private static readonly Color FallbackSkin = Color32.op_Implicit(new Color32((byte)210, (byte)178, (byte)148, byte.MaxValue)); public static LuckyNPC Instance { get; private set; } public static NPC CachedGameNpc { get; private set; } public static bool IsDownAndOut { get { try { NPC val = ResolveNpc(); if ((Object)(object)val == (Object)null) { return false; } NPCHealth health = val.Health; if ((Object)(object)health == (Object)null) { return false; } return health.IsDead || health.IsKnockedOut; } catch { return false; } } } public override bool IsPhysical => true; public LuckyNPC() { Instance = this; try { GameObject gameObject = ((NPC)this).gameObject; NPC val = ((gameObject != null) ? gameObject.GetComponent() : null); if ((Object)(object)val != (Object)null) { CachedGameNpc = val; } } catch { } } protected override void ConfigurePrefab(NPCPrefabBuilder builder) { //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) builder.WithIdentity("Ndrangheta_lucky", "Lucky", "Mancuso").WithSpawnPosition(HiddenSpawn, Quaternion.identity); } protected override void OnCreated() { ((NPC)this).OnCreated(); NDLog.Debug("LuckyNPC OnCreated"); MelonCoroutines.Start(SetupCoroutine()); } private IEnumerator SetupCoroutine() { float timeout = 12f; float elapsed = 0f; bool ready = false; while (elapsed < timeout && !ready) { ready = TryDisableNPCSystems(); if (!ready) { elapsed += Time.deltaTime; yield return null; } } if (!ready) { NDLog.Warn("LuckyNPC never registered in NPCManager — setup aborted"); yield break; } float mackWait = 0f; while (!MackAvatarCloner.TryCaptureSnapshot() && mackWait < 10f) { mackWait += Time.deltaTime; yield return null; } ApplyAvatar(); NDLog.Debug($"Lucky setup complete (visible={true})."); } private bool TryDisableNPCSystems() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) try { NPC nPC = NPCManager.GetNPC("Ndrangheta_lucky"); if ((Object)(object)nPC == (Object)null) { return false; } ((Component)nPC).transform.position = HiddenSpawn; ((Component)nPC).transform.rotation = Quaternion.identity; try { nPC.Region = (EMapRegion)4; } catch { } NPCScheduleManager componentInChildren = ((Component)nPC).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } if ((Object)(object)nPC.Movement != (Object)null) { try { nPC.Movement.PauseMovement(); } catch { } try { nPC.Movement.SetAgentEnabled(false); } catch { } DisableMovementComponentIfParked(nPC); } NavMeshAgent component = ((Component)nPC).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } VisionCone componentInChildren2 = ((Component)nPC).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null) { ((Behaviour)componentInChildren2).enabled = false; } NDLog.Debug($"LuckyNPC: parked at hidden spawn ({HiddenSpawn.x:F1},{HiddenSpawn.y:F1},{HiddenSpawn.z:F1}), AI off"); return true; } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.TryDisableNPCSystems: " + ex.Message); return false; } } private void ApplyAvatar() { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0171: 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) //IL_0282: 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_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: 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_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_01da: 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) if (((NPC)this).Appearance == null) { return; } MackAvatarCloner.MackSnapshot lastSnapshot = MackAvatarCloner.LastSnapshot; bool valid = lastSnapshot.Valid; try { if (valid) { ((NPC)this).Appearance.Set((object)Color32.op_Implicit(lastSnapshot.SkinColor)); ((NPC)this).Appearance.Set((object)lastSnapshot.EyeBallTint); ((NPC)this).Appearance.Set((object)lastSnapshot.PupilDilation); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowScale); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowThickness); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowRestingHeight); ((NPC)this).Appearance.Set((object)lastSnapshot.EyebrowRestingAngle); ((NPC)this).Appearance.Set((object)lastSnapshot.Gender); } else { ((NPC)this).Appearance.Set((object)FallbackSkin); ((NPC)this).Appearance.Set((object)Color.white); ((NPC)this).Appearance.Set((object)0f); } ((NPC)this).Appearance.Set((object)1f); ((NPC)this).Appearance.Set((object)0.5f); ((NPC)this).Appearance.Set((object)"Avatar/Hair/tony/Tony"); ((NPC)this).Appearance.Set((object)HairDark); if (valid && lastSnapshot.FaceLayerPaths != null) { for (int i = 0; i < lastSnapshot.FaceLayerPaths.Length; i++) { string text = lastSnapshot.FaceLayerPaths[i]; if (!string.IsNullOrEmpty(text)) { Color val = ((i < lastSnapshot.FaceLayerColors.Length) ? lastSnapshot.FaceLayerColors[i] : Color.white); try { ((NPC)this).Appearance.WithFaceLayer(text, val); } catch (Exception ex) { NDLog.DebugWarn("Lucky FaceLayer '" + text + "': " + ex.Message); } } } } else { ((NPC)this).Appearance.WithFaceLayer("Avatar/Layers/Face/Face_Neutral", Color.white); ((NPC)this).Appearance.WithFaceLayer("Avatar/Layers/Face/FacialHair_Goatee", HairDark); } ((NPC)this).Appearance.WithBodyLayer("Avatar/Layers/Bottom/Jeans", OutfitBlack); ((NPC)this).Appearance.WithBodyLayer("Avatar/Layers/Top/Buttonup", OutfitBlack); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Chest/Blazer/Blazer", JacketDark); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Feet/CombatBoots/CombatBoots", OutfitBlack); ((NPC)this).Appearance.WithAccessoryLayer("Avatar/Accessories/Head/LegendSunglasses/LegendSunglasses", OutfitBlack); NDLog.Debug($"Lucky avatar applied (mackClone={valid})."); } catch (Exception ex2) { NDLog.Warn("LuckyNPC.ApplyAvatar failed: " + ex2.Message); } } public static void TeleportNearTarget(NPC target) { //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_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_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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) //IL_0096: 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_00a6: 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_00ad: 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_00c3: 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_00ed: 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_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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_013b: 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_011d: 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) if ((Object)(object)target == (Object)null) { return; } try { NPC val = ResolveNpc(); if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null) && !((Object)(object)((Component)target).transform == (Object)null)) { EnsureAlive(val); Vector3 position = ((Component)target).transform.position; Vector3 forward = ((Component)target).transform.forward; Vector3 right = ((Component)target).transform.right; Vector3 val2 = position + right * HitOffsetFromTarget.x + forward * HitOffsetFromTarget.z; NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(val2 + new Vector3(0f, 1.5f, 0f), ref val3, 5f, -1)) { val2 = ((NavMeshHit)(ref val3)).position; } WarpTo(val, val2); Vector3 val4 = position - val2; val4.y = 0f; if (((Vector3)(ref val4)).sqrMagnitude > 0.01f) { ((Component)val).transform.rotation = Quaternion.LookRotation(val4); } NDLog.Debug($"Lucky teleported near target at ({val2.x:F1},{val2.y:F1},{val2.z:F1})."); } } catch (Exception ex) { NDLog.Warn("LuckyNPC.TeleportNearTarget: " + ex.Message); } } public static void ReturnToHidden() { //IL_002e: 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) try { NPC val = ResolveNpc(); if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { EnsureAlive(val); WarpTo(val, HiddenSpawn); ((Component)val).transform.rotation = Quaternion.identity; NDLog.Debug($"Lucky returned to hidden ({HiddenSpawn.x:F0},{HiddenSpawn.y:F0},{HiddenSpawn.z:F0})."); } } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.ReturnToHidden: " + ex.Message); } } public static void TickWatchdog() { //IL_008b: 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_00be: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority) { return; } NPC val = ResolveNpc(); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } bool isDispatching = LuckyController.IsDispatching; bool flag = false; bool flag2 = false; try { NPCHealth health = val.Health; if ((Object)(object)health != (Object)null) { flag = health.IsDead; flag2 = health.IsKnockedOut; } } catch { } if (flag || flag2) { EnsureAlive(val); WarpTo(val, HiddenSpawn); } else if (!isDispatching && ((Component)val).transform.position.y > -100f) { WarpTo(val, HiddenSpawn); DisableMovementComponentIfParked(val); } } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.TickWatchdog: " + ex.Message); } } public static NPC GetNpc() { return ResolveNpc(); } public static void ResetForDemotion() { Instance = null; CachedGameNpc = null; } public static bool PlaceForCombat(Vector3 pos, Vector3 lookTarget) { //IL_0033: 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) //IL_0048: 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_0071: 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_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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00a0: Unknown result type (might be due to invalid IL or missing references) try { NPC val = ResolveNpc(); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return false; } EnsureAlive(val); NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(pos + new Vector3(0f, 1.5f, 0f), ref val2, 8f, -1)) { pos = ((NavMeshHit)(ref val2)).position; } WarpTo(val, pos); Vector3 val3 = lookTarget - pos; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude > 0.01f) { ((Component)val).transform.rotation = Quaternion.LookRotation(val3); } NDLog.Debug($"Lucky placed for combat at ({pos.x:F1},{pos.y:F1},{pos.z:F1})."); return true; } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.PlaceForCombat: " + ex.Message); return false; } } public static bool WarpNextTo(Vector3 targetPos) { //IL_003d: 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_0057: 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_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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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) //IL_0082: 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_00cf: 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_00e5: 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_00bf: Unknown result type (might be due to invalid IL or missing references) try { NPC val = ResolveNpc(); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return false; } EnsureAlive(val); SetInvincible(val, value: true); Vector3 val2 = targetPos + new Vector3(1.2f, 0f, -1.2f); NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(val2 + Vector3.up * 1f, ref val3, 2f, -1)) { val2 = ((NavMeshHit)(ref val3)).position; } WarpTo(val, val2); Vector3 val4 = targetPos - val2; val4.y = 0f; if (((Vector3)(ref val4)).sqrMagnitude > 0.01f) { ((Component)val).transform.rotation = Quaternion.LookRotation(val4); } NDLog.Debug($"Lucky reach-assist warp to ({val2.x:F1},{val2.y:F1},{val2.z:F1})."); return true; } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.WarpNextTo: " + ex.Message); return false; } } public static void EnableCombatSystems() { try { NPC val = ResolveNpc(); if ((Object)(object)val == (Object)null) { return; } EnsureAlive(val); SetInvincible(val, value: true); SuppressShockBehaviours(val); SetAngryFace(val); NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; } if ((Object)(object)val.Movement != (Object)null) { try { ((Behaviour)val.Movement).enabled = true; } catch { } try { val.Movement.SetAgentEnabled(true); } catch { } try { val.Movement.ResumeMovement(); } catch { } try { val.Movement.MoveSpeedMultiplier = 1f; } catch { } } VisionCone componentInChildren = ((Component)val).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = true; } SetHearing(val, on: false); NDLog.Debug("Lucky combat systems ENABLED (movement/vision on, hearing off, vanilla speed)."); } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.EnableCombatSystems: " + ex.Message); } } public static void DisableCombatSystems() { try { NPC val = ResolveNpc(); if ((Object)(object)val == (Object)null) { return; } SetInvincible(val, value: false); if ((Object)(object)val.Movement != (Object)null) { try { val.Movement.MoveSpeedMultiplier = 1f; } catch { } try { val.Movement.PauseMovement(); } catch { } try { val.Movement.SetAgentEnabled(false); } catch { } DisableMovementComponentIfParked(val); } NavMeshAgent component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } VisionCone componentInChildren = ((Component)val).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } SetHearing(val, on: true); NDLog.Debug("Lucky combat systems DISABLED (parked)."); } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.DisableCombatSystems: " + ex.Message); } } public static void SetMoveTarget(Vector3 pos) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) try { NPC val = ResolveNpc(); if (!((Object)(object)((val != null) ? val.Movement : null) == (Object)null)) { val.Movement.SetDestination(pos); } } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.SetMoveTarget: " + ex.Message); } } private static void SuppressShockBehaviours(NPC npc) { try { NPCBehaviour behaviour = npc.Behaviour; if (!((Object)(object)behaviour == (Object)null)) { TryKillBehaviour((Behaviour)(object)behaviour.CoweringBehaviour); TryKillBehaviour((Behaviour)(object)behaviour.HeavyFlinchBehaviour); TryKillBehaviour((Behaviour)(object)behaviour.FleeBehaviour); } } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.SuppressShockBehaviours: " + ex.Message); } } public static void KeepFearless() { try { NPC val = ResolveNpc(); if (!((Object)(object)val == (Object)null)) { SuppressShockBehaviours(val); SetAngryFace(val); SetInvincible(val, value: true); } } catch { } } private static void SetInvincible(NPC npc, bool value) { try { if ((Object)(object)npc == (Object)null) { return; } NPCHealth health = npc.Health; if ((Object)(object)health == (Object)null) { return; } health.npc.NPCData.Health.Invincible = value; if (!value) { return; } try { health.RestoreHealth(); } catch { } } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.SetInvincible: " + ex.Message); } } private static void DisableMovementComponentIfParked(NPC npc) { try { if (!((Object)(object)((npc != null) ? npc.Movement : null) == (Object)null) && SessionGate.IsAuthority) { ((Behaviour)npc.Movement).enabled = false; } } catch (Exception ex) { NDLog.DebugWarn("DisableMovementComponentIfParked: " + ex.Message); } } private static void SetHearing(NPC npc, bool on) { try { NPCAwareness val = ((npc != null) ? npc.Awareness : null); if (!((Object)(object)val == (Object)null)) { Listener listener = val.Listener; if ((Object)(object)listener != (Object)null) { ((Behaviour)listener).enabled = on; } } } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.SetHearing: " + ex.Message); } } private static void SetAngryFace(NPC npc) { try { AvatarEmotionManager val = npc.Avatar?.EmotionManager; if (!((Object)(object)val == (Object)null)) { AvatarEmotionPreset emotion = val.GetEmotion("Angry"); if (emotion != null) { val.SetEmotion(emotion); } } } catch (Exception ex) { NDLog.DebugWarn("LuckyNPC.SetAngryFace: " + ex.Message); } } private static void TryKillBehaviour(Behaviour b) { if ((Object)(object)b == (Object)null) { return; } try { b.Disable(); } catch { } try { ((Behaviour)b).enabled = false; } catch { } } private static NPC ResolveNpc() { NPC cachedGameNpc = CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).gameObject != (Object)null) { return cachedGameNpc; } try { cachedGameNpc = NPCManager.GetNPC("Ndrangheta_lucky"); } catch { cachedGameNpc = null; } if ((Object)(object)cachedGameNpc != (Object)null) { CachedGameNpc = cachedGameNpc; } return cachedGameNpc; } private static void WarpTo(NPC npc, Vector3 pos) { //IL_0064: 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_0047: Unknown result type (might be due to invalid IL or missing references) try { NavMeshAgent component = ((Component)npc).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { component.Warp(pos); return; } if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.Warp(pos); return; } catch { } } } catch { } ((Component)npc).transform.position = pos; } private static void EnsureAlive(NPC npc) { try { NPCHealth health = npc.Health; if (!((Object)(object)health == (Object)null) && (health.IsDead || health.IsKnockedOut)) { try { health.Revive(); } catch (Exception ex) { NDLog.DebugWarn("Lucky.Revive: " + ex.Message); } try { health.RestoreHealth(); } catch { } NDLog.Debug("Lucky was dead/KO — revived."); } } catch { } } } } namespace Ndrangheta.Helper { public static class BattesimoController { public enum Stage { NotStarted, Awaiting, Bleeding, Completed } private static int _attackDay; private static int _attackTime; private const float HEARTBEAT_INTERVAL = 1f; private static float _hbTimer; private const int JOBS_AT_SOTTOCAPO_BEFORE_BATTESIMO = 2; private const int REMIND_EVERY_DAYS = 5; private static int _lastRemindDay = -1; private const float ATTACK_DETECT_WINDOW_HOURS = 2f; public static Stage CurrentStage { get; private set; } = Stage.NotStarted; public static int SaveStage => (int)CurrentStage; public static int SaveAttackDay => _attackDay; public static int SaveAttackTime => _attackTime; public static void ResetForSceneReload() { _hbTimer = 0f; } public static void LoadStage(int stage, int attackDay, int attackTime) { CurrentStage = (Stage)stage; _attackDay = attackDay; _attackTime = attackTime; try { if (CurrentStage == Stage.Awaiting || CurrentStage == Stage.Bleeding) { BattesimoQuest.EnsureCreated(); BattesimoQuest.EnsureFirstEntryActive(); if (CurrentStage == Stage.Bleeding) { BattesimoQuest.OnAttackDetected(); } } } catch (Exception ex) { NDLog.DebugWarn("BattesimoController.LoadStage quest restore: " + ex.Message); } } public static void Tick(float deltaTime) { if (RankManager.CurrentRank < Rank.Sottocapo) { return; } int num = RankTable.For(Rank.Sottocapo).CompletedThreshold + 2; if (PizzoJobManager.CompletedCount < num || CurrentStage == Stage.Completed) { return; } _hbTimer -= deltaTime; if (_hbTimer > 0f) { return; } _hbTimer = 1f; try { switch (CurrentStage) { case Stage.NotStarted: Step_AnnounceBattesimo(); break; case Stage.Awaiting: Step_WatchForAttack(); break; case Stage.Bleeding: Step_WaitForSurvival(); break; } } catch (Exception ex) { NDLog.DebugWarn("BattesimoController.Tick: " + ex.Message); } } private static void Step_AnnounceBattesimo() { DonMessaging.SendDon("Capodecina, listen — there's one more thing. Il battesimo before you walk among uomini d'onore for real. Check your journal — instructions are there. Hit a cop, walk away clean."); BattesimoQuest.EnsureCreated(); BattesimoQuest.EnsureFirstEntryActive(); CurrentStage = Stage.Awaiting; NdranghetaSaveData.Instance?.PushNow(); NDLog.Info("Battesimo announced — quest created, awaiting cop attack."); } public static void NotifyAttack(string source) { try { if (CurrentStage == Stage.Awaiting) { TimeManager instance = NetworkSingleton.Instance; if (!((Object)(object)instance == (Object)null)) { _attackDay = instance.ElapsedDays; _attackTime = instance.CurrentTime; CurrentStage = Stage.Bleeding; BattesimoQuest.OnAttackDetected(); NdranghetaSaveData.Instance?.PushNow(); NDLog.Info($"Battesimo: cop attack registered ({source}, day={_attackDay} time={_attackTime}). Survival timer started."); DonMessaging.SendDon("Heard you swung. Stay alive an hour, stay out of the cuffs, and you're in for real."); } } } catch (Exception ex) { NDLog.DebugWarn("BattesimoController.NotifyAttack: " + ex.Message); } } private static void Step_WatchForAttack() { try { List officers = PoliceOfficer.Officers; if (officers != null) { for (int i = 0; i < officers.Count; i++) { PoliceOfficer val; try { val = officers[i]; } catch { continue; } if ((Object)(object)val == (Object)null) { continue; } float num; try { num = (((Object)(object)((NPC)val).Health != (Object)null) ? ((float)((NPC)val).Health.HoursSinceAttackedByPlayer) : (-1f)); } catch { continue; } if (num >= 0f && num < 2f) { NotifyAttack("host scan"); if (CurrentStage == Stage.Bleeding) { return; } } } } TimeManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null) { int elapsedDays = instance.ElapsedDays; if (_lastRemindDay < 0) { _lastRemindDay = elapsedDays; } if (elapsedDays - _lastRemindDay >= 5) { _lastRemindDay = elapsedDays; DonMessaging.SendDon("Still waiting for the battesimo. Hit a cop, walk away, stay clean for an hour. Until then no real work."); NDLog.Debug("Battesimo: re-announce reminder sent."); } } } catch (Exception ex) { NDLog.DebugWarn("Step_WatchForAttack: " + ex.Message); } } private static void Step_WaitForSurvival() { try { TimeManager instance = NetworkSingleton.Instance; if (!((Object)(object)instance == (Object)null)) { int elapsedDays = instance.ElapsedDays; int currentTime = instance.CurrentTime; bool flag = false; if (elapsedDays > _attackDay) { flag = true; } else if (elapsedDays == _attackDay && currentTime - _attackTime >= 100) { flag = true; } if (flag) { CurrentStage = Stage.Completed; BattesimoQuest.OnSurvived(); NdranghetaSaveData.Instance?.PushNow(); NDLog.Info("Battesimo completed."); DonMessaging.SendDon("You bled and stayed standing. The 'Ndrina is yours now, uomo d'onore. Next time I text, it won't be pizzo runs. Get ready for il contratto."); } } } catch (Exception ex) { NDLog.DebugWarn("Step_WaitForSurvival: " + ex.Message); } } } internal static class BossMarkerSync { public static string Label { get; private set; } = ""; public static Vector3 Pos { get; private set; } = Vector3.zero; public static int Kind { get; private set; } public static int RaidSeconds { get; private set; } public static bool Active => !string.IsNullOrEmpty(Label); public static void SetRaidSeconds(int s) { RaidSeconds = ((s >= 0) ? s : 0); } public static void Set(string label, Vector3 worldPos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Set(label, worldPos, 0); } public static void Set(string label, Vector3 worldPos, int kind) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Label = label ?? ""; Pos = worldPos; Kind = kind; } public static void SetLabel(string label) { Label = label ?? ""; } public static void SetPos(Vector3 worldPos) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (Active) { Pos = worldPos; } } public static void Clear() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) Label = ""; Pos = Vector3.zero; Kind = 0; RaidSeconds = 0; } } [HarmonyPatch(typeof(BuildUpdate_Grid), "Place")] internal static class BuildGridPlaceGuard { private static int _logBudget = 5; [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { if (__exception == null) { return null; } string text = null; try { text = __exception.Message; } catch { } if (!(__exception is ArgumentOutOfRangeException) && !(__exception is IndexOutOfRangeException) && (text == null || text.IndexOf("out of range", StringComparison.OrdinalIgnoreCase) < 0)) { return __exception; } if (_logBudget > 0) { _logBudget--; NDLog.DebugWarn("BuildUpdate_Grid.Place index-out-of-range geschluckt (FIX-091 Deposito-Grid — echte Korrektur gehoert in LagerGrid)."); } return null; } } internal static class CarBombManager { private enum State { Idle, Placing, Armed } private const float FUSE_SECONDS = 45f; private const float BOMB_RADIUS = 9f; private const float BOMB_DAMAGE = 450f; private const float BOMB_PUSH = 1200f; private const float AIM_RANGE = 8f; private const float PLACE_TIMEOUT = 90f; private const string BOMB_ITEM_ID = "bomb"; private const int KILL_BONUS = 2500; private const float CAR_MAX_BOUNDS = 14f; private static readonly string[] DECO_CAR_NAMES = new string[5] { "Shitbox", "Bruiser", "Veeper", "Cheetah", "Hotbox" }; private static readonly Color GHOST_GREEN = new Color(0.15f, 0.95f, 0.2f); private static readonly Color GHOST_RED = new Color(0.95f, 0.12f, 0.1f); private static State _state = State.Idle; private static GameObject _ghost; private static bool _ghostValid; private static bool? _ghostTintValid; private static bool _ghostIsPrimitive; private static LandVehicle _aimCar; private static GameObject _aimDeco; private static Vector3 _placeLocalPos; private static Quaternion _placeLocalRot; private static float _placeTimer; private static bool _aimLastGot; private static int _decoCacheColId; private static GameObject _decoCacheRoot; private static bool _decoCacheNeg; private static float _decoResolveAt; private const float DECO_RESOLVE_INTERVAL = 0.12f; private static LandVehicle _targetCar; private static string _targetCarGuid; private static GameObject _targetDeco; private static GameObject _bombProp; private static AudioSourceController _bombAudio; private static float _armedUntil; private static float _timeSinceBeep; private static bool _blinkOn; public static void ResetForSceneReload() { try { AbortQuiet(); } catch { } } public static void BeginPlacementFromChat() { try { if (TerritoryHandover.IsBossForLocalPeer) { if (_state == State.Armed) { DonMessaging.SendDon("One's already ticking, boss."); return; } if (_state == State.Placing) { DonMessaging.SendDon("Already wiring one up — close your phone and aim at a car."); return; } if (!HasBombItem()) { DonMessaging.SendDon("You need a bomb in your pocket for this one, boss."); return; } BuildGhost(); _aimCar = null; _aimDeco = null; _ghostValid = false; _placeTimer = 0f; _aimLastGot = false; _state = State.Placing; DonMessaging.SendDon("Close your phone, aim at a car and LEFT-CLICK to plant the bomb. Press R to cancel."); NDLog.Debug("[CARBOMB] placement mode ON."); } } catch (Exception ex) { NDLog.Warn("CarBomb.Begin: " + ex.Message); AbortQuiet(); } } public static void Tick(float dt) { switch (_state) { case State.Placing: TickPlacing(dt); break; case State.Armed: TickArmed(dt); break; } } private static void TickPlacing(float dt) { if (PlayerArrested()) { DonMessaging.SendDon("Cops are on you, boss — pull back."); AbortQuiet(); RefreshChat(); return; } PlayerCamera instance = PlayerSingleton.Instance; bool flag = true; try { flag = (Object)(object)instance == (Object)null || instance.ActiveUIElementCount != 0 || GameInput.IsTyping; } catch { } if ((Object)(object)instance == (Object)null || flag) { if ((Object)(object)_ghost != (Object)null) { _ghost.SetActive(false); } return; } UpdateAim(instance); try { if (GameInput.GetButtonDown((ButtonCode)14)) { DonMessaging.SendDon("Pulled it back, boss."); AbortQuiet(); RefreshChat(); return; } } catch { } bool flag2 = false; try { flag2 = GameInput.GetButtonDown((ButtonCode)0); } catch { } if (flag2 && _ghostValid && ((Object)(object)_aimCar != (Object)null || (Object)(object)_aimDeco != (Object)null)) { Place(); } } private static void UpdateAim(PlayerCamera cam) { //IL_0019: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: 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) //IL_0197: 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_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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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_01e0: 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_01f4: 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) _ghostValid = false; _aimCar = null; _aimDeco = null; LandVehicle val = null; GameObject val2 = null; RaycastHit val3 = default(RaycastHit); bool flag = false; try { Transform transform = ((Component)cam).transform; if (Physics.Raycast(transform.position, transform.forward, ref val3, 8f, -5, (QueryTriggerInteraction)1) && (Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) { val = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent(); if ((Object)(object)val != (Object)null) { flag = true; } else { val2 = ResolveDecoCached(((RaycastHit)(ref val3)).collider); if ((Object)(object)val2 != (Object)null) { flag = true; } } } } catch { } if (flag != _aimLastGot) { _aimLastGot = flag; string text = "none"; try { if ((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) { text = ((Object)((RaycastHit)(ref val3)).collider).name; } } catch { } NDLog.Debug($"[CARBOMB][aim] got={flag} car={(Object)(object)val != (Object)null} deco={(Object)(object)val2 != (Object)null} hit={text}"); } if (flag) { _aimCar = val; _aimDeco = val2; _ghostValid = true; Transform val4 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : val2.transform); if ((Object)(object)_ghost != (Object)null) { _ghost.SetActive(true); _ghost.transform.position = ((RaycastHit)(ref val3)).point; _ghost.transform.rotation = Quaternion.FromToRotation(Vector3.up, ((RaycastHit)(ref val3)).normal); TintGhost(valid: true); try { _placeLocalPos = val4.InverseTransformPoint(((RaycastHit)(ref val3)).point); _placeLocalRot = Quaternion.Inverse(val4.rotation) * _ghost.transform.rotation; } catch { } } } else if ((Object)(object)_ghost != (Object)null) { try { Transform transform2 = ((Component)cam).transform; _ghost.SetActive(true); _ghost.transform.position = transform2.position + transform2.forward * 1.5f; _ghost.transform.rotation = Quaternion.identity; TintGhost(valid: false); } catch { } } } private static void Place() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) try { if (!ConsumeBombItem()) { DonMessaging.SendDon("Lost the bomb somewhere, boss — check your pockets."); AbortQuiet(); RefreshChat(); return; } LandVehicle aimCar = _aimCar; GameObject aimDeco = _aimDeco; DestroyGhost(); Transform parent = (((Object)(object)aimCar != (Object)null) ? ((Component)aimCar).transform : (((Object)(object)aimDeco != (Object)null) ? aimDeco.transform : null)); SpawnBombProp(parent, _placeLocalPos, _placeLocalRot); _targetCar = aimCar; _targetCarGuid = (((Object)(object)aimCar != (Object)null) ? ResolveGuid(aimCar) : null); _targetDeco = aimDeco; _armedUntil = Time.time + 45f; _timeSinceBeep = 1000f; _state = State.Armed; DonMessaging.SendDon("Bomb's on the car, boss. 45 seconds — walk away."); NDLog.Debug($"[CARBOMB] armed (car GUID={_targetCarGuid}, deco={(Object)(object)_targetDeco != (Object)null})."); RefreshChat(); } catch (Exception ex) { NDLog.Warn("CarBomb.Place: " + ex.Message); AbortQuiet(); } } private static GameObject ResolveDecoCached(Collider col) { int num = 0; try { num = (((Object)(object)col != (Object)null) ? ((Object)col).GetInstanceID() : 0); } catch { } if (num != 0 && num == _decoCacheColId) { if (_decoCacheNeg) { return null; } if ((Object)(object)_decoCacheRoot != (Object)null) { return _decoCacheRoot; } } if (Time.time < _decoResolveAt) { return _decoCacheNeg ? null : _decoCacheRoot; } _decoResolveAt = Time.time + 0.12f; GameObject val = FindDecoCarRoot(col); _decoCacheColId = num; _decoCacheRoot = val; _decoCacheNeg = (Object)(object)val == (Object)null; return val; } private static void ClearDecoCache() { _decoCacheColId = 0; _decoCacheRoot = null; _decoCacheNeg = false; } private static bool PlayerArrested() { try { Player local = Player.Local; return (Object)(object)local != (Object)null && local.IsArrested; } catch { return false; } } private static GameObject FindDecoCarRoot(Collider col) { try { if ((Object)(object)col == (Object)null) { return null; } if ((Object)(object)((Component)col).GetComponentInParent() != (Object)null) { return null; } if ((Object)(object)((Component)col).GetComponentInParent() != (Object)null) { return null; } if ((Object)(object)((Component)col).GetComponentInParent() != (Object)null) { return null; } Transform val = ((Component)col).transform; GameObject val2 = null; for (int i = 0; i < 4; i++) { if (!((Object)(object)val != (Object)null)) { break; } if (QualifiesAsDecoCar(((Component)val).gameObject)) { val2 = ((Component)val).gameObject; } else if ((Object)(object)val2 != (Object)null) { break; } val = val.parent; } return val2; } catch { return null; } } private static bool QualifiesAsDecoCar(GameObject go) { //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)go == (Object)null) { return false; } bool flag = false; Collider[] componentsInChildren = go.GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { string text = ((Object)((Component)val).gameObject).name ?? ""; if (text.IndexOf("Collider_Body", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Trunk", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } } bool flag2 = false; if (!flag) { string text2 = ((Object)go).name ?? ""; for (int j = 0; j < DECO_CAR_NAMES.Length; j++) { if (text2.IndexOf(DECO_CAR_NAMES[j], StringComparison.OrdinalIgnoreCase) >= 0) { flag2 = true; break; } } } if (!flag && !flag2) { return false; } MeshRenderer[] componentsInChildren2 = go.GetComponentsInChildren(true); if (componentsInChildren2 == null || componentsInChildren2.Length == 0) { return false; } Bounds bounds = ((Renderer)componentsInChildren2[0]).bounds; for (int k = 1; k < componentsInChildren2.Length; k++) { ((Bounds)(ref bounds)).Encapsulate(((Renderer)componentsInChildren2[k]).bounds); } Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).magnitude > 14f) { return false; } return true; } catch { return false; } } private static void TickArmed(float dt) { if (!CarAlive()) { DonMessaging.SendDon("The car drove off and we lost it, boss — no boom."); DestroyBombProp(); _targetCar = null; _targetCarGuid = null; _state = State.Idle; return; } float num = _armedUntil - Time.time; float num2 = Mathf.Clamp(45f - num, 0f, 45f); _timeSinceBeep += dt; float num3 = Mathf.Lerp(1f, 0.125f, num2 / 45f); if (_timeSinceBeep >= num3) { _timeSinceBeep = 0f; Beep(); } if (num <= 0f) { Detonate(); } } private static void Detonate() { //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_033c: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0279: 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_0209: Unknown result type (might be due to invalid IL or missing references) Vector3 val = CarPos(); List list = SnapshotVictims(val, 12f); DestroyBombProp(); try { if ((Object)(object)_targetDeco != (Object)null) { Object.Destroy((Object)(object)_targetDeco); } else if (SessionGate.IsAuthority) { LandVehicle val2 = ResolveCar(); if ((Object)(object)val2 != (Object)null) { try { if (val2.IsOccupied) { val2.ExitVehicle(); } } catch { } try { val2.DestroyVehicle(); } catch { } } } else if (!string.IsNullOrEmpty(_targetCarGuid)) { try { ClientActionNet.SendAction("carbombkill", _targetCarGuid); NDLog.Debug("[CARBOMB] client relayed car despawn (GUID=" + _targetCarGuid + ") to host."); } catch { } } } catch { } _targetCar = null; _targetCarGuid = null; _targetDeco = null; try { ExplosionData val3 = new ExplosionData { DamageRadius = 9f, MaxDamage = 450f, PushForceRadius = 18f, MaxPushForce = 1200f, CheckLoS = false, ExplosionType = (EExplosionType)0 }; CombatManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null) { instance.CreateExplosion(val, val3); } } catch (Exception ex) { NDLog.Warn("[CARBOMB] CreateExplosion: " + ex.Message); } try { if (SessionGate.IsAuthority && list != null) { int num = 0; for (int i = 0; i < list.Count; i++) { NPC val4 = list[i]; if ((Object)(object)val4 == (Object)null || (Object)(object)((Component)val4).transform == (Object)null) { continue; } NPCHealth health = val4.Health; if ((Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut) { continue; } float num2 = Vector3.Distance(((Component)val4).transform.position, val); if (!(num2 > 9f)) { float num3 = Mathf.Lerp(450f, 0f, Mathf.Clamp01(num2 / 9f)); try { health.TakeDamage(num3, true); num++; } catch { } } } NDLog.Debug($"[CARBOMB] direct-damage pass @ {val} r={9f}: {num} npc(s) hit."); } } catch (Exception ex2) { NDLog.DebugWarn("[CARBOMB] direct-damage: " + ex2.Message); } try { PlayerSingleton.Instance.StartCameraShake(3f, 1.6f, true); } catch { } try { MelonCoroutines.Start(AwardKillBonus(list)); } catch { } try { Sfx.PlayOneShot("quest-effect", 0.8f); } catch { } try { DonMessaging.SendDon("Boom. That car's scrap metal, boss."); } catch { } try { LuckyChatController.RefreshIfHandoverActive(); } catch { } _state = State.Idle; NDLog.Info($"[CARBOMB] detonated @ {val} (r={9f}, dmg={450f})."); } private static void BuildGhost() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) DestroyGhost(); ClearDecoCache(); _ghost = CloneBombModel("Ndrangheta_CarBombGhost"); _ghostIsPrimitive = false; if ((Object)(object)_ghost == (Object)null) { _ghost = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)_ghost).name = "Ndrangheta_CarBombGhost"; _ghost.transform.localScale = new Vector3(0.3f, 0.5f, 0.3f); _ghostIsPrimitive = true; } StripCollidersAndBodies(_ghost); _ghostTintValid = null; TintGhost(valid: false); } private static void TintGhost(bool valid) { //IL_0074: 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_0058: 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) if ((Object)(object)_ghost == (Object)null || (_ghostTintValid.HasValue && _ghostTintValid.Value == valid)) { return; } _ghostTintValid = valid; try { if (_ghostIsPrimitive) { PropVisuals.Apply(_ghost, valid ? GHOST_GREEN : GHOST_RED); } else { PropVisuals.ApplyGlass(_ghost, valid ? GHOST_GREEN : GHOST_RED, 0.4f); } } catch { } } private static void DestroyGhost() { try { if ((Object)(object)_ghost != (Object)null) { Object.Destroy((Object)(object)_ghost); } } catch { } _ghost = null; _ghostTintValid = null; } private static void SpawnBombProp(Transform parent, Vector3 localPos, Quaternion localRot) { //IL_0046: 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_009a: 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_013b: Unknown result type (might be due to invalid IL or missing references) _bombAudio = null; GameObject val = CloneBombModel("Ndrangheta_CarBomb"); if ((Object)(object)val == (Object)null) { val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Ndrangheta_CarBomb"; val.transform.localScale = new Vector3(0.3f, 0.5f, 0.3f); PropVisuals.Apply(val, new Color(0.08f, 0.08f, 0.09f)); } _bombProp = val; StripCollidersAndBodies(val); try { if ((Object)(object)parent != (Object)null) { val.transform.SetParent(parent, false); } val.transform.localPosition = localPos; val.transform.localRotation = localRot; } catch { } try { _bombAudio = val.GetComponentInChildren(true); } catch { } if (!((Object)(object)_bombAudio == (Object)null)) { return; } try { BombPlantLocation val2 = Object.FindObjectOfType(true); AudioSourceController val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentInChildren(true) : null); if ((Object)(object)val3 != (Object)null && (Object)(object)((Component)val3).gameObject != (Object)null) { GameObject val4 = Object.Instantiate(((Component)val3).gameObject, val.transform); val4.transform.localPosition = Vector3.zero; val4.SetActive(true); _bombAudio = val4.GetComponent(); } } catch { } } private static GameObject CloneBombModel(string name) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) try { BombPlantLocation val = Object.FindObjectOfType(true); GameObject val2 = null; try { val2 = (((Object)(object)val != (Object)null) ? val.BombModel : null); } catch { } if ((Object)(object)val2 != (Object)null) { GameObject val3 = Object.Instantiate(val2, Vector3.zero, Quaternion.identity); ((Object)val3).name = name; val3.SetActive(true); return val3; } } catch (Exception ex) { NDLog.DebugWarn("[CARBOMB] CloneBombModel: " + ex.Message); } return null; } private static void StripCollidersAndBodies(GameObject go) { try { Collider[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { try { Object.Destroy((Object)(object)componentsInChildren[i]); } catch { } } Rigidbody[] componentsInChildren2 = go.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { try { Object.Destroy((Object)(object)componentsInChildren2[j]); } catch { } } } catch { } } private static void Beep() { //IL_00b3: 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) bool flag = false; try { if ((Object)(object)_bombAudio != (Object)null) { _bombAudio.Play(); flag = true; } } catch { } if (flag) { return; } _blinkOn = !_blinkOn; try { if ((Object)(object)_bombProp != (Object)null) { Renderer component = _bombProp.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.material != (Object)null) { component.material.color = (_blinkOn ? new Color(0.9f, 0.05f, 0.05f) : new Color(0.08f, 0.08f, 0.09f)); } } } catch { } } private static void DestroyBombProp() { try { if ((Object)(object)_bombProp != (Object)null) { Object.Destroy((Object)(object)_bombProp); } } catch { } _bombProp = null; } private static bool CarAlive() { try { if ((Object)(object)_targetDeco != (Object)null) { return true; } if ((Object)(object)_targetCar == (Object)null || (Object)(object)((Component)_targetCar).gameObject == (Object)null) { _targetCar = ResolveCarByGuid(_targetCarGuid); } return (Object)(object)_targetCar != (Object)null && (Object)(object)((Component)_targetCar).gameObject != (Object)null; } catch { return false; } } private static LandVehicle ResolveCar() { try { if ((Object)(object)_targetCar != (Object)null && (Object)(object)((Component)_targetCar).gameObject != (Object)null) { return _targetCar; } } catch { } return ResolveCarByGuid(_targetCarGuid); } private static Vector3 CarPos() { //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) //IL_001b: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_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) try { if ((Object)(object)_targetDeco != (Object)null) { return _targetDeco.transform.position; } } catch { } try { LandVehicle val = ResolveCar(); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform != (Object)null) { return ((Component)val).transform.position; } } catch { } try { if ((Object)(object)_bombProp != (Object)null) { return _bombProp.transform.position; } } catch { } return Vector3.zero; } private static string ResolveGuid(LandVehicle car) { try { if ((Object)(object)car != (Object)null) { return car.GUID.ToString(); } } catch { } return null; } private static LandVehicle ResolveCarByGuid(string guid) { try { if (string.IsNullOrEmpty(guid)) { return null; } List list = NetworkSingleton.Instance?.AllVehicles; if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { LandVehicle val = list[i]; if (!((Object)(object)val == (Object)null)) { string text = null; try { text = val.GUID.ToString(); } catch { } if (text != null && text == guid) { return val; } } } } catch { } return null; } public static void HostKillCar(string guid) { try { if (!SessionGate.IsAuthority || string.IsNullOrEmpty(guid)) { return; } LandVehicle val = ResolveCarByGuid(guid); if ((Object)(object)val != (Object)null) { try { if (val.IsOccupied) { val.ExitVehicle(); } } catch { } try { val.DestroyVehicle(); } catch { } NDLog.Debug("[CARBOMB] host despawned client-bombed car (GUID=" + guid + ")."); } else { NDLog.DebugWarn("[CARBOMB] host could not resolve client-bombed car (GUID=" + guid + ")."); } } catch (Exception ex) { NDLog.DebugWarn("[CARBOMB] HostKillCar: " + ex.Message); } } private static bool HasBombItem() { try { PlayerInventory instance = PlayerSingleton.Instance; return (Object)(object)instance != (Object)null && instance.GetAmountOfItem("bomb") != 0; } catch { return false; } } private static bool ConsumeBombItem() { try { PlayerInventory instance = PlayerSingleton.Instance; if ((Object)(object)instance == (Object)null || instance.GetAmountOfItem("bomb") == 0) { return false; } instance.RemoveAmountOfItem("bomb", 1u); return true; } catch { return false; } } private static void RefreshChat() { try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static List SnapshotVictims(Vector3 center, float radius) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) List list = new List(); try { NPC[] array = Object.FindObjectsOfType(); if (array != null) { foreach (NPC val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null) && !(Vector3.Distance(((Component)val).transform.position, center) > radius)) { bool flag; try { NPCHealth health = val.Health; flag = (Object)(object)health == (Object)null || (!health.IsDead && !health.IsKnockedOut); } catch { flag = false; } if (flag) { list.Add(val); } } } } } catch (Exception ex) { NDLog.DebugWarn("[CARBOMB] SnapshotVictims: " + ex.Message); } return list; } private static IEnumerator AwardKillBonus(List victims) { yield return (object)new WaitForSeconds(0.6f); int kills = 0; try { for (int i = 0; i < victims.Count; i++) { NPC n = victims[i]; if (!((Object)(object)n == (Object)null)) { NPCHealth hp = n.Health; if ((Object)(object)hp != (Object)null && (hp.IsDead || hp.IsKnockedOut)) { kills++; } } } } catch { } if (kills > 0) { try { PayoutHelper.AddCash(kills * 2500, "Car Bomb kills"); } catch { } try { DonMessaging.SendDon((kills == 1) ? "Caught one in the blast, boss — little extra in your pocket." : $"Took {kills} out with that one, boss — nice bonus."); } catch { } } } internal static void SweepStaleMarker() { try { if (CarBombMarkerQuest.Instance != null) { CarBombMarkerQuest.CompleteAndClear(); } } catch { } } private static void AbortQuiet() { DestroyGhost(); DestroyBombProp(); ClearDecoCache(); _aimCar = null; _aimDeco = null; _ghostValid = false; _targetCar = null; _targetCarGuid = null; _targetDeco = null; try { if (CarBombMarkerQuest.Instance != null) { CarBombMarkerQuest.CompleteAndClear(); } } catch { } _state = State.Idle; } } public static class CaricoJobPicker { public sealed class Pick { public string ItemId; public string DisplayName; public int Quantity; public int BonusBricks; public int CashReward; public bool HeavenlyQuality; public string BonusItemId; public string BonusDisplayName; } public static Pick PickForRank(Rank rank, Random rng) { List list = new List(); foreach (ItemCatalog.Entry item in ItemCatalog.GetResolvableSmuggleRotation(rank)) { list.Add(item); } if (list.Count == 0) { return null; } ItemCatalog.Entry entry = list[rng.Next(list.Count)]; Pick pick = new Pick { ItemId = entry.Id, DisplayName = entry.DisplayName, Quantity = QuantityFor(rank), BonusBricks = BonusFor(rank), CashReward = CashRewardFor(rank), HeavenlyQuality = (rank == Rank.Capodecina || rank == Rank.Sottocapo) }; if (rank == Rank.Sottocapo) { pick.BonusItemId = "cocaine"; pick.BonusDisplayName = "Cocaine"; } return pick; } public static int QuantityFor(Rank rank) { return rank switch { Rank.Soldato => 4, Rank.Capodecina => 5, Rank.Sottocapo => 5, _ => 0, }; } public static int BonusFor(Rank rank) { return rank switch { Rank.Soldato => 1, Rank.Capodecina => 2, Rank.Sottocapo => 3, _ => 0, }; } public static int CashRewardFor(Rank rank) { return rank switch { Rank.Soldato => 2000, Rank.Capodecina => 3500, Rank.Sottocapo => 5500, _ => 0, }; } public static bool IsUnlocked(Rank rank) { return QuantityFor(rank) > 0; } } public static class ConsentController { public enum State { Unasked, Active, Paused } private static bool _questionPending; public const string YesText = "Yes, more contracts."; public const string NoText = "Not for me. Ask later."; private const int RepeatAskDays = 3; private const float HEARTBEAT_INTERVAL = 2f; private static float _hbTimer; public static State CurrentState { get; private set; } = State.Unasked; public static int LastAskDay { get; private set; } = -1; public static bool QuestionPending => _questionPending; public static bool ContrattoUnlocked => CurrentState == State.Active; public static void ResetForSceneReload() { _hbTimer = 0f; _questionPending = false; } public static void LoadState(int state, int lastAskDay) { CurrentState = (State)state; LastAskDay = lastAskDay; } public static void ApplyClientAnswer(bool yes) { try { if (SessionGate.IsAuthority && _questionPending) { if (yes) { OnYes(); } else { OnNo(); } try { DonMessaging.RemoveYesNoButtons("Yes, more contracts.", "Not for me. Ask later."); } catch { } NDLog.Info("Consent answered by client: " + (yes ? "Yes" : "No") + "."); } } catch (Exception ex) { NDLog.DebugWarn("ConsentController.ApplyClientAnswer: " + ex.Message); } } public static void OnContrattoCompleted() { if (CurrentState == State.Unasked) { AskQuestion("You handled that clean. Are you the type for this kind of work?"); } } public static void Tick(float deltaTime) { if (CurrentState != State.Paused) { return; } _hbTimer -= deltaTime; if (_hbTimer > 0f) { return; } _hbTimer = 2f; try { TimeManager instance = NetworkSingleton.Instance; if (!((Object)(object)instance == (Object)null)) { int elapsedDays = instance.ElapsedDays; if (LastAskDay >= 0 && elapsedDays - LastAskDay >= 3 && !_questionPending) { AskQuestion("Thought about it more? Still need a hand on contracts."); } } } catch (Exception ex) { NDLog.DebugWarn("ConsentController.Tick: " + ex.Message); } } private static void AskQuestion(string smsText) { DonMessaging.SendDon(smsText); DonMessaging.RegisterYesNoButtons("Yes, more contracts.", OnYes, "Not for me. Ask later.", OnNo); _questionPending = true; try { TimeManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null) { LastAskDay = instance.ElapsedDays; } } catch { } NdranghetaSaveData.Instance?.PushNow(); } private static void OnYes() { CurrentState = State.Active; _questionPending = false; DonMessaging.SendDon("Bene. Contratti will come like the rest of the jobs from now on. When you see the name, you finish it."); NdranghetaSaveData.Instance?.PushNow(); NDLog.Info("Consent: Active — Contratto pool enabled."); } private static void OnNo() { CurrentState = State.Paused; _questionPending = false; DonMessaging.SendDon("Capito. Not for now. I'll ask again in a few days."); NdranghetaSaveData.Instance?.PushNow(); NDLog.Debug("Consent: Paused."); } } [HarmonyPatch] internal static class ContactsVanillaOnClientPatch { private static MethodBase TargetMethod() { try { Type type = AccessTools.TypeByName("S1API.Internal.Patches.ContactsAppPatches"); return (type == null) ? null : AccessTools.Method(type, "HasCustomNpcTypes", (Type[])null, (Type[])null); } catch { return null; } } private static bool Prepare() { return TargetMethod() != null; } private static void Postfix(ref bool __result) { try { if (!SessionGate.IsAuthority) { __result = false; } } catch { } } } public sealed class ContrabandJob { public enum JobKind { Pizzo, Trasporto, Carico, Contratto } public enum SourceType { DeadDropPickup, PlayerProvides, NpcRob, StationSteal } public enum PayloadType { Cash, Item } public enum DeliveryType { DonOnly, DeadDropDrop, ContrattoKill } public enum RewardKind { KeepEnvelopeMinusCut, FamigliaCash, FamigliaCashPlusItem, ContractCashInStash } public JobKind Kind; public string LoreTag; public bool IsCurfew; public SourceType Source; public PayloadType Payload; public string ItemId; public string ItemDisplayName; public int CashAmount; public int Quantity; public string SourceDropName; public Vector3 SourceDropPos; public string SourceDropGuid; public DeliveryType Delivery; public string DeliveryDropName; public Vector3 DeliveryDropPos; public string DeliveryDropGuid; public int DeliveryCashAmount; public int DeliveryItemQuantity; public bool RequiresDonReturn = true; public int DonCutDeduct; public RewardKind Reward; public int RewardCash; public string RewardItemId; public int RewardItemQuantity; public string RewardDropGuid; public TimeSpan? Deadline; public string ContrattoTargetName; public string ContrattoTargetCategory; public static ContrabandJob Pizzo(string targetName, string dropName, Vector3 dropPos, string dropGuid, int envelope, int cut, bool curfew) { //IL_003e: 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) return new ContrabandJob { Kind = JobKind.Pizzo, LoreTag = "pizzo", IsCurfew = curfew, Source = SourceType.DeadDropPickup, Payload = PayloadType.Cash, CashAmount = envelope, SourceDropName = dropName, SourceDropPos = dropPos, SourceDropGuid = dropGuid, Delivery = DeliveryType.DonOnly, RequiresDonReturn = true, DonCutDeduct = cut, Reward = RewardKind.KeepEnvelopeMinusCut, ContrattoTargetName = targetName }; } public static ContrabandJob Trasporto(string aName, Vector3 aPos, string aGuid, string bName, Vector3 bPos, string bGuid, int envelope, int cut, int reward, bool curfew) { //IL_0049: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) return new ContrabandJob { Kind = JobKind.Trasporto, LoreTag = (curfew ? "trasporto_curfew" : "trasporto"), IsCurfew = curfew, Source = SourceType.DeadDropPickup, Payload = PayloadType.Cash, CashAmount = envelope, SourceDropName = aName, SourceDropPos = aPos, SourceDropGuid = aGuid, Delivery = DeliveryType.DeadDropDrop, DeliveryDropName = bName, DeliveryDropPos = bPos, DeliveryDropGuid = bGuid, DeliveryCashAmount = envelope - cut, RequiresDonReturn = true, DonCutDeduct = cut, Reward = RewardKind.FamigliaCash, RewardCash = reward }; } public static ContrabandJob Carico(string itemId, string itemDisplayName, int quantity, string aName, Vector3 aPos, string aGuid, string bName, Vector3 bPos, string bGuid, int rewardCash, int bonusBricks, string gazeboDropGuid) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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) return new ContrabandJob { Kind = JobKind.Carico, LoreTag = "carico_" + (itemId ?? "unknown"), Source = SourceType.DeadDropPickup, Payload = PayloadType.Item, ItemId = itemId, ItemDisplayName = itemDisplayName, Quantity = quantity, SourceDropName = aName, SourceDropPos = aPos, SourceDropGuid = aGuid, Delivery = DeliveryType.DeadDropDrop, DeliveryDropName = bName, DeliveryDropPos = bPos, DeliveryDropGuid = bGuid, DeliveryItemQuantity = quantity, RequiresDonReturn = true, DonCutDeduct = 0, Reward = RewardKind.FamigliaCashPlusItem, RewardCash = rewardCash, RewardItemId = itemId, RewardItemQuantity = bonusBricks, RewardDropGuid = gazeboDropGuid }; } public static ContrabandJob Contratto(string targetName, string targetCategory, int rewardCash, string gazeboDropGuid) { return new ContrabandJob { Kind = JobKind.Contratto, LoreTag = "contratto", Source = SourceType.PlayerProvides, Payload = PayloadType.Item, ItemId = "revolver", Quantity = 1, Delivery = DeliveryType.ContrattoKill, RequiresDonReturn = true, Reward = RewardKind.ContractCashInStash, RewardCash = rewardCash, RewardDropGuid = gazeboDropGuid, ContrattoTargetName = targetName, ContrattoTargetCategory = targetCategory }; } } public static class ContrattoTargetPicker { public sealed class Choice { public NPC Npc; public string DisplayName; public string Category; } public static Choice PickRandom(Random rng) { List list = new List(); try { List officers = PoliceOfficer.Officers; if (officers != null) { for (int i = 0; i < officers.Count; i++) { PoliceOfficer val = officers[i]; if (!((Object)(object)val == (Object)null)) { NPC val2 = GameCompat.Cast((Object)(object)val); if (!((Object)(object)val2 == (Object)null) && !KillDetector.IsDead(val2)) { string displayName = SafeName(val2); list.Add(new Choice { Npc = val2, DisplayName = displayName, Category = "cop" }); } } } } } catch (Exception ex) { NDLog.DebugWarn("PickRandom cops: " + ex.Message); } try { foreach (PizzoTargets.Target item in PizzoTargets.AllTargets()) { if (item != null && !string.IsNullOrEmpty(item.NpcId)) { NPC val3 = null; try { val3 = NPCManager.GetNPC(item.NpcId); } catch { } if (!((Object)(object)val3 == (Object)null) && !KillDetector.IsDead(val3)) { list.Add(new Choice { Npc = val3, DisplayName = item.DisplayName, Category = "shopkeeper" }); } } } } catch (Exception ex2) { NDLog.DebugWarn("PickRandom shopkeepers: " + ex2.Message); } try { Dealer[] array = Object.FindObjectsOfType(); if (array != null) { foreach (Dealer val4 in array) { if ((Object)(object)val4 == (Object)null) { continue; } bool isRecruited; try { isRecruited = val4.IsRecruited; } catch { continue; } if (isRecruited) { NPC val5 = GameCompat.Cast((Object)(object)val4); if (!((Object)(object)val5 == (Object)null) && !KillDetector.IsDead(val5)) { list.Add(new Choice { Npc = val5, DisplayName = SafeName(val5), Category = "own_dealer" }); } } } } } catch (Exception ex3) { NDLog.DebugWarn("PickRandom dealers: " + ex3.Message); } if (list.Count == 0) { return null; } if (rng == null) { rng = new Random(); } Choice choice = list[rng.Next(list.Count)]; NDLog.Debug("Contratto target picked: " + choice.DisplayName + " (" + choice.Category + ")"); return choice; } private static string SafeName(NPC n) { try { return (n.FirstName + " " + n.LastName).Trim(); } catch { return "the mark"; } } } public static class CurfewHelper { public const int CurfewStart = 2100; public const int CurfewEnd = 500; public const float CurfewPayMultiplier = 2f; public static bool IsCurfewActive() { try { TimeManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { return false; } int currentTime = instance.CurrentTime; return currentTime >= 2100 || currentTime <= 500; } catch (Exception ex) { NDLog.DebugWarn("CurfewHelper.IsCurfewActive: " + ex.Message); return false; } } } public static class DailyTribute { public const int TributeAmount = 1500; private const float HEARTBEAT_INTERVAL = 1f; private static float _hbTimer; private static float _payTributeWarnMuteUntil = -999f; public static int LastTributeDay { get; private set; } = -1; public static bool Initialized { get; private set; } public static void ResetForSceneReload() { _hbTimer = 0f; } public static void LoadLastDay(int day) { LastTributeDay = day; } public static void Tick(float deltaTime) { if (RankManager.CurrentRank < Rank.Sottocapo) { return; } _hbTimer -= deltaTime; if (_hbTimer > 0f) { return; } _hbTimer = 1f; try { TimeManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { return; } int elapsedDays = instance.ElapsedDays; if (!Initialized) { if (LastTributeDay < 0) { LastTributeDay = elapsedDays; } Initialized = true; } else if (elapsedDays > LastTributeDay && PayTribute()) { LastTributeDay = elapsedDays; NdranghetaSaveData.Instance?.PushNow(); } } catch (Exception ex) { NDLog.DebugWarn("DailyTribute.Tick: " + ex.Message); } } private static bool PayTribute() { try { bool flag = false; try { flag = RealEstateManager.VillaOwned; } catch { } if (flag) { if (!PayoutHelper.AddOnlineBalance(1500, "Famiglia tribute")) { return false; } DonMessaging.SendDon($"Tribute's wired to your account, Sottocapo — ${1500}. " + "Family takes care of family."); NDLog.Info($"Daily tribute paid: ${1500} (online balance — villa owned)."); return true; } List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null) { return false; } string value = "Gazebo"; DeadDrop val = null; for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val2; try { val2 = deadDrops[i]; } catch { continue; } if (!((Object)(object)val2 == (Object)null)) { string text; try { text = val2.DeadDropName; } catch { text = null; } if (!string.IsNullOrEmpty(text) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { val = val2; break; } } } if ((Object)(object)val == (Object)null) { return false; } bool flag2 = DeadDropCashHelper.SpawnCashInDrop(val, 1500); if (!flag2 && !PayoutHelper.AddCash(1500, "Daily tribute (Gazebo full)")) { return false; } DonMessaging.SendDon($"Tribute's handled, Sottocapo — ${1500}. " + "Family takes care of family."); NDLog.Info(string.Format("Daily tribute paid: ${0} ({1}).", 1500, flag2 ? "stash" : "wallet")); return true; } catch (Exception ex) { if (Time.time >= _payTributeWarnMuteUntil) { _payTributeWarnMuteUntil = Time.time + 30f; NDLog.Warn("PayTribute: " + ex.Message); } else { NDLog.DebugWarn("PayTribute: " + ex.Message); } return false; } } } public static class DeadDropCashHelper { private static float _lastFullWarn = -999f; public static bool SpawnCashInDrop(DeadDrop drop, int amount) { if ((Object)(object)drop == (Object)null || amount <= 0) { return false; } try { WorldStorageEntity storage = drop.Storage; if ((Object)(object)storage == (Object)null) { NDLog.DebugWarn("SpawnCashInDrop: Storage is null."); return false; } MoneyManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { NDLog.DebugWarn("SpawnCashInDrop: MoneyManager not ready."); return false; } CashInstance cashInstance = instance.GetCashInstance((float)amount); if (cashInstance == null) { NDLog.DebugWarn("SpawnCashInDrop: GetCashInstance returned null."); return false; } bool flag = true; try { flag = ((StorageEntity)storage).CanItemFit((ItemInstance)(object)cashInstance, 1); } catch { flag = true; } if (!flag) { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _lastFullWarn > 15f) { _lastFullWarn = realtimeSinceStartup; NDLog.Warn($"SpawnCashInDrop: ${amount} doesn't fit in '{SafeDropName(drop)}' (throttled)."); } return false; } ((StorageEntity)storage).InsertItem((ItemInstance)(object)cashInstance, true); NDLog.Debug($"Spawned ${amount} cash in '{SafeDropName(drop)}'."); return true; } catch (Exception ex) { NDLog.Warn("SpawnCashInDrop failed: " + ex.Message); return false; } } public static int GetTotalCashInDrop(DeadDrop drop) { if ((Object)(object)drop == (Object)null) { return 0; } try { WorldStorageEntity storage = drop.Storage; if ((Object)(object)storage == (Object)null) { return 0; } List itemSlots = ((StorageEntity)storage).ItemSlots; if (itemSlots == null) { return 0; } float num = 0f; for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val; try { val = itemSlots[i]; } catch { continue; } if (val == null) { continue; } ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance == null) { continue; } CashInstance val2 = GameCompat.CastObj((object)itemInstance); if (val2 == null) { continue; } float num2 = 0f; try { num2 = val2.Balance; } catch { } if (num2 <= 0f) { try { num2 = ((BaseItemInstance)val2).GetMonetaryValue(); } catch { } } int num3 = 1; try { num3 = ((BaseItemInstance)itemInstance).Quantity; } catch { } if (num3 < 1) { num3 = 1; } num += num2 * (float)num3; } return (int)num; } catch (Exception ex) { NDLog.DebugWarn("GetTotalCashInDrop: " + ex.Message); return 0; } } public static int RemoveAllCashFromDrop(DeadDrop drop) { if ((Object)(object)drop == (Object)null) { return 0; } try { WorldStorageEntity storage = drop.Storage; if ((Object)(object)storage == (Object)null) { return 0; } List itemSlots = ((StorageEntity)storage).ItemSlots; if (itemSlots == null) { return 0; } float num = 0f; for (int num2 = itemSlots.Count - 1; num2 >= 0; num2--) { ItemSlot val; try { val = itemSlots[num2]; } catch { continue; } if (val == null) { continue; } ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance == null) { continue; } CashInstance val2 = GameCompat.CastObj((object)itemInstance); if (val2 == null) { continue; } float num3 = 0f; try { num3 = val2.Balance; } catch { } if (num3 <= 0f) { try { num3 = ((BaseItemInstance)val2).GetMonetaryValue(); } catch { } } int num4 = 1; try { num4 = ((BaseItemInstance)itemInstance).Quantity; } catch { } if (num4 < 1) { num4 = 1; } num += num3 * (float)num4; try { val.ClearStoredInstance(false); } catch { } } return (int)num; } catch (Exception ex) { NDLog.DebugWarn("RemoveAllCashFromDrop: " + ex.Message); return 0; } } public static bool HasAnyCashInDrop(DeadDrop drop) { if ((Object)(object)drop == (Object)null) { return false; } try { WorldStorageEntity storage = drop.Storage; if ((Object)(object)storage == (Object)null) { return false; } List itemSlots = ((StorageEntity)storage).ItemSlots; if (itemSlots == null) { return false; } for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val; try { val = itemSlots[i]; } catch { continue; } if (val == null) { continue; } ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance != null) { CashInstance val2 = GameCompat.CastObj((object)itemInstance); if (val2 != null && ((BaseItemInstance)itemInstance).Quantity > 0) { return true; } } } return false; } catch (Exception ex) { NDLog.DebugWarn("HasAnyCashInDrop: " + ex.Message); return false; } } public static DeadDrop FindDropByGuid(string guid) { if (string.IsNullOrEmpty(guid)) { return null; } try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null) { return null; } for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val; try { val = deadDrops[i]; } catch { continue; } if (!((Object)(object)val == (Object)null)) { string a; try { a = val.GUID.ToString(); } catch { continue; } if (string.Equals(a, guid, StringComparison.Ordinal)) { return val; } } } } catch { } return null; } private static string SafeDropName(DeadDrop drop) { try { return drop.DeadDropName ?? "drop"; } catch { return "drop"; } } } internal static class DonCompassMarker { public static void EnsureSpawned() { } } internal static class DonMapMarker { } internal static class DoorLocator { public const float SEWER_Y_CUTOFF = -1.5f; public static bool IsLikelySewer(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return pos.y < -1.5f; } public static bool TryGetNearestSpawnDoor(Vector3 nearTo, NPC avoidBuildingOf, out Vector3 doorPos, float maxDistance = 150f, float minDistance = 6f) { //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_005a: 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_0174: 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_00f9: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_0118: 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_011e: 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_014e: Unknown result type (might be due to invalid IL or missing references) doorPos = nearTo; try { object obj = null; try { if ((Object)(object)avoidBuildingOf != (Object)null) { obj = avoidBuildingOf.CurrentBuilding; } } catch { } StaticDoor[] array = Object.FindObjectsOfType(); if (array == null || array.Length == 0) { return false; } float num = maxDistance * maxDistance; float num2 = minDistance * minDistance; bool flag = obj != null; bool flag2 = false; Vector3 val = nearTo; for (int i = 0; i < array.Length; i++) { StaticDoor val2; try { val2 = array[i]; } catch { continue; } if ((Object)(object)val2 == (Object)null) { continue; } if (obj != null) { bool flag3 = false; try { NPCEnterableBuilding building = val2.Building; flag3 = (Object)(object)building != (Object)null && GameCompat.SameInstance((object)building, (object)avoidBuildingOf.CurrentBuilding); } catch { } if (flag3) { continue; } } Vector3 val3; try { Transform accessPoint = val2.AccessPoint; val3 = (((Object)(object)accessPoint != (Object)null) ? accessPoint.position : ((Component)val2).transform.position); } catch { continue; } if (!IsLikelySewer(val3)) { Vector3 val4 = val3 - nearTo; float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude; if ((!flag || !(sqrMagnitude < num2)) && sqrMagnitude < num) { num = sqrMagnitude; val = val3; flag2 = true; } } } if (flag2) { doorPos = val; } return flag2; } catch (Exception ex) { NDLog.DebugWarn("DoorLocator.TryGetNearestSpawnDoor: " + ex.Message); return false; } } public static bool TryGetTargetOwnDoor(NPC target, out Vector3 doorPos) { //IL_0019: 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_0026: 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_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) //IL_014b: 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_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_00b4: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) doorPos = (((Object)(object)target != (Object)null && (Object)(object)((Component)target).transform != (Object)null) ? ((Component)target).transform.position : Vector3.zero); try { if ((Object)(object)target == (Object)null) { return false; } object obj = null; try { obj = target.CurrentBuilding; } catch { } if (obj == null) { return TryGetNearestDoor(((Component)target).transform.position, out doorPos, 60f); } StaticDoor[] array = Object.FindObjectsOfType(); if (array == null || array.Length == 0) { return false; } Vector3 position = ((Component)target).transform.position; float num = float.MaxValue; bool flag = false; Vector3 val = doorPos; for (int i = 0; i < array.Length; i++) { StaticDoor val2; try { val2 = array[i]; } catch { continue; } if ((Object)(object)val2 == (Object)null) { continue; } bool flag2 = false; try { NPCEnterableBuilding building = val2.Building; flag2 = (Object)(object)building != (Object)null && GameCompat.SameInstance((object)building, (object)target.CurrentBuilding); } catch { } if (flag2) { Vector3 val3; try { Transform accessPoint = val2.AccessPoint; val3 = (((Object)(object)accessPoint != (Object)null) ? accessPoint.position : ((Component)val2).transform.position); } catch { continue; } Vector3 val4 = val3 - position; float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val = val3; flag = true; } } } if (flag) { doorPos = val; } return flag; } catch (Exception ex) { NDLog.DebugWarn("DoorLocator.TryGetTargetOwnDoor: " + ex.Message); return false; } } public static bool TryGetTargetOwnDoorOriented(NPC target, out Vector3 doorPos, out Vector3 outwardDir) { //IL_0019: 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_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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: 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) //IL_01e9: 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_0151: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00b1: 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_0156: 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_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: 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_01ae: Unknown result type (might be due to invalid IL or missing references) doorPos = (((Object)(object)target != (Object)null && (Object)(object)((Component)target).transform != (Object)null) ? ((Component)target).transform.position : Vector3.zero); outwardDir = Vector3.zero; try { if ((Object)(object)target == (Object)null) { return false; } object obj = null; try { obj = target.CurrentBuilding; } catch { } if (obj == null) { return false; } StaticDoor[] array = Object.FindObjectsOfType(); if (array == null || array.Length == 0) { return false; } Vector3 position = ((Component)target).transform.position; float num = float.MaxValue; bool flag = false; Vector3 val = doorPos; Vector3 val2 = Vector3.zero; for (int i = 0; i < array.Length; i++) { StaticDoor val3; try { val3 = array[i]; } catch { continue; } if ((Object)(object)val3 == (Object)null) { continue; } bool flag2 = false; try { NPCEnterableBuilding building = val3.Building; flag2 = (Object)(object)building != (Object)null && GameCompat.SameInstance((object)building, (object)target.CurrentBuilding); } catch { } if (flag2) { Vector3 zero = Vector3.zero; Vector3 val4; try { Transform accessPoint = val3.AccessPoint; val4 = (((Object)(object)accessPoint != (Object)null) ? accessPoint.position : ((Component)val3).transform.position); zero = ((!((Object)(object)accessPoint != (Object)null)) ? ((Component)val3).transform.forward : accessPoint.forward); } catch { continue; } Vector3 val5 = val4 - position; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val = val4; val2 = zero; flag = true; } } } if (flag) { doorPos = val; outwardDir = new Vector3(val2.x, 0f, val2.z); } return flag; } catch (Exception ex) { NDLog.DebugWarn("DoorLocator.TryGetTargetOwnDoorOriented: " + ex.Message); return false; } } public static bool TryGetNearestDoor(Vector3 from, out Vector3 doorPos, float maxDistance = 200f) { //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_002e: 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_00d1: 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_007c: 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_0081: 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_008c: Unknown result type (might be due to invalid IL or missing references) //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_00ac: 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) doorPos = from; try { StaticDoor[] array = Object.FindObjectsOfType(); if (array == null || array.Length == 0) { return false; } float num = maxDistance * maxDistance; bool flag = false; Vector3 val = from; for (int i = 0; i < array.Length; i++) { StaticDoor val2; try { val2 = array[i]; } catch { continue; } if (!((Object)(object)val2 == (Object)null)) { Vector3 val3; try { Transform accessPoint = val2.AccessPoint; val3 = (((Object)(object)accessPoint != (Object)null) ? accessPoint.position : ((Component)val2).transform.position); } catch { continue; } Vector3 val4 = val3 - from; float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val = val3; flag = true; } } } if (flag) { doorPos = val; } return flag; } catch (Exception ex) { NDLog.DebugWarn("DoorLocator.TryGetNearestDoor: " + ex.Message); return false; } } } public static class DoorPoiMarker { private sealed class Marker { public GameObject go; public POI poi; public Vector3 pos; public string label; public Sprite icon; public bool iconApplied; } private const string HolderName = "Ndrangheta_DoorPois"; private const float UI_SCALE = 0.5f; private static GameObject _holder; private static readonly Dictionary _markers = new Dictionary(StringComparer.Ordinal); private static GameObject _templateClone; private static float _noTemplateWarnMuteUntil = -999f; private static float _templateScanCooldownUntil; public static void Set(string key, Vector3 pos, string label, Sprite icon) { //IL_039c: 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_0326: 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_02ce: 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_0045: 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_0211: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(key)) { return; } try { EnsureHolder(); if (_markers.TryGetValue(key, out var value) && value != null && (Object)(object)value.go != (Object)null) { value.pos = pos; try { value.go.transform.position = pos; } catch { } try { if ((Object)(object)value.poi != (Object)null) { ((Component)value.poi).transform.position = pos; } } catch { } UpdatePoiPosition(value.poi); if (!string.Equals(value.label, label, StringComparison.Ordinal)) { value.label = label; ApplyLabel(value.poi, label); } if ((Object)(object)icon != (Object)null && value.icon != icon) { value.icon = icon; value.iconApplied = false; ApplyIconAsync(value); } return; } GameObject template = GetTemplate(); if ((Object)(object)template == (Object)null) { if (Time.time >= _noTemplateWarnMuteUntil) { _noTemplateWarnMuteUntil = Time.time + 30f; NDLog.Warn("[DOORPOI] no base-POI template found in scene — marker '" + key + "' not created."); } else { NDLog.DebugWarn("[DOORPOI] no base-POI template found in scene — marker '" + key + "' not created."); } return; } GameObject val = Object.Instantiate(template); if ((Object)(object)val == (Object)null) { if (Time.time >= _noTemplateWarnMuteUntil) { _noTemplateWarnMuteUntil = Time.time + 30f; NDLog.Warn("[DOORPOI] Instantiate returned null for '" + key + "'."); } else { NDLog.DebugWarn("[DOORPOI] Instantiate returned null for '" + key + "'."); } return; } ((Object)val).name = "DoorPoi_" + key; val.transform.SetParent(_holder.transform, false); val.transform.position = pos; POI component = val.GetComponent(); if ((Object)(object)component == (Object)null) { if (Time.time >= _noTemplateWarnMuteUntil) { _noTemplateWarnMuteUntil = Time.time + 30f; NDLog.Warn("[DOORPOI] cloned object has no POI component for '" + key + "'."); } else { NDLog.DebugWarn("[DOORPOI] cloned object has no POI component for '" + key + "'."); } try { Object.Destroy((Object)(object)val); return; } catch { return; } } try { component.AutoUpdatePosition = true; } catch { } try { component.Rotate = false; } catch { } try { component.MainTextVisibility = (TextShowMode)((!string.IsNullOrEmpty(label)) ? 2 : 0); } catch { } if (!string.IsNullOrEmpty(label)) { try { component.DefaultMainText = label; } catch { } try { component.SetMainText(label); } catch { } } Marker marker = new Marker { go = val, poi = component, pos = pos, label = label, icon = icon, iconApplied = false }; _markers[key] = marker; try { if (!val.activeSelf) { val.SetActive(true); } } catch { } try { ((Behaviour)component).enabled = true; } catch { } ApplyIconAsync(marker); NDLog.Debug($"[DOORPOI] marker '{key}' created @ {pos} (label='{label}', icon={(Object)(object)icon != (Object)null})."); } catch (Exception ex) { if (Time.time >= _noTemplateWarnMuteUntil) { _noTemplateWarnMuteUntil = Time.time + 30f; NDLog.Warn("[DOORPOI] Set('" + key + "') failed: " + ex.Message); } else { NDLog.DebugWarn("[DOORPOI] Set('" + key + "') failed: " + ex.Message); } } } public static void Remove(string key) { if (string.IsNullOrEmpty(key)) { return; } try { if (_markers.TryGetValue(key, out var value)) { _markers.Remove(key); DestroyMarker(value); NDLog.Debug("[DOORPOI] marker '" + key + "' removed."); } } catch (Exception ex) { NDLog.DebugWarn("[DOORPOI] Remove('" + key + "') failed: " + ex.Message); } } public static void RemoveAll() { try { foreach (KeyValuePair marker in _markers) { DestroyMarker(marker.Value); } } catch { } _markers.Clear(); try { if ((Object)(object)_templateClone != (Object)null) { Object.Destroy((Object)(object)_templateClone); } } catch { } _templateClone = null; try { if ((Object)(object)_holder != (Object)null) { Object.Destroy((Object)(object)_holder); } } catch { } _holder = null; NDLog.Debug("[DOORPOI] all markers removed."); } private static void EnsureHolder() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!((Object)(object)_holder != (Object)null)) { _holder = new GameObject("Ndrangheta_DoorPois"); } } private static void DestroyMarker(Marker m) { if (m == null) { return; } try { if ((Object)(object)m.go != (Object)null) { try { m.go.SetActive(false); } catch { } try { Object.Destroy((Object)(object)m.go); } catch { } } } catch { } m.go = null; m.poi = null; } private static GameObject GetTemplate() { if ((Object)(object)_templateClone != (Object)null) { return _templateClone; } if (Time.time < _templateScanCooldownUntil) { return null; } _templateScanCooldownUntil = Time.time + 3f; _templateClone = ClonePoiTemplate(); return _templateClone; } private static GameObject ClonePoiTemplate() { //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Expected O, but got Unknown try { POI[] array = Object.FindObjectsOfType(true); if (array != null && array.Length != 0) { POI val = null; for (int i = 0; i < array.Length; i++) { POI val2; try { val2 = array[i]; } catch { continue; } if (!((Object)(object)val2 == (Object)null) && IsExactBasePoi(val2)) { bool flag = true; try { flag = (Object)(object)val2.UI == (Object)null; } catch { } if (flag) { val = val2; break; } } } if ((Object)(object)val != (Object)null) { GameObject val3 = Object.Instantiate(((Component)val).gameObject); if ((Object)(object)val3 != (Object)null) { PrepTemplate(val3); NDLog.Debug("[DOORPOI] template via cloned base POI."); return val3; } } else { NDLog.DebugWarn($"[DOORPOI] {array.Length} POIs found but none is an exact base POI."); } } } catch (Exception ex) { NDLog.DebugWarn("[DOORPOI] clone-base strategy: " + ex.Message); } try { Quest val4 = Object.FindObjectOfType(true); if ((Object)(object)val4 != (Object)null) { GameObject val5 = null; try { val5 = val4.PoIPrefab; } catch { } if ((Object)(object)val5 != (Object)null) { GameObject val6 = Object.Instantiate(val5); if ((Object)(object)val6 != (Object)null && (Object)(object)val6.GetComponent() != (Object)null) { PrepTemplate(val6); NDLog.Debug("[DOORPOI] template via Quest.PoIPrefab."); return val6; } if ((Object)(object)val6 != (Object)null) { try { Object.Destroy((Object)(object)val6); } catch { } } } } } catch (Exception ex2) { NDLog.DebugWarn("[DOORPOI] PoIPrefab strategy: " + ex2.Message); } try { POI val7 = Object.FindObjectOfType(true); GameObject val8 = null; try { if ((Object)(object)val7 != (Object)null) { val8 = val7.UIPrefab; } } catch { } if ((Object)(object)val8 != (Object)null) { GameObject val9 = new GameObject("DoorPoiTemplate"); POI val10 = val9.AddComponent(); try { val10.UIPrefab = val8; } catch { } PrepTemplate(val9); NDLog.Debug("[DOORPOI] template via fresh POI + UIPrefab."); return val9; } } catch (Exception ex3) { NDLog.DebugWarn("[DOORPOI] fresh-POI strategy: " + ex3.Message); } return null; } private static void PrepTemplate(GameObject tmpl) { try { tmpl.SetActive(false); } catch { } try { Object.DontDestroyOnLoad((Object)(object)tmpl); } catch { } try { ((Object)tmpl).name = "DoorPoiTemplate"; } catch { } } private static bool IsExactBasePoi(POI p) { try { return ((object)p).GetType() == typeof(POI); } catch { return false; } } private static void UpdatePoiPosition(POI poi) { if ((Object)(object)poi == (Object)null) { return; } try { if (Singleton.InstanceExists) { poi.UpdatePosition(); } } catch { } } private static void ApplyLabel(POI poi, string label) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)poi == (Object)null) { return; } try { poi.MainTextVisibility = (TextShowMode)((!string.IsNullOrEmpty(label)) ? 2 : 0); } catch { } try { poi.DefaultMainText = label ?? string.Empty; } catch { } try { poi.SetMainText(label ?? string.Empty); } catch { } } private static void ApplyIconAsync(Marker m) { if (m == null) { return; } try { MelonCoroutines.Start(WaitAndApplyIcon(m)); } catch (Exception ex) { NDLog.DebugWarn("[DOORPOI] ApplyIconAsync: " + ex.Message); } } private static IEnumerator WaitAndApplyIcon(Marker m) { float elapsed = 0f; while (elapsed < 20f) { if (m == null || (Object)(object)m.go == (Object)null || m.iconApplied) { yield break; } RectTransform ui = null; try { ui = (((Object)(object)m.poi != (Object)null) ? m.poi.UI : null); } catch { } if ((Object)(object)ui != (Object)null) { try { ((Transform)ui).localScale = new Vector3(0.5f, 0.5f, 1f); } catch { } if ((Object)(object)m.icon == (Object)null || TryApplyIcon(m)) { m.iconApplied = true; NDLog.Debug("[DOORPOI] UI finalized (scaled" + (((Object)(object)m.icon != (Object)null) ? "+icon" : "") + ")."); yield break; } } elapsed += Time.deltaTime; yield return null; } NDLog.DebugWarn("[DOORPOI] UI finalize timed out."); } private static bool TryApplyIcon(Marker m) { try { POI poi = m.poi; if ((Object)(object)poi == (Object)null) { return false; } RectTransform val = null; try { val = poi.IconContainer; } catch { } if ((Object)(object)val == (Object)null) { return false; } Image[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return false; } bool result = false; Image[] array = componentsInChildren; foreach (Image val2 in array) { if (!((Object)(object)val2 == (Object)null)) { val2.sprite = m.icon; result = true; } } return result; } catch (Exception ex) { NDLog.DebugWarn("[DOORPOI] TryApplyIcon: " + ex.Message); return false; } } } public static class FaidaState { public static int BenziePoints { get; private set; } public static int RevealedDeals { get; private set; } public static int BattlesLost { get; private set; } public static int TriadPoints { get; private set; } public static void RecordReveal() { RevealedDeals++; } public static void RecordWin() { BenziePoints++; } public static void RecordLoss() { BattlesLost++; } public static void RecordTriadWin() { TriadPoints++; } public static void RecordTriadLoss() { BattlesLost++; } public static void Load(int benziePoints, int revealedDeals, int triadPoints = 0) { BenziePoints = ((benziePoints >= 0) ? benziePoints : 0); RevealedDeals = ((revealedDeals >= 0) ? revealedDeals : 0); TriadPoints = ((triadPoints >= 0) ? triadPoints : 0); } public static void ResetForSceneReload() { BenziePoints = 0; RevealedDeals = 0; BattlesLost = 0; TriadPoints = 0; } } internal static class FamigliaActor { internal sealed class Actor { public GameObject Body; public int SlotIdx; public Vector3 Post; public float Yaw; } internal static Actor TryPost(CartelGoon cloneSource, int slotIdx, Vector3 post, float yaw) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) return TryPostTemplate(((Object)(object)cloneSource != (Object)null) ? ((Component)cloneSource).gameObject : null, slotIdx, post, yaw); } internal static Actor TryPostTemplate(GameObject template, int slotIdx, Vector3 post, float yaw, GoonPool pool = null) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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) try { if ((Object)(object)template == (Object)null) { return null; } GameObject val = Object.Instantiate(template); if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = $"Ndrangheta_FamigliaActor_{slotIdx}"; CartelGoon val2 = null; try { val2 = val.GetComponentInChildren(true); } catch { } try { if ((Object)(object)val2 != (Object)null && (Object)(object)pool != (Object)null) { FamigliaOutfit.ApplyGuardia(val2, slotIdx, pool); } } catch { } StripToVisual(val); try { if ((Object)(object)val2 != (Object)null) { val2.IsGoonSpawned = false; } } catch { } try { val.transform.position = post; val.transform.rotation = Quaternion.Euler(0f, yaw, 0f); } catch { } try { if (!val.activeSelf) { val.SetActive(true); } } catch { } NDLog.Debug($"[ACTOR] Famiglia stand-in posted for slot {slotIdx} (pool fallback)."); return new Actor { Body = val, SlotIdx = slotIdx, Post = post, Yaw = yaw }; } catch (Exception ex) { NDLog.DebugWarn($"[ACTOR] TryPost slot {slotIdx}: {ex.Message}"); return null; } } internal static void Hold(Actor a) { //IL_0027: 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_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_0068: 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) try { if (a != null && !((Object)(object)a.Body == (Object)null)) { Transform transform = a.Body.transform; Vector3 val = transform.position - a.Post; if (((Vector3)(ref val)).sqrMagnitude > 4f) { transform.position = a.Post; } transform.rotation = Quaternion.Euler(0f, a.Yaw, 0f); } } catch { } } internal static void Destroy(Actor a) { try { if (a != null && (Object)(object)a.Body != (Object)null) { Object.Destroy((Object)(object)a.Body); } } catch { } } private static void StripToVisual(GameObject go) { try { Animator val = null; try { val = go.GetComponentInChildren(true); } catch { } try { MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren(true); if (componentsInChildren != null) { for (int i = 0; i < componentsInChildren.Length; i++) { try { MonoBehaviour val2 = componentsInChildren[i]; if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = false; } } catch { } } } } catch { } try { NavMeshAgent[] componentsInChildren2 = go.GetComponentsInChildren(true); if (componentsInChildren2 != null) { for (int j = 0; j < componentsInChildren2.Length; j++) { try { if ((Object)(object)componentsInChildren2[j] != (Object)null) { ((Behaviour)componentsInChildren2[j]).enabled = false; } } catch { } } } } catch { } try { NavMeshObstacle[] componentsInChildren3 = go.GetComponentsInChildren(true); if (componentsInChildren3 != null) { for (int k = 0; k < componentsInChildren3.Length; k++) { try { if ((Object)(object)componentsInChildren3[k] != (Object)null) { ((Behaviour)componentsInChildren3[k]).enabled = false; } } catch { } } } } catch { } try { Collider[] componentsInChildren4 = go.GetComponentsInChildren(true); if (componentsInChildren4 != null) { for (int l = 0; l < componentsInChildren4.Length; l++) { try { if ((Object)(object)componentsInChildren4[l] != (Object)null) { componentsInChildren4[l].enabled = false; } } catch { } } } } catch { } try { Rigidbody[] componentsInChildren5 = go.GetComponentsInChildren(true); if (componentsInChildren5 != null) { for (int m = 0; m < componentsInChildren5.Length; m++) { try { if ((Object)(object)componentsInChildren5[m] != (Object)null) { componentsInChildren5[m].isKinematic = true; componentsInChildren5[m].useGravity = false; } } catch { } } } } catch { } if ((Object)(object)val != (Object)null) { try { ((Behaviour)val).enabled = true; val.applyRootMotion = false; val.cullingMode = (AnimatorCullingMode)0; return; } catch { return; } } } catch (Exception ex) { NDLog.DebugWarn("[ACTOR] StripToVisual: " + ex.Message); } } } internal static class FamigliaOutfit { private static readonly Color OutfitBlack = new Color(0.07f, 0.07f, 0.08f); private static readonly Color JacketDark = new Color(0.12f, 0.12f, 0.14f); private static readonly Color TriadRed = new Color(0.55f, 0.05f, 0.06f); private static readonly Color TriadDark = new Color(0.1f, 0.02f, 0.03f); private static AvatarSettings _clothing; private static AvatarSettings _guardia; private static AvatarSettings _triad; private static AvatarSettings _triadBoss; private static readonly Dictionary _maleBaseClones = new Dictionary(); public static void Apply(CartelGoon goon, int idx, GoonPool pool) { ApplySettings(goon, idx, pool, GetClothing(), "Apply"); try { FamigliaReskinSync.Register(goon, idx); } catch { } } public static void ApplyGuardia(CartelGoon goon, int idx, GoonPool pool) { ApplySettings(goon, idx, pool, GetGuardia(), "ApplyGuardia"); } public static void ApplyTriad(CartelGoon goon, int idx, GoonPool pool) { ApplySettings(goon, idx, pool, GetTriad(), "ApplyTriad"); } public static void ApplyTriadBoss(CartelGoon goon, int idx, GoonPool pool) { ApplySettings(goon, idx, pool, GetTriadBoss(), "ApplyTriadBoss"); } private static void ApplySettings(CartelGoon goon, int idx, GoonPool pool, AvatarSettings clothing, string tag) { try { Avatar val = (((Object)(object)goon != (Object)null) ? ((NPC)goon).Avatar : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)clothing == (Object)null)) { ClearStrayHair(val); val.LoadAvatarSettings(clothing); AvatarSettings[] array = (((Object)(object)pool != (Object)null) ? pool.MaleBaseAppearances : null); if (array != null && array.Length != 0) { int i = (idx % array.Length + array.Length) % array.Length; val.LoadNakedSettings(MaleBaseClone(array, i), false, 100); } } } catch (Exception ex) { NDLog.DebugWarn("FamigliaOutfit." + tag + ": " + ex.Message); } } private static void ClearStrayHair(Avatar av) { try { Transform headBone = av.HeadBone; if ((Object)(object)headBone != (Object)null) { Hair[] componentsInChildren = ((Component)headBone).GetComponentsInChildren(true); if (componentsInChildren != null) { for (int i = 0; i < componentsInChildren.Length; i++) { try { if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)((Component)componentsInChildren[i]).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)componentsInChildren[i]).gameObject); } } catch { } } } } try { av.appliedHair = null; } catch { } } catch (Exception ex) { NDLog.DebugWarn("FamigliaOutfit.ClearStrayHair: " + ex.Message); } } private static AvatarSettings MaleBaseClone(AvatarSettings[] bases, int i) { try { if (_maleBaseClones.TryGetValue(i, out var value) && (Object)(object)value != (Object)null) { return value; } AvatarSettings val = Object.Instantiate(bases[i]); ((Object)val).hideFlags = (HideFlags)52; try { val.Gender = 0f; } catch { } _maleBaseClones[i] = val; return val; } catch { return bases[i]; } } private static AvatarSettings GetGuardia() { //IL_007a: 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_00b7: 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_00d9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_guardia != (Object)null) { return _guardia; } try { AvatarSettings val = ScriptableObject.CreateInstance(); if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = "NDR_GuardiaClothing"; ((Object)val).hideFlags = (HideFlags)52; try { val.Gender = 0f; val.Height = 1f; val.Weight = 0.5f; } catch { } if (!AddBodyLayer(val, "Avatar/Layers/Bottom/Jeans", OutfitBlack)) { return null; } if (!AddBodyLayer(val, "Avatar/Layers/Top/Buttonup", OutfitBlack)) { return null; } AddAccessory(val, "Avatar/Accessories/Chest/BulletproofVest/BulletproofVest", OutfitBlack); AddAccessory(val, "Avatar/Accessories/Feet/CombatBoots/CombatBoots", OutfitBlack); AddAccessory(val, "Avatar/Accessories/Head/LegendSunglasses/LegendSunglasses", OutfitBlack); _guardia = val; NDLog.Debug("FamigliaOutfit: guardia settings composed (Jeans/Buttonup/Vest/Boots/Sunglasses)."); return _guardia; } catch (Exception ex) { NDLog.Warn("FamigliaOutfit.GetGuardia: " + ex.Message); return null; } } private static AvatarSettings GetTriad() { //IL_007a: 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_00b4: 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) if ((Object)(object)_triad != (Object)null) { return _triad; } try { AvatarSettings val = ScriptableObject.CreateInstance(); if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = "NDR_TriadClothing"; ((Object)val).hideFlags = (HideFlags)52; try { val.Gender = 0f; val.Height = 1f; val.Weight = 0.5f; } catch { } if (!AddBodyLayer(val, "Avatar/Layers/Bottom/Jeans", TriadDark)) { return null; } if (!AddBodyLayer(val, "Avatar/Layers/Top/Buttonup", TriadRed)) { return null; } AddAccessory(val, "Avatar/Accessories/Feet/CombatBoots/CombatBoots", TriadDark); AddAccessory(val, "Avatar/Accessories/Head/LegendSunglasses/LegendSunglasses", OutfitBlack); _triad = val; NDLog.Debug("FamigliaOutfit: triad settings composed (red Buttonup / dark Jeans / Boots / Sunglasses)."); return _triad; } catch (Exception ex) { NDLog.Warn("FamigliaOutfit.GetTriad: " + ex.Message); return null; } } private static AvatarSettings GetTriadBoss() { //IL_007a: 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_00b7: 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_00d9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_triadBoss != (Object)null) { return _triadBoss; } try { AvatarSettings val = ScriptableObject.CreateInstance(); if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = "NDR_TriadBossClothing"; ((Object)val).hideFlags = (HideFlags)52; try { val.Gender = 0f; val.Height = 1f; val.Weight = 0.5f; } catch { } if (!AddBodyLayer(val, "Avatar/Layers/Bottom/Jeans", TriadDark)) { return null; } if (!AddBodyLayer(val, "Avatar/Layers/Top/Buttonup", TriadRed)) { return null; } AddAccessory(val, "Avatar/Accessories/Chest/Blazer/Blazer", TriadRed); AddAccessory(val, "Avatar/Accessories/Feet/CombatBoots/CombatBoots", TriadDark); AddAccessory(val, "Avatar/Accessories/Head/LegendSunglasses/LegendSunglasses", OutfitBlack); _triadBoss = val; NDLog.Debug("FamigliaOutfit: triad-boss settings composed (red Blazer over red Buttonup)."); return _triadBoss; } catch (Exception ex) { NDLog.Warn("FamigliaOutfit.GetTriadBoss: " + ex.Message); return null; } } private static AvatarSettings GetClothing() { //IL_007a: 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_00b7: 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_00d9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_clothing != (Object)null) { return _clothing; } try { AvatarSettings val = ScriptableObject.CreateInstance(); if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = "NDR_FamigliaClothing"; ((Object)val).hideFlags = (HideFlags)52; try { val.Gender = 0f; val.Height = 1f; val.Weight = 0.5f; } catch { } if (!AddBodyLayer(val, "Avatar/Layers/Bottom/Jeans", OutfitBlack)) { return null; } if (!AddBodyLayer(val, "Avatar/Layers/Top/Buttonup", OutfitBlack)) { return null; } AddAccessory(val, "Avatar/Accessories/Chest/Blazer/Blazer", JacketDark); AddAccessory(val, "Avatar/Accessories/Feet/CombatBoots/CombatBoots", OutfitBlack); AddAccessory(val, "Avatar/Accessories/Head/LegendSunglasses/LegendSunglasses", OutfitBlack); _clothing = val; NDLog.Debug("FamigliaOutfit: clothing settings composed (Jeans/Buttonup/Blazer/Boots/Sunglasses)."); return _clothing; } catch (Exception ex) { NDLog.Warn("FamigliaOutfit.GetClothing: " + ex.Message); return null; } } private static bool AddBodyLayer(AvatarSettings s, string path, Color tint) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_002e: Unknown result type (might be due to invalid IL or missing references) try { List bodyLayerSettings = s.BodyLayerSettings; if (bodyLayerSettings == null) { return false; } bodyLayerSettings.Add(new LayerSetting { layerPath = path, layerTint = tint }); return true; } catch (Exception ex) { NDLog.DebugWarn("FamigliaOutfit body '" + path + "': " + ex.Message); return false; } } private static void AddAccessory(AvatarSettings s, string path, Color color) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: 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) try { List accessorySettings = s.AccessorySettings; if (accessorySettings != null) { AccessorySetting val = new AccessorySetting(); val.path = path; val.color = color; accessorySettings.Add(val); } } catch (Exception ex) { NDLog.DebugWarn("FamigliaOutfit acc '" + path + "': " + ex.Message); } } } internal static class FamigliaReskinSync { private static readonly Dictionary _goons = new Dictionary(); private static int _lastEncodeCount = -1; private static readonly Dictionary _clientCount = new Dictionary(); private static readonly Dictionary _clientNext = new Dictionary(); private static readonly Dictionary _clientGoons = new Dictionary(); private static GoonPool _clientPool; private static float _clientScanNext; private static int _lastCsvLen = -1; private const int RE_APPLY_TIMES = 8; private const float SCAN_INTERVAL = 0.5f; private const float RE_APPLY_INTERVAL = 1f; public static void Register(CartelGoon goon, int idx) { try { if (SessionGate.IsAuthority && !((Object)(object)goon == (Object)null)) { string text = KeyOf(goon); if (!string.IsNullOrEmpty(text)) { _goons[text] = idx; } else { NDLog.DebugWarn("[RESKIN] host: goon has no NetworkObject — cannot sync reskin."); } } } catch { } } public static void Unregister(CartelGoon goon) { try { if (!((Object)(object)goon == (Object)null)) { string text = KeyOf(goon); if (!string.IsNullOrEmpty(text)) { _goons.Remove(text); } } } catch { } } public static string Encode() { try { if (_goons.Count != _lastEncodeCount) { _lastEncodeCount = _goons.Count; NDLog.Debug($"[RESKIN] host publishing {_goons.Count} famiglia goon(s)."); } if (_goons.Count == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(); bool flag = true; foreach (KeyValuePair goon in _goons) { if (!flag) { stringBuilder.Append('~'); } flag = false; stringBuilder.Append(goon.Key).Append(':').Append(goon.Value); } return stringBuilder.ToString(); } catch { return ""; } } private static string KeyOf(CartelGoon goon) { try { NetworkObject val = (((Object)(object)goon != (Object)null && (Object)(object)((Component)goon).gameObject != (Object)null) ? ((Component)goon).gameObject.GetComponent() : null); if ((Object)(object)val == (Object)null) { return null; } return val.ObjectId.ToString(); } catch { return null; } } private static void ReenableClientGoonAI(CartelGoon goon) { try { NPCBehaviour behaviour = ((NPC)goon).Behaviour; if ((Object)(object)behaviour != (Object)null && !((Behaviour)behaviour).enabled) { ((Behaviour)behaviour).enabled = true; } } catch { } try { NPCAwareness awareness = ((NPC)goon).Awareness; VisionCone val = (((Object)(object)awareness != (Object)null) ? awareness.VisionCone : null); if ((Object)(object)val != (Object)null && !((Behaviour)val).enabled) { ((Behaviour)val).enabled = true; } } catch { } } private static void ReenableAllCachedGoons() { foreach (KeyValuePair clientGoon in _clientGoons) { if ((Object)(object)clientGoon.Value != (Object)null) { ReenableClientGoonAI(clientGoon.Value); } } } public static void ClientApply(string csv) { try { if (SessionGate.IsAuthority || Time.time < _clientScanNext) { return; } _clientScanNext = Time.time + 0.5f; int num = csv?.Length ?? 0; if (num != _lastCsvLen) { _lastCsvLen = num; NDLog.Debug(string.Format("[RESKIN] client csv len={0} ('{1}').", num, (num > 60) ? (csv.Substring(0, 60) + "…") : csv)); } if (string.IsNullOrEmpty(csv)) { if (_clientCount.Count > 0 || _clientGoons.Count > 0) { ReenableAllCachedGoons(); _clientCount.Clear(); _clientNext.Clear(); _clientGoons.Clear(); } return; } Dictionary dictionary = new Dictionary(); string[] array = csv.Split(new char[1] { '~' }); foreach (string text in array) { if (string.IsNullOrEmpty(text)) { continue; } int num2 = text.IndexOf(':'); if (num2 > 0) { string key = text.Substring(0, num2); if (!int.TryParse(text.Substring(num2 + 1), out var result)) { result = 0; } dictionary[key] = result; } } if (_clientCount.Count > 0 || _clientGoons.Count > 0) { List list = null; foreach (KeyValuePair item in _clientCount) { if (!dictionary.ContainsKey(item.Key)) { (list ?? (list = new List())).Add(item.Key); } } foreach (KeyValuePair clientGoon in _clientGoons) { if (!dictionary.ContainsKey(clientGoon.Key) && (list == null || !list.Contains(clientGoon.Key))) { (list ?? (list = new List())).Add(clientGoon.Key); } } if (list != null) { for (int j = 0; j < list.Count; j++) { if (_clientGoons.TryGetValue(list[j], out var value) && (Object)(object)value != (Object)null) { ReenableClientGoonAI(value); } _clientCount.Remove(list[j]); _clientNext.Remove(list[j]); _clientGoons.Remove(list[j]); } } } if (dictionary.Count == 0) { return; } bool flag = false; foreach (KeyValuePair item2 in dictionary) { if (!_clientGoons.TryGetValue(item2.Key, out var value2) || (Object)(object)value2 == (Object)null) { flag = true; break; } } if (flag) { CartelGoon[] array2 = Object.FindObjectsOfType(true); if (array2 != null && array2.Length != 0) { if ((Object)(object)_clientPool == (Object)null) { _clientPool = Object.FindObjectOfType(true); } foreach (CartelGoon val in array2) { if (!((Object)(object)val == (Object)null)) { string text2 = KeyOf(val); if (text2 != null && dictionary.ContainsKey(text2) && (!_clientGoons.TryGetValue(text2, out var value3) || (Object)(object)value3 == (Object)null)) { _clientGoons[text2] = val; NDLog.Debug("[RESKIN] client resolved goon objId=" + text2 + "."); } } } } else { NDLog.Debug($"[RESKIN] client: {dictionary.Count} wanted but 0 CartelGoons in scene yet."); } } foreach (KeyValuePair item3 in dictionary) { if (!_clientGoons.TryGetValue(item3.Key, out var value4) || (Object)(object)value4 == (Object)null) { continue; } string key2 = item3.Key; int value5 = item3.Value; try { if (((NPC)value4).FirstName != "Famiglia") { LuckyBrawlManager.RenameToFamiglia(value4); } } catch { } try { NPCBehaviour behaviour = ((NPC)value4).Behaviour; if ((Object)(object)behaviour != (Object)null && ((Behaviour)behaviour).enabled) { ((Behaviour)behaviour).enabled = false; } } catch { } try { NPCAwareness awareness = ((NPC)value4).Awareness; VisionCone val2 = (((Object)(object)awareness != (Object)null) ? awareness.VisionCone : null); if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled) { ((Behaviour)val2).enabled = false; } } catch { } _clientCount.TryGetValue(key2, out var value6); _clientNext.TryGetValue(key2, out var value7); if (value6 < 8 && !(Time.time < value7)) { try { FamigliaOutfit.Apply(value4, value5, _clientPool); } catch { } try { LuckyBrawlManager.RenameToFamiglia(value4); } catch { } _clientCount[key2] = value6 + 1; _clientNext[key2] = Time.time + 1f; if (value6 == 0) { NDLog.Debug($"[RESKIN] client applied famiglia look to goon objId={key2} (idx {value5})."); } } } } catch (Exception ex) { NDLog.DebugWarn("FamigliaReskinSync.ClientApply: " + ex.Message); } } public static void ResetForSceneReload() { _goons.Clear(); _clientCount.Clear(); _clientNext.Clear(); _clientGoons.Clear(); _clientPool = null; _clientScanNext = 0f; _lastCsvLen = -1; } } public static class FamigliaStash { public static int GetTotalCashInStash() { DeadDrop val = ResolveStashDrop(); if ((Object)(object)val == (Object)null) { return 0; } try { WorldStorageEntity storage = val.Storage; if ((Object)(object)storage == (Object)null) { return 0; } List itemSlots = ((StorageEntity)storage).ItemSlots; if (itemSlots == null) { return 0; } int num = 0; for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val2; try { val2 = itemSlots[i]; } catch { continue; } if (val2 == null) { continue; } ItemInstance itemInstance; try { itemInstance = val2.ItemInstance; } catch { continue; } if (itemInstance != null) { CashInstance val3 = GameCompat.CastObj((object)itemInstance); if (val3 != null) { num += ((BaseItemInstance)itemInstance).Quantity; } } } return num; } catch (Exception ex) { NDLog.DebugWarn("GetTotalCashInStash: " + ex.Message); return 0; } } public static bool ClearAllCashFromStash() { DeadDrop val = ResolveStashDrop(); if ((Object)(object)val == (Object)null) { return false; } try { WorldStorageEntity storage = val.Storage; if ((Object)(object)storage == (Object)null) { return false; } List itemSlots = ((StorageEntity)storage).ItemSlots; if (itemSlots == null) { return false; } for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val2; try { val2 = itemSlots[i]; } catch { continue; } if (val2 == null) { continue; } ItemInstance itemInstance; try { itemInstance = val2.ItemInstance; } catch { continue; } if (itemInstance == null) { continue; } CashInstance val3 = GameCompat.CastObj((object)itemInstance); if (val3 != null) { try { val2.ClearStoredInstance(false); } catch { } } } return true; } catch (Exception ex) { NDLog.DebugWarn("ClearAllCashFromStash: " + ex.Message); return false; } } private static DeadDrop ResolveStashDrop() { try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null) { return null; } string value = "Gazebo"; if (string.IsNullOrEmpty(value)) { return null; } for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val; try { val = deadDrops[i]; } catch { continue; } if (!((Object)(object)val == (Object)null)) { string text; try { text = val.DeadDropName; } catch { text = null; } if (!string.IsNullOrEmpty(text) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return val; } } } } catch { } return null; } } public enum FearTitle { RespectedMan, WellKnown, FearedVip, HolyShitRun, TheButcher, Psychopath, Monster } public static class FearState { private static readonly int[] Thresholds = new int[7] { 0, 1, 3, 6, 10, 15, 21 }; private static readonly string[] Names = new string[7] { "Respected", "Well Known", "Feared VIP", "Holy Shit Run!", "The Butcher", "Psychopath", "Monster" }; private static readonly float[] GreenHalves = new float[7] { 0.05f, 0.09f, 0.14f, 0.2f, 0.28f, 0.38f, 0.5f }; public static int Points { get; private set; } public static FearTitle CurrentTitle => TitleFromPoints(Points); public static string CurrentTitleName => NameFor(CurrentTitle); public static string CurrentTitleUpper => NameFor(CurrentTitle).ToUpperInvariant(); public static float GreenHalf => GreenHalfFor(CurrentTitle); public static bool IsMaxed => CurrentTitle == FearTitle.Monster; public static int PointsToNext { get { int currentTitle = (int)CurrentTitle; if (currentTitle >= Thresholds.Length - 1) { return 0; } return Mathf.Max(0, Thresholds[currentTitle + 1] - Points); } } public static FearTitle TitleFromPoints(int points) { FearTitle result = FearTitle.RespectedMan; for (int i = 0; i < Thresholds.Length; i++) { if (points >= Thresholds[i]) { result = (FearTitle)i; } } return result; } public static string NameFor(FearTitle t) { int num = (int)t; if (num < 0) { num = 0; } if (num >= Names.Length) { num = Names.Length - 1; } return Names[num]; } public static float GreenHalfFor(FearTitle t) { int num = (int)t; if (num < 0) { num = 0; } if (num >= GreenHalves.Length) { num = GreenHalves.Length - 1; } return GreenHalves[num]; } public static string TitleUpperFromPoints(int points) { return NameFor(TitleFromPoints(points)).ToUpperInvariant(); } public static string TitleNameFromPoints(int points) { return NameFor(TitleFromPoints(points)); } public static void AddPoint() { FearTitle currentTitle = CurrentTitle; Points++; FearTitle currentTitle2 = CurrentTitle; NDLog.Info($"[FEAR] +1 fear point ({Points}); title {currentTitle} -> {currentTitle2}."); if (currentTitle2 > currentTitle) { try { DonMessaging.SendDon(PromotionMessage(currentTitle2)); } catch { } } } public static void LoadPoints(int points) { Points = Mathf.Max(0, points); } public static void ResetForSceneReload() { Points = 0; } private static string PromotionMessage(FearTitle t) { return t switch { FearTitle.WellKnown => "People are starting to whisper your name, boss. A well-known man now — the Benzies feel it too. Keep leaning on them.", FearTitle.FearedVip => "Word's getting around. You're a feared man in this town — doors open before you knock. The more of them you break, the louder it gets.", FearTitle.HolyShitRun => "They run when they see you coming now, boss. “Holy shit, run” — that's the new prayer on the street. Beautiful.", FearTitle.TheButcher => "The street's got a name for you: the Butcher. Even our own men keep a respectful distance. Fear like that keeps the books clean.", FearTitle.Psychopath => "They don't call you a man anymore — a psychopath, they say. Good. Let them. Nobody short-changes a psychopath.", FearTitle.Monster => "You're not a man to them now, boss — you're a monster. The biggest names in town lower their eyes. The famiglia has never been feared like this.", _ => "You've earned a new name on the street: " + NameFor(t) + ".", }; } } internal static class Furniture { internal static readonly Color Walnut = Hex("#3A2A1A"); internal static readonly Color WalnutLt = Hex("#5A4226"); internal static readonly Color Burgundy = Hex("#5A1A1F"); internal static readonly Color BurgDark = Hex("#3E1115"); internal static readonly Color Cream = Hex("#E3DCCB"); internal static readonly Color Gold = Hex("#C9A227"); internal static readonly Color Brass = Hex("#9C7A33"); internal static readonly Color Leather = Hex("#22201E"); internal static readonly Color LeatherLt = Hex("#3A332C"); internal static readonly Color Steel = Hex("#5C6066"); internal static readonly Color SteelDark = Hex("#34383D"); internal static readonly Color Screen = Hex("#0B0E12"); internal static readonly Color Green = Hex("#2E5A36"); internal static readonly Color GreenDark = Hex("#1E3E24"); internal static readonly Color CrateWood = Hex("#6E4A28"); internal static readonly Color CrateEdge = Hex("#4A3018"); internal static readonly Color CrateLt = Hex("#865E36"); internal static readonly Color BarrelRust = Hex("#7A3B2A"); internal static readonly Color BarrelBlue = Hex("#2E5A78"); internal static readonly Color Tarp = Hex("#39463A"); internal static readonly Color Concrete = Hex("#43464B"); internal static Color Hex(string hex) { //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) //IL_000d: 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_002d: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (ColorUtility.TryParseHtmlString(hex, ref result)) { return result; } return new Color(0.5f, 0.5f, 0.5f, 1f); } internal static GameObject Box(Transform parent, string name, Vector3 localPos, Vector3 size, Color color, bool keepCollider = false) { //IL_0004: 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_0006: 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) return Prim((PrimitiveType)3, parent, name, localPos, size, Quaternion.identity, color, keepCollider); } internal static GameObject Cyl(Transform parent, string name, Vector3 localPos, float diameter, float height, Color color, bool keepCollider = false) { //IL_0004: 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_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) return Prim((PrimitiveType)2, parent, name, localPos, new Vector3(diameter, height * 0.5f, diameter), Quaternion.identity, color, keepCollider); } internal static GameObject Sphere(Transform parent, string name, Vector3 localPos, float diameter, Color color, bool keepCollider = false) { //IL_0004: 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_0012: Unknown result type (might be due to invalid IL or missing references) return Prim((PrimitiveType)0, parent, name, localPos, new Vector3(diameter, diameter, diameter), Quaternion.identity, color, keepCollider); } private static GameObject Prim(PrimitiveType type, Transform parent, string name, Vector3 localPos, Vector3 scale, Quaternion localRot, Color color, bool keepCollider) { //IL_0004: 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_003f: 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_0085: Unknown result type (might be due to invalid IL or missing references) GameObject val = null; try { val = GameObject.CreatePrimitive(type); ((Object)val).name = name; if ((Object)(object)parent != (Object)null) { val.transform.SetParent(parent, false); } val.transform.localPosition = localPos; val.transform.localRotation = localRot; val.transform.localScale = scale; if (!keepCollider) { try { Collider component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } catch { } } PropVisuals.ApplyFlat(val, color); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Prim " + name + ": " + ex.Message); } return val; } internal static GameObject Group(Transform roomRoot, string name, Vector3 localPos, float yaw) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0027: 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_0050: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); if ((Object)(object)roomRoot != (Object)null) { val.transform.SetParent(roomRoot, false); } val.transform.localPosition = localPos; val.transform.localRotation = Quaternion.Euler(0f, yaw, 0f); val.transform.localScale = Vector3.one; return val; } internal static void PointLight(Transform parent, Vector3 localPos, Color color, float intensity, float range) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_002c: 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) try { GameObject val = new GameObject("Glow"); if ((Object)(object)parent != (Object)null) { val.transform.SetParent(parent, false); } val.transform.localPosition = localPos; Light val2 = val.AddComponent(); val2.type = (LightType)2; val2.color = color; val2.intensity = intensity; val2.range = range; val2.shadows = (LightShadows)0; } catch { } } internal static void Sofa(Transform root, Vector3 pos, float yaw, Color body) { //IL_0008: 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) //IL_003e: 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) //IL_0060: 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_0096: 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_00af: 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_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_0118: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_017f: 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_01b9: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Sofa", pos, yaw).transform; Box(transform, "Base", new Vector3(0f, 0.22f, 0f), new Vector3(2.4f, 0.4f, 0.95f), body); Box(transform, "Back", new Vector3(0f, 0.62f, -0.4f), new Vector3(2.4f, 0.8f, 0.18f), body); Box(transform, "ArmL", new Vector3(-1.15f, 0.45f, 0f), new Vector3(0.22f, 0.55f, 0.95f), body); Box(transform, "ArmR", new Vector3(1.15f, 0.45f, 0f), new Vector3(0.22f, 0.55f, 0.95f), body); for (int i = -1; i <= 1; i++) { Box(transform, $"SeatCushion{i}", new Vector3((float)i * 0.78f, 0.46f, 0.05f), new Vector3(0.72f, 0.14f, 0.78f), Lighten(body, 0.06f)); Box(transform, $"BackCushion{i}", new Vector3((float)i * 0.78f, 0.7f, -0.3f), new Vector3(0.72f, 0.5f, 0.16f), Lighten(body, 0.1f)); } Box(transform, "FootL", new Vector3(-1f, 0.04f, 0.35f), new Vector3(0.1f, 0.08f, 0.1f), Walnut); Box(transform, "FootR", new Vector3(1f, 0.04f, 0.35f), new Vector3(0.1f, 0.08f, 0.1f), Walnut); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Sofa: " + ex.Message); } } internal static void Armchair(Transform root, Vector3 pos, float yaw, Color body) { //IL_0008: 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) //IL_003e: 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) //IL_0060: 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_0096: 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_00af: 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_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_0102: 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_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) try { Transform transform = Group(root, "Furn_Armchair", pos, yaw).transform; Box(transform, "Base", new Vector3(0f, 0.22f, 0f), new Vector3(0.95f, 0.4f, 0.9f), body); Box(transform, "Back", new Vector3(0f, 0.62f, -0.38f), new Vector3(0.95f, 0.78f, 0.16f), body); Box(transform, "ArmL", new Vector3(-0.48f, 0.45f, 0f), new Vector3(0.16f, 0.52f, 0.9f), body); Box(transform, "ArmR", new Vector3(0.48f, 0.45f, 0f), new Vector3(0.16f, 0.52f, 0.9f), body); Box(transform, "Cushion", new Vector3(0f, 0.46f, 0.05f), new Vector3(0.72f, 0.14f, 0.74f), Lighten(body, 0.07f)); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Armchair: " + ex.Message); } } internal static void CoffeeTable(Transform root, Vector3 pos, float yaw) { //IL_0008: 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) //IL_003e: 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) //IL_0064: 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_009e: 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_00ce: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_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) try { Transform transform = Group(root, "Furn_CoffeeTable", pos, yaw).transform; Box(transform, "Frame", new Vector3(0f, 0.18f, 0f), new Vector3(1.3f, 0.36f, 0.7f), Walnut); Box(transform, "Top", new Vector3(0f, 0.4f, 0f), new Vector3(1.45f, 0.05f, 0.82f), Gold); Cyl(transform, "Decanter", new Vector3(-0.3f, 0.52f, 0f), 0.12f, 0.22f, BurgDark); Cyl(transform, "GlassA", new Vector3(0.1f, 0.47f, 0.12f), 0.06f, 0.08f, Cream); Cyl(transform, "GlassB", new Vector3(0.25f, 0.47f, -0.1f), 0.06f, 0.08f, Cream); Box(transform, "Box", new Vector3(0.35f, 0.46f, 0.18f), new Vector3(0.22f, 0.08f, 0.16f), Leather); } catch (Exception ex) { NDLog.DebugWarn("[FURN] CoffeeTable: " + ex.Message); } } internal static void Rug(Transform root, Vector3 pos, float yaw, float sizeX, float sizeZ) { //IL_0008: 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) //IL_0037: 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_005d: 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) //IL_009c: 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_00c6: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Rug", pos, yaw).transform; Box(transform, "Border", new Vector3(0f, 0.012f, 0f), new Vector3(sizeX, 0.02f, sizeZ), Brass); Box(transform, "Field", new Vector3(0f, 0.02f, 0f), new Vector3(sizeX - 0.4f, 0.02f, sizeZ - 0.4f), Burgundy); Box(transform, "Medallion", new Vector3(0f, 0.026f, 0f), new Vector3((sizeX - 0.4f) * 0.45f, 0.02f, (sizeZ - 0.4f) * 0.45f), BurgDark); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Rug: " + ex.Message); } } internal static void BarCounter(Transform root, Vector3 pos, float yaw, float length) { //IL_0008: 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) //IL_003a: 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_0060: 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) //IL_009c: 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) //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_00ed: 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_011e: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_0180: 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_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_01c5: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: 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_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: 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_0209: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Bar", pos, yaw).transform; Box(transform, "Body", new Vector3(0f, 0.55f, 0f), new Vector3(0.7f, 1.1f, length), Walnut); Box(transform, "Front", new Vector3(0.33f, 0.55f, 0f), new Vector3(0.06f, 1f, length - 0.1f), Gold); Box(transform, "Top", new Vector3(0f, 1.13f, 0f), new Vector3(0.85f, 0.06f, length + 0.2f), Cream); Box(transform, "FootRail", new Vector3(0.42f, 0.12f, 0f), new Vector3(0.05f, 0.05f, length), Brass); Box(transform, "BackShelf", new Vector3(-0.42f, 1.4f, 0f), new Vector3(0.12f, 1.6f, length), WalnutLt); Box(transform, "Shelf1", new Vector3(-0.34f, 1.05f, 0f), new Vector3(0.22f, 0.04f, length - 0.2f), Walnut); Box(transform, "Shelf2", new Vector3(-0.34f, 1.55f, 0f), new Vector3(0.22f, 0.04f, length - 0.2f), Walnut); Color[] array = (Color[])(object)new Color[6] { Hex("#1E3A2E"), Hex("#3E1E12"), Hex("#5A1A1F"), Hex("#22303E"), Cream, Hex("#2A2A2A") }; int num = Mathf.Max(3, Mathf.FloorToInt(length / 0.28f)); for (int i = 0; i < num; i++) { float num2 = (0f - length) * 0.5f + 0.2f + (float)i * (length - 0.4f) / (float)Mathf.Max(1, num - 1); float num3 = ((i % 2 == 0) ? 1.2f : 1.7f); Cyl(transform, $"Bottle{i}", new Vector3(-0.34f, num3, num2), 0.07f, 0.26f, array[i % array.Length]); } } catch (Exception ex) { NDLog.DebugWarn("[FURN] BarCounter: " + ex.Message); } } internal static void BarStool(Transform root, Vector3 pos, float yaw) { //IL_0008: 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) //IL_0039: 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_0069: 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_0099: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Stool", pos, yaw).transform; Cyl(transform, "Seat", new Vector3(0f, 0.78f, 0f), 0.36f, 0.1f, Leather); Cyl(transform, "Pole", new Vector3(0f, 0.4f, 0f), 0.07f, 0.74f, Brass); Cyl(transform, "Foot", new Vector3(0f, 0.04f, 0f), 0.42f, 0.06f, SteelDark); } catch (Exception ex) { NDLog.DebugWarn("[FURN] BarStool: " + ex.Message); } } internal static void DiningTable(Transform root, Vector3 pos, float yaw, float length, float width) { //IL_0008: 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) //IL_0037: 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_005d: 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) //IL_00b3: 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_00cc: 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_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_0119: 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_014b: 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_0164: 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_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: 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_01f6: 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) try { Transform transform = Group(root, "Furn_Table", pos, yaw).transform; Box(transform, "Top", new Vector3(0f, 0.76f, 0f), new Vector3(width, 0.08f, length), WalnutLt); Box(transform, "Apron", new Vector3(0f, 0.66f, 0f), new Vector3(width - 0.2f, 0.14f, length - 0.2f), Walnut); float num = width * 0.5f - 0.18f; float num2 = length * 0.5f - 0.25f; Box(transform, "Leg1", new Vector3(0f - num, 0.36f, 0f - num2), new Vector3(0.12f, 0.72f, 0.12f), Walnut); Box(transform, "Leg2", new Vector3(num, 0.36f, 0f - num2), new Vector3(0.12f, 0.72f, 0.12f), Walnut); Box(transform, "Leg3", new Vector3(0f - num, 0.36f, num2), new Vector3(0.12f, 0.72f, 0.12f), Walnut); Box(transform, "Leg4", new Vector3(num, 0.36f, num2), new Vector3(0.12f, 0.72f, 0.12f), Walnut); Box(transform, "Runner", new Vector3(0f, 0.805f, 0f), new Vector3(0.4f, 0.02f, length - 0.6f), Burgundy); Cyl(transform, "Candle1", new Vector3(0f, 0.86f, (0f - length) * 0.25f), 0.05f, 0.18f, Cream); Cyl(transform, "Candle2", new Vector3(0f, 0.86f, length * 0.25f), 0.05f, 0.18f, Cream); } catch (Exception ex) { NDLog.DebugWarn("[FURN] DiningTable: " + ex.Message); } } internal static void Chair(Transform root, Vector3 pos, float yaw) { //IL_0008: 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) //IL_003e: 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) //IL_0064: 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_009e: 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) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //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) try { Transform transform = Group(root, "Furn_Chair", pos, yaw).transform; Box(transform, "Seat", new Vector3(0f, 0.46f, 0f), new Vector3(0.44f, 0.08f, 0.44f), Burgundy); Box(transform, "Back", new Vector3(0f, 0.74f, -0.18f), new Vector3(0.44f, 0.56f, 0.08f), Walnut); Box(transform, "Leg1", new Vector3(-0.18f, 0.23f, -0.18f), new Vector3(0.06f, 0.46f, 0.06f), Walnut); Box(transform, "Leg2", new Vector3(0.18f, 0.23f, -0.18f), new Vector3(0.06f, 0.46f, 0.06f), Walnut); Box(transform, "Leg3", new Vector3(-0.18f, 0.23f, 0.18f), new Vector3(0.06f, 0.46f, 0.06f), Walnut); Box(transform, "Leg4", new Vector3(0.18f, 0.23f, 0.18f), new Vector3(0.06f, 0.46f, 0.06f), Walnut); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Chair: " + ex.Message); } } internal static void Bookshelf(Transform root, Vector3 pos, float yaw) { //IL_0008: 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_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_0078: 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_0089: 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_00ba: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0114: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0156: 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_0167: 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_0173: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0272: 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_0294: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Bookshelf", pos, yaw).transform; float num = 1.8f; float num2 = 2.2f; float num3 = 0.4f; Box(transform, "Back", new Vector3(0f, num2 * 0.5f, (0f - num3) * 0.5f), new Vector3(num, num2, 0.06f), Walnut); Box(transform, "SideL", new Vector3((0f - num) * 0.5f, num2 * 0.5f, 0f), new Vector3(0.08f, num2, num3), Walnut); Box(transform, "SideR", new Vector3(num * 0.5f, num2 * 0.5f, 0f), new Vector3(0.08f, num2, num3), Walnut); Box(transform, "Bottom", new Vector3(0f, 0.05f, 0f), new Vector3(num, 0.1f, num3), Walnut); Box(transform, "Topb", new Vector3(0f, num2 - 0.05f, 0f), new Vector3(num, 0.1f, num3), Walnut); Color[] array = (Color[])(object)new Color[7] { Burgundy, Hex("#1E3A2E"), Walnut, Hex("#22303E"), BurgDark, Gold, Cream }; for (int i = 0; i < 4; i++) { float num4 = 0.4f + (float)i * 0.5f; Box(transform, $"Shelf{i}", new Vector3(0f, num4 - 0.05f, 0f), new Vector3(num - 0.16f, 0.04f, num3 - 0.06f), WalnutLt); int num5 = 9; for (int j = 0; j < num5; j++) { float num6 = (0f - num) * 0.5f + 0.2f + (float)j * (num - 0.4f) / (float)(num5 - 1); float num7 = 0.28f + (float)((j * 7 + i * 3) % 5) * 0.03f; Box(transform, $"Book{i}_{j}", new Vector3(num6, num4 + num7 * 0.5f, 0f), new Vector3(0.07f, num7, 0.22f), array[(j + i) % array.Length]); } } } catch (Exception ex) { NDLog.DebugWarn("[FURN] Bookshelf: " + ex.Message); } } internal static void Fireplace(Transform root, Vector3 pos, float yaw) { //IL_0008: 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_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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_0140: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: 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) try { Transform transform = Group(root, "Furn_Fireplace", pos, yaw).transform; float num = 1.8f; float num2 = 1.5f; float num3 = 0.5f; Box(transform, "Surround", new Vector3(0f, num2 * 0.5f, 0f), new Vector3(num, num2, num3), Cream); Box(transform, "Cavity", new Vector3(0f, 0.65f, 0.06f), new Vector3(num - 0.6f, 0.9f, num3), Screen); Box(transform, "Mantel", new Vector3(0f, num2 + 0.05f, 0.05f), new Vector3(num + 0.3f, 0.14f, num3 + 0.2f), WalnutLt); Box(transform, "Hearth", new Vector3(0f, 0.05f, 0.2f), new Vector3(num + 0.1f, 0.1f, num3 + 0.3f), SteelDark); Box(transform, "Logs", new Vector3(0f, 0.28f, 0.12f), new Vector3(0.7f, 0.16f, 0.25f), Hex("#3A1E10")); Box(transform, "Embers", new Vector3(0f, 0.3f, 0.12f), new Vector3(0.55f, 0.1f, 0.18f), Hex("#D4501E")); PointLight(((Component)transform).transform, new Vector3(0f, 0.4f, 0.2f), Hex("#FF7A2A"), 1.4f, 4.5f); Cyl(transform, "Vase", new Vector3(-0.6f, num2 + 0.22f, 0.05f), 0.14f, 0.28f, Gold); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Fireplace: " + ex.Message); } } internal static void WallTV(Transform root, Vector3 pos, float yaw, float w, float h) { //IL_0008: 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) //IL_0043: 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_0069: 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) //IL_009c: 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) try { Transform transform = Group(root, "Furn_TV", pos, yaw).transform; Box(transform, "Frame", new Vector3(0f, 0f, -0.02f), new Vector3(w + 0.1f, h + 0.1f, 0.08f), Leather); Box(transform, "Screen", new Vector3(0f, 0f, 0.04f), new Vector3(w, h, 0.02f), Screen); PointLight(((Component)transform).transform, new Vector3(0f, 0f, 0.4f), Hex("#2E4A6E"), 0.5f, 3f); } catch (Exception ex) { NDLog.DebugWarn("[FURN] WallTV: " + ex.Message); } } internal static void Sideboard(Transform root, Vector3 pos, float yaw) { //IL_0008: 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) //IL_003e: 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) //IL_0064: 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_009e: 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) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //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) try { Transform transform = Group(root, "Furn_Sideboard", pos, yaw).transform; Box(transform, "Body", new Vector3(0f, 0.35f, 0f), new Vector3(2.2f, 0.6f, 0.5f), Walnut); Box(transform, "Top", new Vector3(0f, 0.67f, 0f), new Vector3(2.3f, 0.05f, 0.55f), Gold); Box(transform, "DoorL", new Vector3(-0.55f, 0.35f, 0.26f), new Vector3(1f, 0.5f, 0.02f), WalnutLt); Box(transform, "DoorR", new Vector3(0.55f, 0.35f, 0.26f), new Vector3(1f, 0.5f, 0.02f), WalnutLt); Box(transform, "HandleL", new Vector3(-0.1f, 0.35f, 0.28f), new Vector3(0.04f, 0.16f, 0.03f), Brass); Box(transform, "HandleR", new Vector3(0.1f, 0.35f, 0.28f), new Vector3(0.04f, 0.16f, 0.03f), Brass); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Sideboard: " + ex.Message); } } internal static void WallArt(Transform root, Vector3 pos, float yaw, float w, float h, Color canvas) { //IL_0008: 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) //IL_0043: 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_0069: 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 { Transform transform = Group(root, "Furn_Art", pos, yaw).transform; Box(transform, "Frame", new Vector3(0f, 0f, 0f), new Vector3(w + 0.12f, h + 0.12f, 0.05f), Gold); Box(transform, "Canvas", new Vector3(0f, 0f, 0.03f), new Vector3(w, h, 0.02f), canvas); } catch (Exception ex) { NDLog.DebugWarn("[FURN] WallArt: " + ex.Message); } } internal static void Chandelier(Transform root, Vector3 pos) { //IL_0008: 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_003d: 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_0068: 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_0111: 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_0153: 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) try { Transform transform = Group(root, "Furn_Chandelier", pos, 0f).transform; Cyl(transform, "Chain", new Vector3(0f, 0.25f, 0f), 0.04f, 0.5f, Brass); Sphere(transform, "Body", new Vector3(0f, 0f, 0f), 0.3f, Gold); int num = 6; for (int i = 0; i < num; i++) { float num2 = (float)i * (float)Math.PI * 2f / (float)num; float num3 = Mathf.Cos(num2) * 0.35f; float num4 = Mathf.Sin(num2) * 0.35f; Box(transform, $"Arm{i}", new Vector3(num3 * 0.5f, -0.05f, num4 * 0.5f), new Vector3(0.05f, 0.05f, 0.05f), Brass); Sphere(transform, $"Bulb{i}", new Vector3(num3, -0.1f, num4), 0.12f, Hex("#FFE7A8")); } PointLight(((Component)transform).transform, new Vector3(0f, -0.2f, 0f), Hex("#FFE3B0"), 2f, 14f); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Chandelier: " + ex.Message); } } internal static void PottedPlant(Transform root, Vector3 pos) { //IL_0008: 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_0042: 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_0072: 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_009d: 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_00c8: 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) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Plant", pos, 0f).transform; Cyl(transform, "Pot", new Vector3(0f, 0.25f, 0f), 0.45f, 0.5f, Hex("#2A2A2C")); Cyl(transform, "PotRim", new Vector3(0f, 0.5f, 0f), 0.5f, 0.06f, SteelDark); Sphere(transform, "Foliage1", new Vector3(0f, 0.95f, 0f), 0.7f, Green); Sphere(transform, "Foliage2", new Vector3(0.18f, 1.25f, 0.1f), 0.5f, GreenDark); Sphere(transform, "Foliage3", new Vector3(-0.15f, 1.2f, -0.12f), 0.45f, Green); Cyl(transform, "Trunk", new Vector3(0f, 0.6f, 0f), 0.08f, 0.5f, Walnut); } catch (Exception ex) { NDLog.DebugWarn("[FURN] PottedPlant: " + ex.Message); } } internal static void FloorLamp(Transform root, Vector3 pos) { //IL_0008: 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_003d: 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_006d: 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_009d: 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_00c8: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_FloorLamp", pos, 0f).transform; Cyl(transform, "Base", new Vector3(0f, 0.04f, 0f), 0.36f, 0.08f, SteelDark); Cyl(transform, "Pole", new Vector3(0f, 0.85f, 0f), 0.05f, 1.6f, Brass); Cyl(transform, "Shade", new Vector3(0f, 1.7f, 0f), 0.5f, 0.35f, Cream); PointLight(((Component)transform).transform, new Vector3(0f, 1.6f, 0f), Hex("#FFE7C2"), 1f, 6f); } catch (Exception ex) { NDLog.DebugWarn("[FURN] FloorLamp: " + ex.Message); } } internal static void Crate(Transform parent, string name, Vector3 localPos, float yaw, float size, Color wood) { //IL_0004: 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_003a: 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_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_008c: 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_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_00ef: 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) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(parent, name, localPos, yaw).transform; Box(transform, "Body", new Vector3(0f, size * 0.5f, 0f), new Vector3(size, size, size), wood); float num = size * 0.5f; Box(transform, "EdgeFL", new Vector3(0f - num, size * 0.5f, num), new Vector3(0.06f, size, 0.06f), CrateEdge); Box(transform, "EdgeFR", new Vector3(num, size * 0.5f, num), new Vector3(0.06f, size, 0.06f), CrateEdge); Box(transform, "EdgeBL", new Vector3(0f - num, size * 0.5f, 0f - num), new Vector3(0.06f, size, 0.06f), CrateEdge); Box(transform, "EdgeBR", new Vector3(num, size * 0.5f, 0f - num), new Vector3(0.06f, size, 0.06f), CrateEdge); GameObject val = Box(transform, "Plank", new Vector3(0f, size * 0.5f, num + 0.005f), new Vector3(size * 1.3f, 0.08f, 0.03f), CrateEdge); if ((Object)(object)val != (Object)null) { val.transform.localRotation = Quaternion.Euler(0f, 0f, 35f); } } catch (Exception ex) { NDLog.DebugWarn("[FURN] Crate: " + ex.Message); } } internal static void CrateStack(Transform root, Vector3 pos, float yaw) { //IL_0008: 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_001d: 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_003f: 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_0054: 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_0076: 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) //IL_009c: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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) try { Crate(root, "Stack_A0", pos + new Vector3(0f, 0f, 0f), yaw + 8f, 0.85f, CrateWood); Crate(root, "Stack_A1", pos + new Vector3(0.9f, 0f, 0.1f), yaw - 12f, 0.7f, CrateLt); Crate(root, "Stack_A2", pos + new Vector3(0.1f, 0.85f, 0.05f), yaw + 20f, 0.65f, CrateWood); Crate(root, "Stack_A3", pos + new Vector3(0.85f, 0.7f, 0f), yaw, 0.55f, CrateLt); } catch (Exception ex) { NDLog.DebugWarn("[FURN] CrateStack: " + ex.Message); } } internal static void PalletRack(Transform root, Vector3 pos, float yaw, float width) { //IL_0008: 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) //IL_0053: 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_0079: 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_0093: 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_00c1: 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_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_0102: 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_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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: 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_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: 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_030b: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Rack", pos, yaw).transform; float num = 2.6f; float num2 = 0.9f; float num3 = width * 0.5f; float num4 = num2 * 0.5f; Box(transform, "PostFL", new Vector3(0f - num3, num * 0.5f, num4), new Vector3(0.1f, num, 0.1f), Hex("#B5651D")); Box(transform, "PostFR", new Vector3(num3, num * 0.5f, num4), new Vector3(0.1f, num, 0.1f), Hex("#B5651D")); Box(transform, "PostBL", new Vector3(0f - num3, num * 0.5f, 0f - num4), new Vector3(0.1f, num, 0.1f), Hex("#B5651D")); Box(transform, "PostBR", new Vector3(num3, num * 0.5f, 0f - num4), new Vector3(0.1f, num, 0.1f), Hex("#B5651D")); float[] array = new float[3] { 0.05f, 1f, 1.9f }; for (int i = 0; i < array.Length; i++) { float num5 = array[i]; Box(transform, $"BeamF{i}", new Vector3(0f, num5, num4), new Vector3(width, 0.08f, 0.08f), Steel); Box(transform, $"BeamB{i}", new Vector3(0f, num5, 0f - num4), new Vector3(width, 0.08f, 0.08f), Steel); Box(transform, $"Deck{i}", new Vector3(0f, num5 + 0.02f, 0f), new Vector3(width - 0.1f, 0.04f, num2 - 0.05f), SteelDark); if (i >= 2) { continue; } int num6 = Mathf.Max(2, Mathf.FloorToInt(width / 0.95f)); for (int j = 0; j < num6; j++) { float num7 = (0f - width) * 0.5f + 0.55f + (float)j * (width - 1.1f) / (float)Mathf.Max(1, num6 - 1); if ((j + i) % 3 == 0) { Crate(transform, $"L{i}Crate{j}", new Vector3(num7, num5 + 0.06f, 0f), j * 17 % 30 - 15, 0.7f, (j % 2 == 0) ? CrateWood : CrateLt); } else { Box(transform, $"L{i}Box{j}", new Vector3(num7, num5 + 0.32f, 0f), new Vector3(0.6f, 0.5f, 0.6f), (j % 2 == 0) ? Hex("#8A6A3A") : Hex("#6A5230")); } } } } catch (Exception ex) { NDLog.DebugWarn("[FURN] PalletRack: " + ex.Message); } } internal static void Barrel(Transform parent, string name, Vector3 localPos, Color color) { //IL_0004: 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) //IL_0039: 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_0065: 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_0095: 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_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) try { Transform transform = Group(parent, name, localPos, 0f).transform; Cyl(transform, "Body", new Vector3(0f, 0.45f, 0f), 0.56f, 0.9f, color); Cyl(transform, "Band1", new Vector3(0f, 0.25f, 0f), 0.6f, 0.06f, SteelDark); Cyl(transform, "Band2", new Vector3(0f, 0.65f, 0f), 0.6f, 0.06f, SteelDark); Cyl(transform, "Top", new Vector3(0f, 0.9f, 0f), 0.56f, 0.04f, Lighten(color, -0.1f)); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Barrel: " + ex.Message); } } internal static void BarrelCluster(Transform root, Vector3 pos) { //IL_0007: 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_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_0032: 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_005d: 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_0077: Unknown result type (might be due to invalid IL or missing references) Barrel(root, "Barrel_A", pos + new Vector3(0f, 0f, 0f), BarrelRust); Barrel(root, "Barrel_B", pos + new Vector3(0.62f, 0f, 0.1f), BarrelBlue); Barrel(root, "Barrel_C", pos + new Vector3(0.32f, 0f, -0.5f), BarrelRust); } internal static void Workbench(Transform root, Vector3 pos, float yaw) { //IL_0008: 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) //IL_003e: 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) //IL_0064: 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_009e: 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) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0112: 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_0151: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: 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_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: 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_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Workbench", pos, yaw).transform; Box(transform, "Top", new Vector3(0f, 0.9f, 0f), new Vector3(2f, 0.08f, 0.7f), WalnutLt); Box(transform, "Apron", new Vector3(0f, 0.78f, -0.25f), new Vector3(2f, 0.2f, 0.1f), Walnut); Box(transform, "LegL", new Vector3(-0.9f, 0.45f, 0f), new Vector3(0.1f, 0.9f, 0.6f), SteelDark); Box(transform, "LegR", new Vector3(0.9f, 0.45f, 0f), new Vector3(0.1f, 0.9f, 0.6f), SteelDark); Box(transform, "Pegboard", new Vector3(0f, 1.7f, -0.34f), new Vector3(2f, 1.2f, 0.04f), Hex("#7A5A2E")); Box(transform, "Tool1", new Vector3(-0.6f, 1.7f, -0.31f), new Vector3(0.08f, 0.4f, 0.04f), Steel); Box(transform, "Tool2", new Vector3(-0.3f, 1.75f, -0.31f), new Vector3(0.3f, 0.08f, 0.04f), SteelDark); Box(transform, "Tool3", new Vector3(0.2f, 1.7f, -0.31f), new Vector3(0.12f, 0.32f, 0.04f), Steel); Box(transform, "Vice", new Vector3(0.7f, 1f, 0.2f), new Vector3(0.2f, 0.16f, 0.16f), SteelDark); Box(transform, "Toolbox", new Vector3(-0.6f, 1.02f, 0.05f), new Vector3(0.4f, 0.18f, 0.24f), Hex("#A11E1E")); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Workbench: " + ex.Message); } } internal static void WeaponsCase(Transform parent, string name, Vector3 localPos, float yaw) { //IL_0004: 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_003a: 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_0065: 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_009f: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0113: 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) try { Transform transform = Group(parent, name, localPos, yaw).transform; Box(transform, "Case", new Vector3(0f, 0.09f, 0f), new Vector3(1.1f, 0.18f, 0.5f), Hex("#1C1C1E")); Box(transform, "Lid", new Vector3(0f, 0.18f, 0f), new Vector3(1.12f, 0.03f, 0.52f), SteelDark); Box(transform, "Latch1", new Vector3(-0.3f, 0.12f, 0.26f), new Vector3(0.1f, 0.08f, 0.03f), Steel); Box(transform, "Latch2", new Vector3(0.3f, 0.12f, 0.26f), new Vector3(0.1f, 0.08f, 0.03f), Steel); Box(transform, "Handle", new Vector3(0f, 0.2f, 0.26f), new Vector3(0.24f, 0.04f, 0.04f), Steel); } catch (Exception ex) { NDLog.DebugWarn("[FURN] WeaponsCase: " + ex.Message); } } internal static void Safe(Transform root, Vector3 pos, float yaw) { //IL_0008: 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) //IL_003e: 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_0069: 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_0087: 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_00b7: 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_00e7: 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_011c: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = Group(root, "Furn_Safe", pos, yaw).transform; Box(transform, "Body", new Vector3(0f, 0.55f, 0f), new Vector3(0.8f, 1.1f, 0.8f), Hex("#26282C")); Box(transform, "Door", new Vector3(0f, 0.55f, 0.41f), new Vector3(0.66f, 0.92f, 0.04f), Hex("#34373C")); Cyl(transform, "Dial", new Vector3(0.12f, 0.55f, 0.45f), 0.2f, 0.06f, Steel); Cyl(transform, "DialPin", new Vector3(0.12f, 0.55f, 0.5f), 0.04f, 0.05f, SteelDark); Box(transform, "Handle", new Vector3(-0.18f, 0.55f, 0.46f), new Vector3(0.06f, 0.3f, 0.06f), Steel); Box(transform, "Feet", new Vector3(0f, 0.03f, 0f), new Vector3(0.82f, 0.06f, 0.82f), Hex("#1A1B1D")); } catch (Exception ex) { NDLog.DebugWarn("[FURN] Safe: " + ex.Message); } } internal static void HangingLamp(Transform root, Vector3 pos, float ceilingY) { //IL_0008: 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_003f: 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_0074: 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_00a9: 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_00d9: 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_0109: 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) try { Transform transform = Group(root, "Furn_HangingLamp", new Vector3(pos.x, ceilingY, pos.z), 0f).transform; Cyl(transform, "Cord", new Vector3(0f, -0.3f, 0f), 0.03f, 0.6f, Hex("#1A1A1A")); Cyl(transform, "Shade", new Vector3(0f, -0.66f, 0f), 0.5f, 0.22f, Hex("#2A2D31")); Cyl(transform, "ShadeRim", new Vector3(0f, -0.76f, 0f), 0.58f, 0.04f, SteelDark); Sphere(transform, "Bulb", new Vector3(0f, -0.74f, 0f), 0.16f, Hex("#FFF0C0")); PointLight(((Component)transform).transform, new Vector3(0f, -0.8f, 0f), Hex("#FFE9C0"), 1.3f, 7f); } catch (Exception ex) { NDLog.DebugWarn("[FURN] HangingLamp: " + ex.Message); } } internal static void TarpPile(Transform root, Vector3 pos, float yaw) { //IL_0008: 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) //IL_003e: 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) //IL_0091: 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_00aa: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) try { Transform transform = Group(root, "Furn_TarpPile", pos, yaw).transform; GameObject val = Box(transform, "Lump1", new Vector3(0f, 0.45f, 0f), new Vector3(1.4f, 0.9f, 1f), Tarp); if ((Object)(object)val != (Object)null) { val.transform.localRotation = Quaternion.Euler(4f, 0f, 6f); } GameObject val2 = Box(transform, "Lump2", new Vector3(0.5f, 0.35f, 0.3f), new Vector3(0.9f, 0.7f, 0.8f), Lighten(Tarp, -0.05f)); if ((Object)(object)val2 != (Object)null) { val2.transform.localRotation = Quaternion.Euler(-6f, 12f, -4f); } GameObject val3 = Box(transform, "Lump3", new Vector3(-0.45f, 0.3f, -0.2f), new Vector3(0.8f, 0.6f, 0.7f), Lighten(Tarp, 0.05f)); if ((Object)(object)val3 != (Object)null) { val3.transform.localRotation = Quaternion.Euler(8f, -10f, 5f); } } catch (Exception ex) { NDLog.DebugWarn("[FURN] TarpPile: " + ex.Message); } } private static Color Lighten(Color c, float by) { //IL_0001: 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_001b: 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_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_0036: Unknown result type (might be due to invalid IL or missing references) return new Color(Mathf.Clamp01(c.r + by), Mathf.Clamp01(c.g + by), Mathf.Clamp01(c.b + by), c.a); } } internal static class GangBattleManager { private enum State { Idle, Pending, Faceoff, Combat } private const int CREW_SIZE = 4; private const int BENZIE_SIZE = 4; private const int POOL_RESERVE = 1; private const float ARRIVE_RADIUS = 6f; private const float FACEOFF_SECS = 3f; private const float BATTLE_DURATION = 240f; private const float RETARGET_INTERVAL = 1.5f; private const float GOON_GIVE_UP = 1000f; private const float VAN_DISTANCE = 16f; private const float DEAL_MIN_DIST = 60f; private const float DEAL_MAX_DIST = 130f; private const float RESULT_BANNER_SECS = 6f; private static readonly EQuality LOOT_QUALITY = (EQuality)4; private static State _state = State.Idle; private static readonly Random _rng = new Random(); private static string _dealPlace = "the docks"; private static string _dealTime = "midnight"; private static Vector3 _arena; private static Vector3 _battleAxis = Vector3.forward; private static Vector3 _playerSpot; private static Vector3 _vanSpot; private static GameObject _blueBox; private static float _faceoffLeft; private static float _battleEndsAt; private static float _retargetCd; private static float _pendingMoveCd; private static GoonPool _pool; private static readonly List _crew = new List(); private static readonly List _crewDefaults = new List(); private static readonly List _benzies = new List(); private static readonly List _benzieDefaults = new List(); private static readonly List _guardSlots = new List(); private static LandVehicle _van; private static string _vanGuid; private static string _resultBanner; private static float _resultBannerLeft; private static GUIStyle _bigStyle; private static GUIStyle _smallStyle; private static readonly Color GOLD = new Color(0.83f, 0.69f, 0.22f, 0.95f); private static readonly Color RED = new Color(0.92f, 0.26f, 0.22f, 1f); private const float BANNER_Y = 110f; private static string _banner; private static float _bannerLeft; public static bool IsActive => _state != State.Idle; public static bool Setup(string place, string time) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0157: 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_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_017b: 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_01c5: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority) { return false; } if (_state != State.Idle) { DonMessaging.SendDon("We've already got a deal on the board, boss — take that one first."); return false; } if (GangWarManager.IsActive) { DonMessaging.SendDon("Not now, boss — we're in the middle of a war. One fight at a time."); return false; } _pool = Object.FindObjectOfType(true); if ((Object)(object)_pool == (Object)null || _pool.UnspawnedGoonCount <= 2) { DonMessaging.SendDon("The Benzies went to ground before we could move on that tip, boss. Next time."); return false; } Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null) { return false; } if (!TryPickArena(((Component)local).transform.position, out _arena)) { DonMessaging.SendDon("No clean spot to hit them, boss. We'll catch the next shipment."); return false; } _dealPlace = (string.IsNullOrEmpty(place) ? "the docks" : place); _dealTime = (string.IsNullOrEmpty(time) ? "midnight" : time); Vector3 val = _arena - ((Component)local).transform.position; val.y = 0f; _battleAxis = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.forward); SpawnBlueBox(_arena); FaidaMarkerQuest.EnsureCreated("Faida: hit the Benzie deal at " + _dealPlace, _arena); BossMarkerSync.Set("Faida: hit the Benzie deal at " + _dealPlace, _arena); DonMessaging.SendDon("Marker's on your map, boss — the Benzie shipment's at " + _dealPlace + ". Get there and take the van. Our men and the Villa guards roll in with you."); _state = State.Pending; NDLog.Info($"[FAIDA] battle set up @ {_arena} (deal '{_dealPlace}', {_dealTime})."); return true; } catch (Exception ex) { NDLog.Warn("[FAIDA] Setup: " + ex.Message); Cleanup(despawnVan: true); return false; } } public static void Tick(float dt) { if (_resultBannerLeft > 0f) { _resultBannerLeft -= dt; if (_resultBannerLeft <= 0f) { _resultBannerLeft = 0f; _resultBanner = null; } } if (_bannerLeft > 0f) { _bannerLeft -= dt; } if (_state == State.Idle) { return; } if (!SessionGate.IsAuthority) { Cleanup(despawnVan: true); _state = State.Idle; return; } switch (_state) { case State.Pending: TickPending(); break; case State.Faceoff: TickFaceoff(dt); break; case State.Combat: TickCombat(dt); break; } } private static void TickPending() { //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_0053: Unknown result type (might be due to invalid IL or missing references) Player local = Player.Local; if (!((Object)(object)local == (Object)null) && !((Object)(object)((Component)local).transform == (Object)null)) { _pendingMoveCd -= Time.deltaTime; if (_pendingMoveCd <= 0f) { _pendingMoveCd = 1f; FaidaMarkerQuest.MoveTo(_arena); } if (Vector3.Distance(((Component)local).transform.position, _arena) <= 6f) { BeginBattle(); } } } private static void TickFaceoff(float dt) { HoldEveryoneStill(); _faceoffLeft -= dt; if (_faceoffLeft <= 0f) { StartCombat(); } } private static void TickCombat(float dt) { if (Time.time >= _battleEndsAt) { LoseBattle("the Benzies held us off and slipped away with the van"); return; } _retargetCd -= dt; if (_retargetCd > 0f) { return; } _retargetCd = 1.5f; PruneGoons(_crew, _crewDefaults); PruneGoons(_benzies, _benzieDefaults); List list = AliveGoons(_benzies); if (list.Count == 0) { WinBattle(); return; } List list2 = LivePlayerSideTargets(); for (int i = 0; i < _crew.Count; i++) { if (SafeSpawned(_crew[i])) { CartelGoon val = Nearest(_crew[i], list); if ((Object)(object)val != (Object)null) { AttackGoon(_crew[i], val); } } } for (int j = 0; j < _benzies.Count; j++) { if (SafeSpawned(_benzies[j])) { NPC val2 = Nearest(_benzies[j], list2); if ((Object)(object)val2 != (Object)null) { AttackNpc(_benzies[j], val2); } } } for (int k = 0; k < _guardSlots.Count; k++) { int slot = _guardSlots[k]; if (GuardNPC.IsDownOrKO(slot)) { continue; } NPC val3 = GuardNPC.Resolve(slot); if (!((Object)(object)val3 == (Object)null)) { NPC val4 = NearestNpc(val3, list); if ((Object)(object)val4 != (Object)null) { GuardNPC.Engage(slot, val4); } } } } private static void BeginBattle() { //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_0018: 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_0027: 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_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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0063: 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_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_0082: 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_0088: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_0166: Unknown result type (might be due to invalid IL or missing references) try { DestroyBlueBox(); Player local = Player.Local; _playerSpot = _arena; _vanSpot = NavSnap(_arena + _battleAxis * 16f, 8f); Vector3 center = NavSnap(_arena + _battleAxis * 12f, 8f); Vector3 center2 = NavSnap(_arena - _battleAxis * 4f, 8f); float num = YawTowards(_battleAxis); try { MobTeleport.Fade(_playerSpot, false, num); } catch { } if ((Object)(object)_pool == (Object)null) { _pool = Object.FindObjectOfType(true); } int num2 = (((Object)(object)_pool != (Object)null) ? Mathf.Max(0, _pool.UnspawnedGoonCount - 1) : 0); int num3 = num2 / 2; int num4 = Mathf.Clamp(4, 1, Mathf.Max(1, num3)); int requested = Mathf.Clamp(4, 0, Mathf.Max(0, num2 - num4)); SpawnVan(_vanSpot, YawTowards(-_battleAxis)); SpawnSide(_benzies, _benzieDefaults, center, num4, crew: false, YawTowards(-_battleAxis)); SpawnSide(_crew, _crewDefaults, center2, requested, crew: true, num); DeployVillaGuards(center2, num); _faceoffLeft = 3f; _state = State.Faceoff; ShowBanner("FAIDA — FACE OFF", 3.5f); try { Sfx.PlayOneShot("quest-effect", 0.7f); } catch { } DonMessaging.SendDon("There they are, boss — on the van. Three seconds, then we hit them."); NDLog.Debug($"[FAIDA] battle begun: crew={_crew.Count} guards={_guardSlots.Count} benzies={_benzies.Count}."); } catch (Exception ex) { NDLog.Warn("[FAIDA] BeginBattle: " + ex.Message); LoseBattle("something went wrong on the approach"); } } private static void StartCombat() { try { for (int i = 0; i < _crew.Count; i++) { LuckyBrawlManagerMakeReady(_crew[i]); } for (int j = 0; j < _benzies.Count; j++) { LuckyBrawlManagerMakeReady(_benzies[j]); } List list = AliveGoons(_benzies); List list2 = LivePlayerSideTargets(); for (int k = 0; k < _crew.Count; k++) { if (SafeSpawned(_crew[k])) { CartelGoon val = Nearest(_crew[k], list); if ((Object)(object)val != (Object)null) { AttackGoon(_crew[k], val); } } } for (int l = 0; l < _benzies.Count; l++) { if (SafeSpawned(_benzies[l])) { NPC val2 = Nearest(_benzies[l], list2); if ((Object)(object)val2 != (Object)null) { AttackNpc(_benzies[l], val2); } } } for (int m = 0; m < _guardSlots.Count; m++) { int slot = _guardSlots[m]; NPC val3 = GuardNPC.Resolve(slot); if (!((Object)(object)val3 == (Object)null)) { NPC val4 = NearestNpc(val3, list); if ((Object)(object)val4 != (Object)null) { GuardNPC.Engage(slot, val4); } } } _battleEndsAt = Time.time + 240f; _retargetCd = 1.5f; _state = State.Combat; ShowBanner("FAIDA — TAKE THE VAN", 3.5f); DonMessaging.SendDon("Hit them, boss! Drop every last one and the van's ours."); NDLog.Debug("[FAIDA] combat live."); } catch (Exception ex) { NDLog.Warn("[FAIDA] StartCombat: " + ex.Message); LoseBattle("the ambush fell apart"); } } private static void WinBattle() { try { int num = FillVanWithLoot(); try { if (_van != null) { _van.IsPlayerOwned = true; } } catch { } _van = null; _vanGuid = null; FaidaState.RecordWin(); try { FaidaMarkerQuest.CompleteAndClear(fanfare: true); } catch { } ShowResult("FAIDA — WON"); try { Sfx.PlayOneShot("quest-effect", 0.85f); } catch { } DonMessaging.SendDon((num > 0) ? "The street's ours, boss. The van's loaded — bricks and a couple of nice pieces. Drive it home." : "We took them down, boss. The van's yours — what's left of the load's in the back."); NDLog.Info($"[FAIDA] WON (van loot items delivered={num})."); } catch (Exception ex) { NDLog.Warn("[FAIDA] WinBattle: " + ex.Message); } finally { Cleanup(despawnVan: false); _state = State.Idle; try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } } private static void LoseBattle(string reason) { try { FaidaState.RecordLoss(); try { FaidaMarkerQuest.CompleteAndClear(); } catch { } ShowResult("FAIDA — LOST"); DonMessaging.SendDon("Call it, boss — " + reason + ". We'll get the next one."); NDLog.Info("[FAIDA] LOST (" + reason + ")."); } catch (Exception ex) { NDLog.Warn("[FAIDA] LoseBattle: " + ex.Message); } finally { Cleanup(despawnVan: true); _state = State.Idle; try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } } private static void SpawnVan(Vector3 pos, float yaw) { //IL_00ed: 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_0098: Unknown result type (might be due to invalid IL or missing references) try { VehicleManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { NDLog.DebugWarn("[FAIDA] no VehicleManager — no van."); return; } string text = "Veeper"; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { text = "veeper"; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { NDLog.DebugWarn("[FAIDA] van prefab missing."); return; } } LandVehicle val = VehicleRegistry.CreateVehicle(text); if (val == null) { NDLog.DebugWarn("[FAIDA] CreateVehicle null."); return; } val.Spawn(pos, Quaternion.Euler(0f, yaw, 0f)); try { val.ApplyColor((VehicleColor)11); } catch { } try { val.IsPlayerOwned = false; } catch { } _van = val; try { _vanGuid = val.GUID; } catch { _vanGuid = null; } NDLog.Debug($"[FAIDA] van '{text}' spawned @ {pos} (GUID={_vanGuid})."); } catch (Exception ex) { NDLog.DebugWarn("[FAIDA] SpawnVan: " + ex.Message); } } private static StorageEntity ResolveVanStorage() { try { if (string.IsNullOrEmpty(_vanGuid)) { return null; } List list = NetworkSingleton.Instance?.AllVehicles; if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { LandVehicle val = list[i]; if ((Object)(object)val == (Object)null) { continue; } string text = null; try { text = val.GUID.ToString(); } catch { } if (text == _vanGuid) { try { return val.Storage; } catch { return null; } } } } catch (Exception ex) { NDLog.DebugWarn("[FAIDA] ResolveVanStorage: " + ex.Message); } return null; } private static int FillVanWithLoot() { StorageEntity val = ResolveVanStorage(); if ((Object)(object)val == (Object)null) { NDLog.Warn("[FAIDA] van storage null — loot not delivered."); return 0; } int num = 0; num += GiveWeapon(val, ResolveFirst("goldenm1911", "m1911", "revolver", "pistol")); num += GiveWeapon(val, ResolveFirst("pumpshotgun")); num += GiveDrug(val, "cocaine", 5); num += GiveDrug(val, "meth", 5); num += GiveDrug(val, ResolveFirst("ogkush", "sourdiesel", "greencrack"), 5); return num + GiveDrug(val, ResolveFirst("shrooms", "magicmushrooms", "mushrooms"), 5); } private static int GiveDrug(StorageEntity storage, string id, int qty) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(id) || !ItemCatalog.ExistsInRegistry(id)) { NDLog.Warn("[FAIDA] drug id '" + id + "' not in registry — skipped."); return 0; } return RewardSpawner.SpawnItemInStorage(storage, id, qty, LOOT_QUALITY, "Faida van"); } private static int GiveWeapon(StorageEntity storage, string id) { if (string.IsNullOrEmpty(id) || !ItemCatalog.ExistsInRegistry(id)) { NDLog.Warn("[FAIDA] weapon id '" + id + "' not in registry — skipped."); return 0; } return RewardSpawner.SpawnItemInStorage(storage, id, 1, null, "Faida van"); } private static string ResolveFirst(params string[] ids) { for (int i = 0; i < ids.Length; i++) { if (ItemCatalog.ExistsInRegistry(ids[i])) { return ids[i]; } } return (ids.Length != 0) ? ids[0] : null; } private static void SpawnSide(List list, List defaults, Vector3 center, int requested, bool crew, float faceYaw) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_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_0067: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_pool == (Object)null) { return; } int num = _pool.UnspawnedGoonCount - 1; int num2 = Mathf.Clamp(requested, 0, num); if (num2 <= 0) { NDLog.DebugWarn(string.Format("[FAIDA] pool empty for {0} (avail={1}).", crew ? "crew" : "benzies", num)); return; } Vector3 val = NavSnap(center, 8f); List list2 = _pool.SpawnMultipleGoons(val, num2, false); if (list2 == null) { return; } for (int i = 0; i < list2.Count; i++) { CartelGoon val2 = list2[i]; if ((Object)(object)val2 == (Object)null) { continue; } LuckyBrawlManager.GoonDefaults item = LuckyBrawlManager.CaptureGoonDefaults(val2); ArmGoonShotgun(val2); if (crew) { try { FamigliaOutfit.Apply(val2, i, _pool); } catch { } LuckyBrawlManager.RenameToFamiglia(val2); } MakeStationary(val2, faceYaw); float num3 = 360f / (float)Mathf.Max(1, list2.Count) * (float)i + (float)(_rng.NextDouble() * 30.0 - 15.0); Vector3 position = NavSnap(val + Quaternion.Euler(0f, num3, 0f) * Vector3.forward * (1.6f + (float)_rng.NextDouble() * 1.6f), 4f); try { if ((Object)(object)((Component)val2).transform != (Object)null) { ((Component)val2).transform.position = position; ((Component)val2).transform.rotation = Quaternion.Euler(0f, faceYaw, 0f); } } catch { } list.Add(val2); defaults.Add(item); } } catch (Exception ex) { NDLog.Warn("[FAIDA] SpawnSide(" + (crew ? "crew" : "benzies") + "): " + ex.Message); } } private static void DeployVillaGuards(Vector3 center, float faceYaw) { //IL_000d: 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_001c: 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_0060: 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) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) //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_009d: 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_00a5: Unknown result type (might be due to invalid IL or missing references) _guardSlots.Clear(); try { Vector3 val = Vector3.Cross(Vector3.up, _battleAxis); int num = 0; for (int i = 0; i < 7; i++) { if (GuardNPC.IsDeployed(i)) { float num2 = ((num % 2 == 0) ? 1f : (-1f)); float num3 = 1.5f + (float)(num / 2) * 2f; Vector3 pos = NavSnap(center + val * num2 * (2f + (float)(num / 2) * 1.2f) - _battleAxis * (num3 - 1.5f), 4f); if (GuardNPC.Deploy(i, pos, faceYaw)) { _guardSlots.Add(i); num++; } } } NDLog.Debug($"[FAIDA] borrowed {_guardSlots.Count} villa guards."); } catch (Exception ex) { NDLog.DebugWarn("[FAIDA] DeployVillaGuards: " + ex.Message); } } private static void HoldEveryoneStill() { //IL_0010: 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_00ba: 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) for (int i = 0; i < _crew.Count; i++) { MakeStationary(_crew[i], YawTowards(_battleAxis)); } for (int j = 0; j < _benzies.Count; j++) { MakeStationary(_benzies[j], YawTowards(-_battleAxis)); } for (int k = 0; k < _guardSlots.Count; k++) { NPC val = GuardNPC.Resolve(_guardSlots[k]); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform != (Object)null) { GuardNPC.HoldPost(_guardSlots[k], ((Component)val).transform.position, YawTowards(_battleAxis)); } } } private static void ArmGoonShotgun(CartelGoon g) { try { CombatBehaviour val = ((g == null) ? null : ((NPC)g).Behaviour?.CombatBehaviour); if ((Object)(object)val == (Object)null) { return; } try { val.SetDefaultWeapon(LuckyWeaponVisual.LoadAvatarWeaponByPath("Avatar/Equippables/PumpShotgun")); } catch { } val.GiveUpRange = 1000f; try { val.DefaultSearchTime = 9999f; } catch { } try { val.SetWeapon("Avatar/Equippables/PumpShotgun"); } catch { } } catch { } } private static void MakeStationary(CartelGoon g, float faceYaw) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)g == (Object)null || (Object)(object)((Component)g).gameObject == (Object)null) { return; } try { NPCScheduleManager componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { movement.Stop(); } catch { } try { movement.PauseMovement(); } catch { } } try { if ((Object)(object)((Component)g).transform != (Object)null) { ((Component)g).transform.rotation = Quaternion.Euler(0f, faceYaw, 0f); } } catch { } } catch { } } private static void LuckyBrawlManagerMakeReady(CartelGoon g) { try { if ((Object)(object)g == (Object)null) { return; } NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { movement.ResumeMovement(); } catch { } try { movement.SetAgentEnabled(true); } catch { } try { ((Behaviour)movement).enabled = true; } catch { } } try { NPCBehaviour behaviour = ((NPC)g).Behaviour; if ((Object)(object)behaviour != (Object)null && !((Behaviour)behaviour).enabled) { ((Behaviour)behaviour).enabled = true; } } catch { } } catch { } } private static void AttackGoon(CartelGoon attacker, CartelGoon victim) { try { ICombatTargetable val = GameCompat.CastTargetable((object)victim); if (val != null) { bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (flag) { attacker.AttackEntity(val, false); } } } catch { } } private static void AttackNpc(CartelGoon attacker, NPC victim) { try { ICombatTargetable val = GameCompat.CastTargetable((object)victim); if (val != null) { bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (flag) { attacker.AttackEntity(val, false); } } } catch { } } private static List AliveGoons(List list) { List list2 = new List(); for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if (SafeSpawned(val) && !IsDownOrKO(val)) { list2.Add(val); } } return list2; } private static List LivePlayerSideTargets() { List list = new List(); for (int i = 0; i < _crew.Count; i++) { CartelGoon val = _crew[i]; if (SafeSpawned(val) && !IsDownOrKO(val)) { NPC val2 = GameCompat.Cast((Object)(object)val); if ((Object)(object)val2 != (Object)null) { list.Add(val2); } } } for (int j = 0; j < _guardSlots.Count; j++) { if (!GuardNPC.IsDownOrKO(_guardSlots[j])) { NPC val3 = GuardNPC.Resolve(_guardSlots[j]); if ((Object)(object)val3 != (Object)null) { list.Add(val3); } } } return list; } private static CartelGoon Nearest(CartelGoon from, List list) { //IL_0010: 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_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_0053: 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) CartelGoon result = null; float num = float.MaxValue; try { Vector3 position = ((Component)from).transform.position; for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } } } catch { } return result; } private static NPC Nearest(CartelGoon from, List list) { //IL_0010: 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_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_0053: 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) NPC result = null; float num = float.MaxValue; try { Vector3 position = ((Component)from).transform.position; for (int i = 0; i < list.Count; i++) { NPC val = list[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } } } catch { } return result; } private static NPC NearestNpc(NPC from, List list) { //IL_0010: 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_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_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) NPC result = null; float num = float.MaxValue; try { Vector3 position = ((Component)from).transform.position; for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } NPC val2 = GameCompat.Cast((Object)(object)val); if (!((Object)(object)val2 == (Object)null)) { Vector3 val3 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val2; } } } } catch { } return result; } private static bool SafeSpawned(CartelGoon g) { try { return (Object)(object)g != (Object)null && g.IsGoonSpawned; } catch { return false; } } private static bool IsDownOrKO(CartelGoon g) { try { NPCHealth health = ((NPC)g).Health; return (Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut; } catch { return true; } } private static void PruneGoons(List list, List defaults) { for (int num = list.Count - 1; num >= 0; num--) { if (!SafeSpawned(list[num])) { try { LuckyBrawlManager.RestoreGoonDefaults(list[num], (num < defaults.Count) ? defaults[num] : null); } catch { } list.RemoveAt(num); if (num < defaults.Count) { defaults.RemoveAt(num); } } } } private static void SpawnBlueBox(Vector3 pos) { //IL_0008: 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_002c: Unknown result type (might be due to invalid IL or missing references) DestroyBlueBox(); try { _blueBox = RapimentoZones.MakeDropoffZone(pos, new Vector3(4f, 3f, 4f), new Color(0.2f, 0.45f, 0.95f)); } catch (Exception ex) { NDLog.DebugWarn("[FAIDA] SpawnBlueBox: " + ex.Message); } } private static void DestroyBlueBox() { try { if ((Object)(object)_blueBox != (Object)null) { Object.Destroy((Object)(object)_blueBox); } } catch { } _blueBox = null; } private static bool TryPickArena(Vector3 playerPos, out Vector3 arena) { //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_003e: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_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_011d: 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_0082: 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) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) arena = playerPos; NavMeshHit val2 = default(NavMeshHit); NavMeshHit val3 = default(NavMeshHit); for (int i = 0; i < 16; i++) { float num = (float)(_rng.NextDouble() * 360.0); float num2 = 60f + (float)_rng.NextDouble() * 70f; Vector3 val = playerPos + Quaternion.Euler(0f, num, 0f) * Vector3.forward * num2; try { if (NavMesh.SamplePosition(val, ref val2, 12f, -1) && NavMesh.SamplePosition(((NavMeshHit)(ref val2)).position + Vector3.forward * 16f, ref val3, 10f, -1)) { arena = ((NavMeshHit)(ref val2)).position; return true; } } catch { } } try { Vector3 val4 = playerPos + Quaternion.Euler(0f, (float)(_rng.NextDouble() * 360.0), 0f) * Vector3.forward * 60f; NavMeshHit val5 = default(NavMeshHit); if (NavMesh.SamplePosition(val4, ref val5, 25f, -1)) { arena = ((NavMeshHit)(ref val5)).position; return true; } } catch { } return false; } private static Vector3 NavSnap(Vector3 pos, float radius) { //IL_0002: 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_0023: 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_0026: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(pos, ref val, radius, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return pos; } private static float YawTowards(Vector3 dir) { //IL_0027: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) dir.y = 0f; if (((Vector3)(ref dir)).sqrMagnitude < 0.01f) { return 0f; } Quaternion val = Quaternion.LookRotation(dir); return ((Quaternion)(ref val)).eulerAngles.y; } private static void ShowBanner(string text, float secs) { _banner = text; _bannerLeft = secs; } public static void OnGUI() { //IL_0040: 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_0132: 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_00cd: Unknown result type (might be due to invalid IL or missing references) try { EnsureStyles(); float num = 700f; float x = ((float)Screen.width - num) * 0.5f; if (_state == State.Faceoff) { DrawShadowed("FAIDA — FACE OFF", x, 110f, num, 44f, _bigStyle, GOLD); DrawShadowed(Mathf.CeilToInt(Mathf.Max(0f, _faceoffLeft)).ToString(), x, 158f, num, 56f, _bigStyle, RED); } else if (_state == State.Combat) { if (_bannerLeft > 0f && !string.IsNullOrEmpty(_banner)) { DrawShadowed(_banner, x, 110f, num, 40f, _bigStyle, GOLD); } DrawShadowed("Wipe the Benzies — take the van", x, 152f, num, 30f, _smallStyle, GOLD); } if (_resultBannerLeft > 0f && !string.IsNullOrEmpty(_resultBanner)) { DrawShadowed(_resultBanner, x, 110f, num, 48f, _bigStyle, GOLD); } } catch { } } private static void EnsureStyles() { //IL_0017: 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_0025: 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_003a: Expected O, but got Unknown //IL_0050: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown if (_bigStyle == null) { _bigStyle = new GUIStyle(GUI.skin.label) { fontSize = 26, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } if (_smallStyle == null) { _smallStyle = new GUIStyle(GUI.skin.label) { fontSize = 18, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } } private static void DrawShadowed(string text, float x, float y, float w, float h, GUIStyle style, Color fill) { //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_001b: 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_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.Label(new Rect(x + 2f, y + 2f, w, h), text, style); GUI.color = fill; GUI.Label(new Rect(x, y, w, h), text, style); GUI.color = color; } private static void ShowResult(string text) { _resultBanner = text; _resultBannerLeft = 6f; } private static void Cleanup(bool despawnVan) { try { BossMarkerSync.Clear(); } catch { } try { ReleaseSide(_crew, _crewDefaults); } catch { } try { ReleaseSide(_benzies, _benzieDefaults); } catch { } for (int i = 0; i < _guardSlots.Count; i++) { try { GuardNPC.StandDown(_guardSlots[i]); } catch { } } _guardSlots.Clear(); DestroyBlueBox(); if (despawnVan) { DespawnVan(); } _pool = null; } private static void ReleaseSide(List list, List defaults) { for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if ((Object)(object)val == (Object)null) { continue; } try { LuckyBrawlManager.RestoreGoonDefaults(val, (i < defaults.Count) ? defaults[i] : null); } catch { } bool flag = false; try { flag = val.IsGoonSpawned; } catch { } if (flag) { try { val.Despawn(); } catch { } } } list.Clear(); defaults.Clear(); } private static void DespawnVan() { try { if (_van != null && SessionGate.IsAuthority) { _van.DestroyVehichle(); } } catch { } _van = null; _vanGuid = null; } public static void ResetForSceneReload() { try { Cleanup(despawnVan: true); } catch { } _state = State.Idle; _faceoffLeft = 0f; _resultBannerLeft = 0f; _resultBanner = null; _bannerLeft = 0f; _banner = null; try { FaidaMarkerQuest.CompleteAndClear(); } catch { } } public static void SweepStaleMarker() { if (_state != State.Idle || FaidaMarkerQuest.Instance == null) { return; } NDLog.Debug("[FAIDA] stale marker quest cleaned up after reload."); FaidaMarkerQuest.CompleteAndClear(); try { BossMarkerSync.Clear(); } catch { } } } internal static class GangWarManager { private enum State { Idle, Faceoff, Combat } private const int CREW_SIZE = 2; private const int TRIAD_SIZE = 6; private const int TRIAD_MIN = 3; private const int POOL_RESERVE = 1; private const float FACEOFF_SECS = 3f; private const float BATTLE_DURATION = 300f; private const float RETARGET_INTERVAL = 1.5f; private const float GOON_GIVE_UP = 1000f; private const float SIDE_GAP = 7f; private const float RESULT_BANNER_SECS = 6f; private static readonly EQuality LOOT_QUALITY = (EQuality)4; private static readonly Vector3 FAIDA_ARENA = new Vector3(158.08f, 0.14f, 22.36f); private static Vector3 _battleAxis = new Vector3(0.909f, 0f, 0.416f); private static State _state = State.Idle; private static readonly Random _rng = new Random(); private static Vector3 _arena; private static float _faceoffLeft; private static float _battleEndsAt; private static float _retargetCd; private static bool _hadAllies; private static GoonPool _pool; private static readonly List _crew = new List(); private static readonly List _crewDefaults = new List(); private static readonly List _triads = new List(); private static readonly List _triadDefaults = new List(); private static readonly List _guardSlots = new List(); private static CartelGoon _sunYee; private static LandVehicle _van; private static string _vanGuid; private static string _resultBanner; private static float _resultBannerLeft; private static string _banner; private static float _bannerLeft; private static float _vanSweepCd; private const float REWARD_VAN_SWEEP_RADIUS = 18f; private static GUIStyle _bigStyle; private static GUIStyle _smallStyle; private static readonly Color GOLD = new Color(0.83f, 0.69f, 0.22f, 0.95f); private static readonly Color RED = new Color(0.92f, 0.26f, 0.22f, 1f); private const float BANNER_Y = 110f; public static bool IsActive => _state != State.Idle; private static bool RivalClanInstalled { get { try { return MobFamilyRegistry.AvailableCount > 1; } catch { return false; } } } public static bool Declare() { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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) try { if (!SessionGate.IsAuthority) { return false; } if (_state != State.Idle) { DonMessaging.SendDon("We're already in it, boss — finish this one first."); return false; } if (GangBattleManager.IsActive) { DonMessaging.SendDon("We've got a job on the board already, boss — clear that first."); return false; } Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null) { return false; } _pool = Object.FindObjectOfType(true); int num = (((Object)(object)_pool != (Object)null) ? Mathf.Max(0, _pool.UnspawnedGoonCount - 1) : 0); if (num < 3) { DonMessaging.SendDon(RivalClanInstalled ? "Sun Yee's men have gone to ground, boss — he hasn't got enough soldiers on the street to make a war of it right now. We move when they're out in force." : "The Benzies have gone to ground, boss — they haven't got enough soldiers on the street to make a war of it right now. We move when they're out in force."); NDLog.Debug($"[GANGWAR] declined — enemy can't field a credible force (pool avail={num}, need {3})."); return false; } _arena = NavSnap(FAIDA_ARENA, 12f); BeginBattle(); return true; } catch (Exception ex) { NDLog.Warn("[GANGWAR] Declare: " + ex.Message); Cleanup(); _state = State.Idle; return false; } } public static void HostDeclareForClient(string who) { NDLog.Debug("[GANGWAR] declared by client '" + who + "'."); Declare(); } private static void BeginBattle() { //IL_0002: 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_0012: 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_002c: 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_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_0046: 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_0055: 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_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_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_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_008a: 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_0099: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_0131: 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) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) try { float num = YawTowards(_battleAxis); float faceYaw = YawTowards(-_battleAxis); Vector3 val = NavSnap(_arena - _battleAxis * 5.5f, 8f); Vector3 center = NavSnap(_arena - _battleAxis * 7f, 8f); Vector3 pos = NavSnap(_arena - _battleAxis * 10f, 6f); Vector3 center2 = NavSnap(_arena + _battleAxis * 7f, 8f); try { MobTeleport.Fade(val, false, num); } catch { } if ((Object)(object)_pool == (Object)null) { _pool = Object.FindObjectOfType(true); } int num2 = (((Object)(object)_pool != (Object)null) ? Mathf.Max(0, _pool.UnspawnedGoonCount - 1) : 0); int num3 = Mathf.Clamp(6, 1, Mathf.Max(1, num2)); int requested = Mathf.Clamp(2, 0, Mathf.Max(0, num2 - num3)); SpawnTriads(center2, num3, faceYaw); SpawnCrew(center, requested, num); int maxGuards = Mathf.Max(2, _triads.Count - _crew.Count); DeployVillaGuards(center, num, maxGuards); try { DonSalvatoreNPC.WarpToScene(pos, num); } catch { } _hadAllies = _crew.Count > 0 || _guardSlots.Count > 0; try { BossMarkerSync.Set(RivalClanInstalled ? "Faida: Gang War — Ndrangheta vs. Triads" : "Faida: Gang War — Ndrangheta vs. Benzies", _arena); } catch { } _faceoffLeft = 3f; _state = State.Faceoff; ShowBanner("FAIDA — GANG WAR", 3.5f); try { Sfx.PlayOneShot("quest-effect", 0.8f); } catch { } DonMessaging.SendDon(RivalClanInstalled ? "Sun Yee On brought his men to our turf, boss. We end it here. Three seconds — then we hit them." : "The Benzies brought their men to our turf, boss. We end it here. Three seconds — then we hit them."); NDLog.Info($"[GANGWAR] battle begun: crew={_crew.Count} guards={_guardSlots.Count} triads={_triads.Count}."); } catch (Exception ex) { NDLog.Warn("[GANGWAR] BeginBattle: " + ex.Message); LoseBattle("the ambush fell apart before it began"); } } public static void Tick(float dt) { if (_resultBannerLeft > 0f) { _resultBannerLeft -= dt; if (_resultBannerLeft <= 0f) { _resultBannerLeft = 0f; _resultBanner = null; } } if (_bannerLeft > 0f) { _bannerLeft -= dt; } SweepEmptyRewardVans(dt); if (_state == State.Idle) { return; } if (!SessionGate.IsAuthority) { Cleanup(); _state = State.Idle; return; } switch (_state) { case State.Faceoff: TickFaceoff(dt); break; case State.Combat: TickCombat(dt); break; } } private static void TickFaceoff(float dt) { HoldEveryoneStill(); ReassertNames(); _faceoffLeft -= dt; if (_faceoffLeft <= 0f) { StartCombat(); } } private static void StartCombat() { try { for (int i = 0; i < _crew.Count; i++) { MakeReady(_crew[i]); } for (int j = 0; j < _triads.Count; j++) { MakeReady(_triads[j]); } _battleEndsAt = Time.time + 300f; _retargetCd = 0f; _state = State.Combat; ShowBanner(RivalClanInstalled ? "FAIDA — WIPE THE TRIADS" : "FAIDA — WIPE THE BENZIES", 3.5f); DonMessaging.SendDon(RivalClanInstalled ? "Hit them, boss! Put Sun Yee in the dirt and the street's ours." : "Hit them, boss! Put the Benzies in the dirt and the street's ours."); NDLog.Debug("[GANGWAR] combat live."); } catch (Exception ex) { NDLog.Warn("[GANGWAR] StartCombat: " + ex.Message); LoseBattle("the attack stalled"); } } private static void TickCombat(float dt) { if (Time.time >= _battleEndsAt) { LoseBattle((RivalClanInstalled ? "the Triads" : "the Benzies") + " held the street and we had to fall back"); return; } _retargetCd -= dt; if (_retargetCd > 0f) { return; } _retargetCd = 1.5f; PruneGoons(_crew, _crewDefaults); PruneGoons(_triads, _triadDefaults); ReassertNames(); List list = AliveGoons(_triads); if (list.Count == 0) { WinBattle(); return; } UpdateSunYeeMortality(list); List list2 = LivePlayerSideTargets(); if (_hadAllies && list2.Count == 0) { LoseBattle("they cut down every last one of our men"); return; } for (int i = 0; i < _crew.Count; i++) { if (SafeSpawned(_crew[i])) { CartelGoon val = NearestGoon(_crew[i], list); if ((Object)(object)val != (Object)null) { AttackGoon(_crew[i], val); } } } for (int j = 0; j < _triads.Count; j++) { if (SafeSpawned(_triads[j])) { NPC val2 = NearestNpcTarget(_triads[j], list2); if ((Object)(object)val2 != (Object)null) { AttackNpc(_triads[j], val2); } } } for (int k = 0; k < _guardSlots.Count; k++) { int slot = _guardSlots[k]; if (GuardNPC.IsDownOrKO(slot)) { continue; } NPC val3 = GuardNPC.Resolve(slot); if (!((Object)(object)val3 == (Object)null)) { NPC val4 = NearestNpcFromList(val3, list); if ((Object)(object)val4 != (Object)null) { GuardNPC.Engage(slot, val4); } } } } private static void UpdateSunYeeMortality(List triadsAlive) { try { if ((Object)(object)_sunYee == (Object)null) { return; } NPCHealth health = ((NPC)_sunYee).Health; if ((Object)(object)health == (Object)null) { return; } bool invincible = false; for (int i = 0; i < triadsAlive.Count; i++) { if (!GameCompat.SameInstance((object)triadsAlive[i], (object)_sunYee)) { invincible = true; break; } } health.npc.NPCData.Health.Invincible = invincible; } catch { } } private static void WinBattle() { try { int num = SpawnRewardVan(); if (RivalClanInstalled) { FaidaState.RecordTriadWin(); } else { FaidaState.RecordWin(); } ShowResult("FAIDA — WON"); try { Sfx.PlayOneShot("quest-effect", 0.85f); } catch { } string text = (RivalClanInstalled ? "Sun Yee's people are finished" : "The Benzies are finished"); DonMessaging.SendDon((num > 0) ? ("It's done, boss. " + text + " — the docks are ours. We cleaned out their stash; it's all in the van out front — bricks and a couple of nice pieces. Drive it home.") : ("It's done, boss. " + text + " — the docks are ours. The Famiglia owes you.")); NDLog.Info($"[GANGWAR] WON (van loot items delivered={num})."); } catch (Exception ex) { NDLog.Warn("[GANGWAR] WinBattle: " + ex.Message); } finally { Cleanup(); _state = State.Idle; try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } } private static void LoseBattle(string reason) { try { FaidaState.RecordTriadLoss(); ShowResult("FAIDA — LOST"); DonMessaging.SendDon("Pull back, boss — " + reason + ". We'll come for them again."); NDLog.Info("[GANGWAR] LOST (" + reason + ")."); } catch (Exception ex) { NDLog.Warn("[GANGWAR] LoseBattle: " + ex.Message); } finally { Cleanup(); _state = State.Idle; try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } } private static int SpawnRewardVan() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //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_0017: 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_001d: 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_0062: 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_007e: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = NavSnap(TortureManager.Torture.SceneVanPos, 8f); SpawnVan(val, YawTowards(_arena - val)); int num = FillVanWithLoot(); try { if (_van != null) { _van.IsPlayerOwned = true; } } catch { } NDLog.Debug($"[GANGWAR] reward van @ ({val.x:F1},{val.y:F1},{val.z:F1}), {num} item(s) loaded."); if (num <= 0) { try { if (_van != null && SessionGate.IsAuthority) { _van.DestroyVehichle(); } } catch { } } _van = null; _vanGuid = null; return num; } catch (Exception ex) { NDLog.Warn("[GANGWAR] SpawnRewardVan: " + ex.Message); return 0; } } private static void SweepEmptyRewardVans(float dt) { //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_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020c: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_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) if (!SessionGate.IsAuthority) { return; } _vanSweepCd -= dt; if (_vanSweepCd > 0f) { return; } _vanSweepCd = 4f; try { VehicleManager instance = NetworkSingleton.Instance; List list = instance?.AllVehicles; if (list == null) { return; } Vector3 sceneVanPos = TortureManager.Torture.SceneVanPos; float num = 324f; for (int num2 = list.Count - 1; num2 >= 0; num2--) { LandVehicle val = list[num2]; if ((Object)(object)val == (Object)null) { continue; } bool flag = false; try { flag = val.IsPlayerOwned; } catch { } if (!flag) { continue; } bool flag2 = false; try { flag2 = val.IsOccupied; } catch { } if (flag2) { continue; } Vector3 position; try { position = ((Component)val).transform.position; } catch { continue; } float num3 = position.x - sceneVanPos.x; float num4 = position.z - sceneVanPos.z; if (num3 * num3 + num4 * num4 > num) { continue; } StorageEntity val2 = null; try { val2 = val.Storage; } catch { } if ((Object)(object)val2 == (Object)null) { continue; } bool flag3 = false; try { flag3 = val2.IsOpened || (Object)(object)val2.CurrentPlayerAccessor != (Object)null; } catch { } if (flag3 || !IsStorageEmpty(val2)) { continue; } try { if (instance.PlayerOwnedVehicles != null) { instance.PlayerOwnedVehicles.Remove(val); } } catch { } try { val.DestroyVehicle(); } catch (Exception ex) { NDLog.DebugWarn("[GANGWAR] DestroyVehicle: " + ex.Message); continue; } NDLog.Debug($"[GANGWAR] removed empty reward van @ ({position.x:F1},{position.z:F1})."); } } catch (Exception ex2) { NDLog.DebugWarn("[GANGWAR] SweepEmptyRewardVans: " + ex2.Message); } } private static bool IsStorageEmpty(StorageEntity storage) { try { List list = ((storage != null) ? storage.ItemSlots : null); if (list == null) { return false; } for (int i = 0; i < list.Count; i++) { ItemSlot val; try { val = list[i]; } catch { continue; } if (val != null && val.ItemInstance != null) { return false; } } return true; } catch { return false; } } private static void SpawnVan(Vector3 pos, float yaw) { //IL_00ec: 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_0098: Unknown result type (might be due to invalid IL or missing references) try { VehicleManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { NDLog.DebugWarn("[GANGWAR] no VehicleManager — no van."); return; } string text = "Veeper"; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { text = "veeper"; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { NDLog.DebugWarn("[GANGWAR] van prefab missing."); return; } } LandVehicle val = VehicleRegistry.CreateVehicle(text); if (val == null) { NDLog.DebugWarn("[GANGWAR] CreateVehicle null."); return; } val.Spawn(pos, Quaternion.Euler(0f, yaw, 0f)); try { val.ApplyColor((VehicleColor)7); } catch { } try { val.IsPlayerOwned = false; } catch { } _van = val; try { _vanGuid = val.GUID; } catch { _vanGuid = null; } NDLog.Debug($"[GANGWAR] reward van '{text}' spawned @ {pos} (GUID={_vanGuid})."); } catch (Exception ex) { NDLog.DebugWarn("[GANGWAR] SpawnVan: " + ex.Message); } } private static StorageEntity ResolveVanStorage() { try { if (string.IsNullOrEmpty(_vanGuid)) { return null; } List list = NetworkSingleton.Instance?.AllVehicles; if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { LandVehicle val = list[i]; if ((Object)(object)val == (Object)null) { continue; } string text = null; try { text = val.GUID.ToString(); } catch { } if (text == _vanGuid) { try { return val.Storage; } catch { return null; } } } } catch (Exception ex) { NDLog.DebugWarn("[GANGWAR] ResolveVanStorage: " + ex.Message); } return null; } private static int FillVanWithLoot() { StorageEntity val = ResolveVanStorage(); if ((Object)(object)val == (Object)null) { NDLog.Warn("[GANGWAR] van storage null — loot not delivered."); return 0; } int num = 0; num += GiveWeapon(val, ResolveFirst("goldenm1911", "m1911", "revolver", "pistol")); num += GiveWeapon(val, ResolveFirst("pumpshotgun")); num += GiveDrug(val, "cocaine", 5); num += GiveDrug(val, "meth", 5); num += GiveDrug(val, ResolveFirst("ogkush", "sourdiesel", "greencrack"), 5); return num + GiveDrug(val, ResolveFirst("shrooms", "magicmushrooms", "mushrooms"), 5); } private static int GiveDrug(StorageEntity storage, string id, int qty) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(id) || !ItemCatalog.ExistsInRegistry(id)) { NDLog.Warn("[GANGWAR] drug id '" + id + "' not in registry — skipped."); return 0; } return RewardSpawner.SpawnItemInStorage(storage, id, qty, LOOT_QUALITY, "Faida war van"); } private static int GiveWeapon(StorageEntity storage, string id) { if (string.IsNullOrEmpty(id) || !ItemCatalog.ExistsInRegistry(id)) { NDLog.Warn("[GANGWAR] weapon id '" + id + "' not in registry — skipped."); return 0; } return RewardSpawner.SpawnItemInStorage(storage, id, 1, null, "Faida war van"); } private static string ResolveFirst(params string[] ids) { for (int i = 0; i < ids.Length; i++) { if (ItemCatalog.ExistsInRegistry(ids[i])) { return ids[i]; } } return (ids.Length != 0) ? ids[0] : null; } private static void SpawnCrew(Vector3 center, int requested, float faceYaw) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) //IL_0068: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_pool == (Object)null) { return; } int num = _pool.UnspawnedGoonCount - 1; int num2 = Mathf.Clamp(requested, 0, num); if (num2 <= 0) { NDLog.DebugWarn($"[GANGWAR] pool empty for crew (avail={num})."); return; } Vector3 val = NavSnap(center, 8f); List list = _pool.SpawnMultipleGoons(val, num2, false); if (list == null) { NDLog.DebugWarn("[GANGWAR] SpawnMultipleGoons(crew) null."); return; } for (int i = 0; i < list.Count; i++) { CartelGoon val2 = list[i]; if (!((Object)(object)val2 == (Object)null)) { LuckyBrawlManager.GoonDefaults item = LuckyBrawlManager.CaptureGoonDefaults(val2); ReviveGoon(val2); ArmGoonShotgun(val2); try { FamigliaOutfit.Apply(val2, i, _pool); } catch { } LuckyBrawlManager.RenameToFamiglia(val2); MakeStationary(val2, faceYaw); PlaceInRing(val2, val, i, list.Count, faceYaw); _crew.Add(val2); _crewDefaults.Add(item); } } } catch (Exception ex) { NDLog.Warn("[GANGWAR] SpawnCrew: " + ex.Message); } } private static void SpawnTriads(Vector3 center, int requested, float faceYaw) { //IL_0182: 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_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_0074: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_pool == (Object)null) { NDLog.DebugWarn("[GANGWAR] no GoonPool — no triads."); return; } int num = _pool.UnspawnedGoonCount - 1; int num2 = Mathf.Clamp(requested, 0, num); if (num2 <= 0) { NDLog.DebugWarn($"[GANGWAR] pool empty for triads (avail={num})."); return; } Vector3 val = NavSnap(center, 8f); List list = _pool.SpawnMultipleGoons(val, num2, false); if (list == null) { NDLog.DebugWarn("[GANGWAR] SpawnMultipleGoons(triads) null."); return; } for (int i = 0; i < list.Count; i++) { CartelGoon val2 = list[i]; if ((Object)(object)val2 == (Object)null) { continue; } LuckyBrawlManager.GoonDefaults item = LuckyBrawlManager.CaptureGoonDefaults(val2); ReviveGoon(val2); ArmGoonShotgun(val2); if (i == 0) { _sunYee = val2; if (RivalClanInstalled) { try { FamigliaOutfit.ApplyTriadBoss(val2, i, _pool); } catch { } RenameGoon(val2, "Sun Yee", "On"); } else { RenameGoon(val2, "Benzie", "Boss"); } } else if (RivalClanInstalled && i % 2 == 0) { try { FamigliaOutfit.ApplyTriad(val2, i, _pool); } catch { } RenameGoon(val2, "Triad", null); } MakeStationary(val2, faceYaw); PlaceInRing(val2, val, i, list.Count, faceYaw); _triads.Add(val2); _triadDefaults.Add(item); } } catch (Exception ex) { NDLog.Warn("[GANGWAR] SpawnTriads: " + ex.Message); } } private static void PlaceInRing(CartelGoon g, Vector3 sp, int i, int count, float faceYaw) { //IL_0002: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0027: 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_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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0063: 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_0094: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = Vector3.Cross(Vector3.up, _battleAxis); float num = ((float)i - (float)(count - 1) * 0.5f) * 2.2f; Vector3 position = NavSnap(sp + val * num + _battleAxis * ((float)_rng.NextDouble() * 1.2f - 0.6f), 4f); if ((Object)(object)((Component)g).transform != (Object)null) { ((Component)g).transform.position = position; ((Component)g).transform.rotation = Quaternion.Euler(0f, faceYaw, 0f); } } catch { } } private static void DeployVillaGuards(Vector3 center, float faceYaw, int maxGuards) { //IL_000d: 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_001c: 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_0069: 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_0080: 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) //IL_0091: 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_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_00a8: Unknown result type (might be due to invalid IL or missing references) _guardSlots.Clear(); try { Vector3 val = Vector3.Cross(Vector3.up, _battleAxis); int num = 0; for (int i = 0; i < 7; i++) { if (num >= maxGuards) { break; } if (GuardNPC.IsDeployed(i)) { float num2 = ((num % 2 == 0) ? 1f : (-1f)); float num3 = (float)(num / 2) * 1.8f; Vector3 pos = NavSnap(center + val * num2 * (3f + (float)(num / 2) * 1.2f) - _battleAxis * num3, 4f); if (GuardNPC.Deploy(i, pos, faceYaw)) { _guardSlots.Add(i); num++; } } } NDLog.Debug($"[GANGWAR] borrowed {_guardSlots.Count} villa guards."); } catch (Exception ex) { NDLog.DebugWarn("[GANGWAR] DeployVillaGuards: " + ex.Message); } } private static void HoldEveryoneStill() { //IL_0010: 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_00ba: 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) for (int i = 0; i < _crew.Count; i++) { MakeStationary(_crew[i], YawTowards(_battleAxis)); } for (int j = 0; j < _triads.Count; j++) { MakeStationary(_triads[j], YawTowards(-_battleAxis)); } for (int k = 0; k < _guardSlots.Count; k++) { NPC val = GuardNPC.Resolve(_guardSlots[k]); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform != (Object)null) { GuardNPC.HoldPost(_guardSlots[k], ((Component)val).transform.position, YawTowards(_battleAxis)); } } } private static void ReassertNames() { for (int i = 0; i < _crew.Count; i++) { try { CartelGoon val = _crew[i]; if ((Object)(object)val != (Object)null && ((NPC)val).FirstName != "Famiglia") { LuckyBrawlManager.RenameToFamiglia(val); } } catch { } } for (int j = 0; j < _triads.Count; j++) { try { CartelGoon val2 = _triads[j]; if ((Object)(object)val2 == (Object)null) { continue; } if (GameCompat.SameInstance((object)val2, (object)_sunYee)) { string text = (RivalClanInstalled ? "Sun Yee" : "Benzie"); string last = (RivalClanInstalled ? "On" : "Boss"); if (((NPC)val2).FirstName != text) { RenameGoon(val2, text, last); } } else if (!(((NPC)val2).NPCData.BasicInfo.FirstName == "Benzies Goon")) { } } catch { } } } private static void RenameGoon(CartelGoon g, string first, string last) { try { ((NPC)g).NPCData.BasicInfo.FirstName = first; bool flag = !string.IsNullOrEmpty(last); ((NPC)g).NPCData.BasicInfo.HasLastName = flag; ((NPC)g).NPCData.BasicInfo.LastName = (flag ? last : string.Empty); } catch (Exception ex) { NDLog.DebugWarn("[GANGWAR] RenameGoon: " + ex.Message); } } private static void ReviveGoon(CartelGoon g) { try { NPCHealth val = (((Object)(object)g != (Object)null) ? ((NPC)g).Health : null); if (!((Object)(object)val == (Object)null)) { bool flag = false; try { flag = val.IsKnockedOut || val.IsDead || !((NPC)g).IsConscious; } catch { } if (flag) { val.Revive(); } } } catch (Exception ex) { NDLog.DebugWarn("[GANGWAR] ReviveGoon: " + ex.Message); } } private static void ArmGoonShotgun(CartelGoon g) { try { CombatBehaviour val = ((g == null) ? null : ((NPC)g).Behaviour?.CombatBehaviour); if ((Object)(object)val == (Object)null) { return; } try { val.SetDefaultWeapon(LuckyWeaponVisual.LoadAvatarWeaponByPath("Avatar/Equippables/PumpShotgun")); } catch { } val.GiveUpRange = 1000f; try { val.DefaultSearchTime = 9999f; } catch { } try { val.SetWeapon("Avatar/Equippables/PumpShotgun"); } catch { } } catch { } } private static void MakeStationary(CartelGoon g, float faceYaw) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)g == (Object)null || (Object)(object)((Component)g).gameObject == (Object)null) { return; } try { NPCScheduleManager componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { movement.Stop(); } catch { } try { movement.PauseMovement(); } catch { } } try { if ((Object)(object)((Component)g).transform != (Object)null) { ((Component)g).transform.rotation = Quaternion.Euler(0f, faceYaw, 0f); } } catch { } } catch { } } private static void MakeReady(CartelGoon g) { try { if ((Object)(object)g == (Object)null) { return; } NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { movement.ResumeMovement(); } catch { } try { movement.SetAgentEnabled(true); } catch { } try { ((Behaviour)movement).enabled = true; } catch { } } try { NPCBehaviour behaviour = ((NPC)g).Behaviour; if ((Object)(object)behaviour != (Object)null && !((Behaviour)behaviour).enabled) { ((Behaviour)behaviour).enabled = true; } } catch { } } catch { } } private static void AttackGoon(CartelGoon attacker, CartelGoon victim) { try { ICombatTargetable val = GameCompat.CastTargetable((object)victim); if (val != null) { bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (flag) { attacker.AttackEntity(val, false); } } } catch { } } private static void AttackNpc(CartelGoon attacker, NPC victim) { try { ICombatTargetable val = GameCompat.CastTargetable((object)victim); if (val != null) { bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (flag) { attacker.AttackEntity(val, false); } } } catch { } } private static List AliveGoons(List list) { List list2 = new List(); for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if (SafeSpawned(val) && !IsDownOrKO(val)) { list2.Add(val); } } return list2; } private static List LivePlayerSideTargets() { List list = new List(); for (int i = 0; i < _crew.Count; i++) { CartelGoon val = _crew[i]; if (SafeSpawned(val) && !IsDownOrKO(val)) { NPC val2 = GameCompat.Cast((Object)(object)val); if ((Object)(object)val2 != (Object)null) { list.Add(val2); } } } for (int j = 0; j < _guardSlots.Count; j++) { if (!GuardNPC.IsDownOrKO(_guardSlots[j])) { NPC val3 = GuardNPC.Resolve(_guardSlots[j]); if ((Object)(object)val3 != (Object)null) { list.Add(val3); } } } return list; } private static CartelGoon NearestGoon(CartelGoon from, List list) { //IL_0010: 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_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_0053: 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) CartelGoon result = null; float num = float.MaxValue; try { Vector3 position = ((Component)from).transform.position; for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } } } catch { } return result; } private static NPC NearestNpcTarget(CartelGoon from, List list) { //IL_0010: 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_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_0053: 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) NPC result = null; float num = float.MaxValue; try { Vector3 position = ((Component)from).transform.position; for (int i = 0; i < list.Count; i++) { NPC val = list[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } } } catch { } return result; } private static NPC NearestNpcFromList(NPC from, List list) { //IL_0010: 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_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_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) NPC result = null; float num = float.MaxValue; try { Vector3 position = ((Component)from).transform.position; for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } NPC val2 = GameCompat.Cast((Object)(object)val); if (!((Object)(object)val2 == (Object)null)) { Vector3 val3 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val2; } } } } catch { } return result; } private static bool SafeSpawned(CartelGoon g) { try { return (Object)(object)g != (Object)null && g.IsGoonSpawned; } catch { return false; } } private static bool IsDownOrKO(CartelGoon g) { try { NPCHealth health = ((NPC)g).Health; return (Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut; } catch { return true; } } private static void PruneGoons(List list, List defaults) { for (int num = list.Count - 1; num >= 0; num--) { if (!SafeSpawned(list[num])) { try { LuckyBrawlManager.RestoreGoonDefaults(list[num], (num < defaults.Count) ? defaults[num] : null); } catch { } if (GameCompat.SameInstance((object)list[num], (object)_sunYee)) { _sunYee = null; } list.RemoveAt(num); if (num < defaults.Count) { defaults.RemoveAt(num); } } } } private static Vector3 NavSnap(Vector3 pos, float radius) { //IL_0002: 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_0023: 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_0026: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(pos, ref val, radius, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return pos; } private static float YawTowards(Vector3 dir) { //IL_0027: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) dir.y = 0f; if (((Vector3)(ref dir)).sqrMagnitude < 0.01f) { return 0f; } Quaternion val = Quaternion.LookRotation(dir); return ((Quaternion)(ref val)).eulerAngles.y; } private static void ShowBanner(string text, float secs) { _banner = text; _bannerLeft = secs; } private static void ShowResult(string text) { _resultBanner = text; _resultBannerLeft = 6f; } public static void OnGUI() { //IL_0040: 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_0143: 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_00ff: Unknown result type (might be due to invalid IL or missing references) try { EnsureStyles(); float num = 700f; float x = ((float)Screen.width - num) * 0.5f; if (_state == State.Faceoff) { DrawShadowed("FAIDA — GANG WAR", x, 110f, num, 44f, _bigStyle, GOLD); DrawShadowed(Mathf.CeilToInt(Mathf.Max(0f, _faceoffLeft)).ToString(), x, 158f, num, 56f, _bigStyle, RED); } else if (_state == State.Combat) { if (_bannerLeft > 0f && !string.IsNullOrEmpty(_banner)) { DrawShadowed(_banner, x, 110f, num, 40f, _bigStyle, GOLD); } DrawShadowed(RivalClanInstalled ? "Ndrangheta vs. Triads — drop Sun Yee On" : "Ndrangheta vs. Benzies — drop their boss", x, 152f, num, 30f, _smallStyle, GOLD); } if (_resultBannerLeft > 0f && !string.IsNullOrEmpty(_resultBanner)) { DrawShadowed(_resultBanner, x, 110f, num, 48f, _bigStyle, GOLD); } } catch { } } private static void EnsureStyles() { //IL_0017: 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_0025: 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_003a: Expected O, but got Unknown //IL_0050: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown if (_bigStyle == null) { _bigStyle = new GUIStyle(GUI.skin.label) { fontSize = 26, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } if (_smallStyle == null) { _smallStyle = new GUIStyle(GUI.skin.label) { fontSize = 18, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } } private static void DrawShadowed(string text, float x, float y, float w, float h, GUIStyle style, Color fill) { //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_001b: 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_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.Label(new Rect(x + 2f, y + 2f, w, h), text, style); GUI.color = fill; GUI.Label(new Rect(x, y, w, h), text, style); GUI.color = color; } private static void Cleanup() { try { BossMarkerSync.Clear(); } catch { } try { DonSalvatoreNPC.RestoreFromScene(); } catch { } try { if ((Object)(object)_sunYee != (Object)null) { NPCHealth health = ((NPC)_sunYee).Health; if ((Object)(object)health != (Object)null) { health.npc.NPCData.Health.Invincible = false; } } } catch { } try { ReleaseSide(_crew, _crewDefaults); } catch { } try { ReleaseSide(_triads, _triadDefaults); } catch { } for (int i = 0; i < _guardSlots.Count; i++) { try { GuardNPC.StandDown(_guardSlots[i]); } catch { } } _guardSlots.Clear(); _sunYee = null; _hadAllies = false; _pool = null; } private static void ReleaseSide(List list, List defaults) { for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if ((Object)(object)val == (Object)null) { continue; } try { LuckyBrawlManager.RestoreGoonDefaults(val, (i < defaults.Count) ? defaults[i] : null); } catch { } bool flag = false; try { flag = val.IsGoonSpawned; } catch { } if (flag) { try { val.Despawn(); } catch { } } } list.Clear(); defaults.Clear(); } public static void ResetForSceneReload() { try { Cleanup(); } catch { } _state = State.Idle; _faceoffLeft = 0f; _resultBannerLeft = 0f; _resultBanner = null; _bannerLeft = 0f; _banner = null; } public static void SweepStaleMarker() { if (_state != State.Idle) { return; } try { BossMarkerSync.Clear(); } catch { } } } internal static class Gif { public sealed class GifFrames { public Sprite[] Frames; public float[] Delays; } private static readonly Dictionary _cache = new Dictionary(); public static GifFrames Load(string resource) { try { if (string.IsNullOrEmpty(resource)) { return null; } if (_cache.TryGetValue(resource, out var value)) { return value; } byte[] d; using (Stream stream = typeof(Gif).Assembly.GetManifestResourceStream(resource)) { if (stream == null) { NDLog.Warn("[GIF] embedded resource not found: " + resource); _cache[resource] = null; return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); d = memoryStream.ToArray(); } GifFrames gifFrames = Decode(d, resource); _cache[resource] = gifFrames; return gifFrames; } catch (Exception ex) { NDLog.Warn("[GIF] Load " + resource + ": " + ex.Message); return null; } } private static GifFrames Decode(byte[] d, string name) { //IL_04c4: 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) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) try { if (d == null || d.Length < 13 || d[0] != 71 || d[1] != 73 || d[2] != 70) { NDLog.Warn("[GIF] " + name + ": not a GIF / too small."); return null; } int num = 6; int num2 = d[num] | (d[num + 1] << 8); num += 2; int num3 = d[num] | (d[num + 1] << 8); num += 2; int num4 = d[num++]; num++; num++; bool flag = (num4 & 0x80) != 0; int num5 = 2 << (num4 & 7); byte[] array = null; if (flag) { array = new byte[num5 * 3]; Array.Copy(d, num, array, 0, num5 * 3); num += num5 * 3; } if (num2 <= 0 || num3 <= 0 || num2 > 4096 || num3 > 4096) { NDLog.Warn($"[GIF] {name}: bad size {num2}x{num3}."); return null; } Color32[] array2 = (Color32[])(object)new Color32[num2 * num3]; List list = new List(); List list2 = new List(); int num6 = 0; int num7 = -1; int num8 = 0; int num9 = 0; while (num < d.Length && num9++ < 100000) { switch (d[num++]) { case 33: { int num24 = ((num < d.Length) ? d[num++] : 0); if (num24 == 249 && num + 5 <= d.Length) { int num25 = d[num++]; int num26 = d[num++]; num8 = (num26 >> 2) & 7; num6 = d[num] | (d[num + 1] << 8); num += 2; int num27 = d[num++]; num7 = (((num26 & 1) != 0) ? num27 : (-1)); num++; if (num25 != 4) { num = SkipSubBlocks(d, num); } } else { num = SkipSubBlocks(d, num); } continue; } case 44: { if (num + 9 > d.Length) { break; } int num10 = d[num] | (d[num + 1] << 8); num += 2; int num11 = d[num] | (d[num + 1] << 8); num += 2; int num12 = d[num] | (d[num + 1] << 8); num += 2; int num13 = d[num] | (d[num + 1] << 8); num += 2; int num14 = d[num++]; bool flag2 = (num14 & 0x80) != 0; bool flag3 = (num14 & 0x40) != 0; int num15 = 2 << (num14 & 7); byte[] array3 = array; if (flag2) { array3 = new byte[num15 * 3]; if (num + num15 * 3 > d.Length) { break; } Array.Copy(d, num, array3, 0, num15 * 3); num += num15 * 3; } Color32[] array4 = ((num8 == 3) ? ((Color32[])array2.Clone()) : null); if (num >= d.Length) { break; } int minCode = d[num++]; byte[] data = ReadSubBlocks(d, ref num); int[] array5 = LzwDecode(data, minCode, num12 * num13); if (array3 != null && array5 != null && num12 > 0 && num13 > 0) { int[] array6 = (flag3 ? InterlaceOrder(num13) : null); for (int i = 0; i < num13; i++) { int num16 = (flag3 ? array6[i] : i); int num17 = i * num12; for (int j = 0; j < num12; j++) { int num18 = array5[num17 + j]; if (num18 == num7) { continue; } int num19 = num10 + j; int num20 = num11 + num16; if (num19 >= 0 && num19 < num2 && num20 >= 0 && num20 < num3) { int num21 = num18 * 3; if (num21 + 2 < array3.Length) { array2[num20 * num2 + num19] = new Color32(array3[num21], array3[num21 + 1], array3[num21 + 2], byte.MaxValue); } } } } } list.Add(MakeSprite(array2, num2, num3, $"{name}#{list.Count}")); list2.Add((num6 > 1) ? ((float)num6 / 100f) : 0.08f); switch (num8) { case 2: { for (int k = 0; k < num13; k++) { for (int l = 0; l < num12; l++) { int num22 = num10 + l; int num23 = num11 + k; if (num22 >= 0 && num22 < num2 && num23 >= 0 && num23 < num3) { array2[num23 * num2 + num22] = new Color32((byte)0, (byte)0, (byte)0, (byte)0); } } } break; } case 3: if (array4 != null) { array2 = array4; } break; } num8 = 0; num7 = -1; num6 = 0; continue; } } break; } if (list.Count == 0) { NDLog.Warn("[GIF] " + name + ": 0 frames decoded."); return null; } NDLog.Debug($"[GIF] '{name}' decoded {list.Count} frame(s) ({num2}x{num3})."); return new GifFrames { Frames = list.ToArray(), Delays = list2.ToArray() }; } catch (Exception ex) { NDLog.Warn("[GIF] Decode " + name + ": " + ex.Message); return null; } } private static int SkipSubBlocks(byte[] d, int pos) { while (pos < d.Length) { int num = d[pos++]; if (num == 0) { break; } pos += num; } return pos; } private static byte[] ReadSubBlocks(byte[] d, ref int pos) { using MemoryStream memoryStream = new MemoryStream(); while (pos < d.Length) { int num = d[pos++]; if (num == 0) { break; } if (pos + num > d.Length) { num = d.Length - pos; } if (num <= 0) { break; } memoryStream.Write(d, pos, num); pos += num; } return memoryStream.ToArray(); } private static int[] LzwDecode(byte[] data, int minCode, int pixelCount) { try { if (data == null || data.Length == 0 || minCode < 2 || minCode > 8) { return null; } int clearCode = 1 << minCode; int endCode = clearCode + 1; int codeSize = minCode + 1; int next = endCode + 1; int[][] dict = new int[4096][]; Reset(); int[] array = new int[pixelCount]; int num = 0; int num2 = 0; int num3 = data.Length * 8; int[] array2 = null; while (num < pixelCount && num2 + codeSize <= num3) { int num4 = 0; for (int i = 0; i < codeSize; i++) { int num5 = num2 + i; num4 |= ((data[num5 >> 3] >> (num5 & 7)) & 1) << i; } num2 += codeSize; if (num4 == clearCode) { Reset(); array2 = null; continue; } if (num4 == endCode) { break; } int[] array3; if (num4 < next && dict[num4] != null) { array3 = dict[num4]; } else { if (array2 == null) { break; } array3 = new int[array2.Length + 1]; Array.Copy(array2, array3, array2.Length); array3[array2.Length] = array2[0]; } for (int j = 0; j < array3.Length; j++) { if (num >= pixelCount) { break; } array[num++] = array3[j]; } if (array2 != null && next < 4096) { int[] array4 = new int[array2.Length + 1]; Array.Copy(array2, array4, array2.Length); array4[array2.Length] = array3[0]; dict[next++] = array4; if (next == 1 << codeSize && codeSize < 12) { codeSize++; } } array2 = array3; } return array; void Reset() { for (int k = 0; k < clearCode; k++) { dict[k] = new int[1] { k }; } dict[clearCode] = null; dict[endCode] = null; next = endCode + 1; codeSize = minCode + 1; } } catch { return null; } } private static int[] InterlaceOrder(int h) { int[] array = new int[h]; int num = 0; for (int i = 0; i < h; i += 8) { array[num++] = i; } for (int j = 4; j < h; j += 8) { array[num++] = j; } for (int k = 2; k < h; k += 4) { array[num++] = k; } for (int l = 1; l < h; l += 2) { array[num++] = l; } return array; } private static Sprite MakeSprite(Color32[] canvas, int w, int h, string name) { //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_0012: 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_0023: Expected O, but got Unknown //IL_006f: 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) Texture2D val = new Texture2D(w, h, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1, name = name }; Color32[] array = (Color32[])(object)new Color32[w * h]; for (int i = 0; i < h; i++) { Array.Copy(canvas, i * w, array, (h - 1 - i) * w, w); } val.SetPixels32(array); val.Apply(false, false); return Sprite.Create(val, new Rect(0f, 0f, (float)w, (float)h), new Vector2(0.5f, 0.5f), 100f); } } internal static class GridItemInitNreGuard { private static int _logBudget = 4; internal static bool ShouldSkipNullGrid(Grid grid, string where) { bool flag = false; try { if ((Object)(object)grid == (Object)null) { flag = true; } } catch { flag = true; } if (!flag) { return false; } if (_logBudget > 0) { _logBudget--; NDLog.DebugWarn("[CLIENTGRID] " + where + ": replizierte Buildable ohne aufloesbares Grid (Client baut Mod-Grid nicht) — Init uebersprungen statt NRE (sonst haengt das Co-op-Lade-Bild an playerDataRetrieveReturned)."); } return true; } } [HarmonyPatch(typeof(GridItem), "InitializeGridItem")] internal static class Patch_GridItem_InitializeGridItem_NullGuard { private static bool Prepare() { try { return AccessTools.Method(typeof(GridItem), "InitializeGridItem", (Type[])null, (Type[])null) != null; } catch { return false; } } [HarmonyPrefix] private static bool Prefix(Grid grid) { return !GridItemInitNreGuard.ShouldSkipNullGrid(grid, "GridItem.InitializeGridItem"); } } [HarmonyPatch(typeof(PlaceableStorageEntity), "InitializeGridItem")] internal static class Patch_PlaceableStorageEntity_InitializeGridItem_NullGuard { private static bool Prepare() { try { return AccessTools.Method(typeof(PlaceableStorageEntity), "InitializeGridItem", (Type[])null, (Type[])null) != null; } catch { return false; } } [HarmonyPrefix] private static bool Prefix(Grid grid) { return !GridItemInitNreGuard.ShouldSkipNullGrid(grid, "PlaceableStorageEntity.InitializeGridItem"); } } internal enum GridKey { Lager, Terrace, Salon } internal static class GridPersistence { private struct Rec { public GridKey Key; public float OX; public float OZ; public int Rot; public string Guid; public string ItemStr; public string ContentsStr; } private struct Pending { public Grid Grid; public string Guid; public string Contents; public int Attempts; } private static readonly List _stash = new List(); private static readonly bool[] _replayed = new bool[3]; private static readonly List _pendingContents = new List(); private const int PENDING_MAX_ATTEMPTS = 600; private static readonly string SLOT_SEP = '\u001f'.ToString(); private static int _lastCapturedCount = -1; private static int _diagOccSeen; private static int _diagNullData; private static int _diagStorages; private static int _diagStorageItems; private static int _lastLoggedStorageItems = -1; private static int _lastLoggedStorages = -1; public static string CaptureAllString() { StringBuilder stringBuilder = new StringBuilder(); _diagOccSeen = 0; _diagNullData = 0; _diagStorages = 0; _diagStorageItems = 0; HashSet hashSet = new HashSet(); try { CaptureGrid(LagerGrid.GridRef, GridKey.Lager, stringBuilder, hashSet); CaptureGrid(VillaRoom.TerraceGridRef, GridKey.Terrace, stringBuilder, hashSet); CaptureGrid(VillaRoom.SalonGridRef, GridKey.Salon, stringBuilder, hashSet); } catch (Exception ex) { NDLog.DebugWarn("[GRIDPERSIST] Capture: " + ex.Message); } try { for (int i = 0; i < _stash.Count; i++) { Rec rec = _stash[i]; if ((!_replayed[(int)rec.Key] || !GridIsLive(rec.Key)) && !hashSet.Contains(rec.Guid) && !GameCompat.IsGuidRegistered(rec.Guid)) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append((int)rec.Key).Append('|').Append(rec.OX.ToString(CultureInfo.InvariantCulture)) .Append('|') .Append(rec.OZ.ToString(CultureInfo.InvariantCulture)) .Append('|') .Append(rec.Rot) .Append('|') .Append(rec.Guid) .Append('|') .Append(Convert.ToBase64String(Encoding.UTF8.GetBytes(rec.ItemStr))) .Append('|') .Append((!string.IsNullOrEmpty(rec.ContentsStr)) ? Convert.ToBase64String(Encoding.UTF8.GetBytes(rec.ContentsStr)) : ""); } } } catch (Exception ex2) { NDLog.DebugWarn("[GRIDPERSIST] Capture stash: " + ex2.Message); } string text = stringBuilder.ToString(); int num = ((!string.IsNullOrEmpty(text)) ? text.Split(new char[1] { '\n' }).Length : 0); if (num != _lastCapturedCount || (_diagOccSeen > 0 && num == 0)) { _lastCapturedCount = num; bool flag = (Object)(object)LagerGrid.GridRef != (Object)null; bool flag2 = (Object)(object)VillaRoom.TerraceGridRef != (Object)null; bool flag3 = (Object)(object)VillaRoom.SalonGridRef != (Object)null; NDLog.Debug($"[GRIDPERSIST] DIAG capture -> {num} buildables (occupants seen={_diagOccSeen}, nullData={_diagNullData}; GridRefs Lager={flag} Terrace={flag2} Salon={flag3})."); } if (_diagStorages != _lastLoggedStorages) { _lastLoggedStorages = _diagStorages; _lastLoggedStorageItems = _diagStorageItems; NDLog.Debug($"[GRIDPERSIST] contents capture -> {_diagStorages} storage furniture, {_diagStorageItems} stored item(s) serialized."); } return text; } private static void CaptureGrid(Grid grid, GridKey key, StringBuilder sb, HashSet seen) { //IL_00e1: 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) if ((Object)(object)grid == (Object)null) { return; } List tiles = grid.Tiles; if (tiles == null) { return; } int count = tiles.Count; for (int i = 0; i < count; i++) { Tile val = tiles[i]; if ((Object)(object)val == (Object)null) { continue; } List buildableOccupants = val.BuildableOccupants; if (buildableOccupants == null) { continue; } int count2 = buildableOccupants.Count; if (count2 > 0) { _diagOccSeen += count2; } for (int j = 0; j < count2; j++) { GridItem val2 = buildableOccupants[j]; if ((Object)(object)val2 == (Object)null) { continue; } GridItemData gridItemData = GameCompat.GetGridItemData(val2); if (gridItemData == null) { _diagNullData++; continue; } string text = null; string text2 = null; Vector2 val3 = default(Vector2); int value = 0; try { text = ((BuildableItemData)gridItemData).GUID; text2 = ((BuildableItemData)gridItemData).ItemString; val3 = gridItemData.OriginCoordinate; value = gridItemData.Rotation; } catch { } if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2) && seen.Add(text)) { string value2 = CaptureContents(val2); if (sb.Length > 0) { sb.Append('\n'); } sb.Append((int)key).Append('|').Append(val3.x.ToString(CultureInfo.InvariantCulture)) .Append('|') .Append(val3.y.ToString(CultureInfo.InvariantCulture)) .Append('|') .Append(value) .Append('|') .Append(text) .Append('|') .Append(Convert.ToBase64String(Encoding.UTF8.GetBytes(text2))) .Append('|') .Append(value2); } } } } private static string CaptureContents(GridItem gi) { try { StorageEntity val = (((Object)(object)gi != (Object)null) ? ((Component)gi).GetComponentInChildren(true) : null); if ((Object)(object)val == (Object)null) { return ""; } _diagStorages++; List itemSlots = val.ItemSlots; if (itemSlots == null || itemSlots.Count == 0) { return ""; } List list = new List(itemSlots.Count); bool flag = false; for (int i = 0; i < itemSlots.Count; i++) { string item = ""; ItemSlot val2; try { val2 = itemSlots[i]; } catch { val2 = null; } ItemInstance val3 = ((val2 != null) ? val2.ItemInstance : null); if (val3 != null) { try { ItemData itemData = val3.GetItemData(); if (itemData != null) { item = ((SaveData)itemData).GetJson(false); flag = true; _diagStorageItems++; } } catch { } } list.Add(item); } if (!flag) { return ""; } return Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Join(SLOT_SEP, list))); } catch (Exception ex) { NDLog.DebugWarn("[GRIDPERSIST] CaptureContents: " + ex.Message); return ""; } } public static void LoadStash(string packed) { _stash.Clear(); _pendingContents.Clear(); for (int i = 0; i < _replayed.Length; i++) { _replayed[i] = false; } if (string.IsNullOrEmpty(packed)) { NDLog.Debug("[GRIDPERSIST] LoadStash: EMPTY (nothing in save) — either nothing was ever placed OR capture is not finding the buildables."); return; } string[] array = packed.Split(new char[1] { '\n' }); for (int j = 0; j < array.Length; j++) { string[] array2 = array[j].Split(new char[1] { '|' }); if (array2.Length >= 6) { try { Rec item = new Rec { Key = (GridKey)int.Parse(array2[0]), OX = float.Parse(array2[1], CultureInfo.InvariantCulture), OZ = float.Parse(array2[2], CultureInfo.InvariantCulture), Rot = int.Parse(array2[3]), Guid = array2[4], ItemStr = Encoding.UTF8.GetString(Convert.FromBase64String(array2[5])), ContentsStr = ((array2.Length >= 7 && !string.IsNullOrEmpty(array2[6])) ? Encoding.UTF8.GetString(Convert.FromBase64String(array2[6])) : null) }; _stash.Add(item); } catch (Exception ex) { NDLog.DebugWarn($"[GRIDPERSIST] parse line {j}: {ex.Message}"); } } } NDLog.Debug($"[GRIDPERSIST] stashed {_stash.Count} saved buildables for replay."); } public static void ReplayIfReady(GridKey key, Grid grid) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority) { return; } DrainPendingContents(); if (_replayed[(int)key] || (Object)(object)grid == (Object)null) { return; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; for (int i = 0; i < _stash.Count; i++) { Rec rec = _stash[i]; if (rec.Key != key) { continue; } num4++; if (GameCompat.IsGuidRegistered(rec.Guid)) { num2++; if (!string.IsNullOrEmpty(rec.ContentsStr)) { TryRestoreContents(grid, rec.Guid, rec.ContentsStr); } } else if (GameCompat.LoadGridItem(rec.ItemStr, grid, new Vector2(rec.OX, rec.OZ), rec.Rot, rec.Guid)) { num++; if (!string.IsNullOrEmpty(rec.ContentsStr)) { TryRestoreContents(grid, rec.Guid, rec.ContentsStr); } } else { num3++; } } _replayed[(int)key] = true; if (num4 > 0) { NDLog.Debug($"[GRIDPERSIST] Replay {key}: {num} placed, {num2} already registered, {num3} FAILED (of {num4} records)."); } } catch (Exception ex) { NDLog.DebugWarn($"[GRIDPERSIST] ReplayIfReady {key}: {ex.Message}"); } } private static void TryRestoreContents(Grid grid, string guid, string contents) { StorageEntity val = FindStorageOnGrid(grid, guid); if ((Object)(object)val != (Object)null) { RestoreInto(val, contents); return; } _pendingContents.Add(new Pending { Grid = grid, Guid = guid, Contents = contents, Attempts = 0 }); } private static void DrainPendingContents() { if (_pendingContents.Count == 0) { return; } for (int num = _pendingContents.Count - 1; num >= 0; num--) { Pending value = _pendingContents[num]; StorageEntity val = FindStorageOnGrid(value.Grid, value.Guid); if ((Object)(object)val != (Object)null) { RestoreInto(val, value.Contents); _pendingContents.RemoveAt(num); } else { value.Attempts++; if (value.Attempts > 600) { NDLog.DebugWarn("[GRIDPERSIST] gave up restoring contents for buildable " + value.Guid + " (no storage resolved)."); _pendingContents.RemoveAt(num); } else { _pendingContents[num] = value; } } } } private static StorageEntity FindStorageOnGrid(Grid grid, string guid) { try { if ((Object)(object)grid == (Object)null || string.IsNullOrEmpty(guid)) { return null; } List tiles = grid.Tiles; if (tiles == null) { return null; } for (int i = 0; i < tiles.Count; i++) { Tile val = tiles[i]; List list = (((Object)(object)val != (Object)null) ? val.BuildableOccupants : null); if (list == null) { continue; } for (int j = 0; j < list.Count; j++) { GridItem val2 = list[j]; if ((Object)(object)val2 == (Object)null) { continue; } GridItemData gridItemData = GameCompat.GetGridItemData(val2); string text = null; try { text = ((BuildableItemData)(gridItemData?)).GUID; } catch { } if (!(text == guid)) { continue; } StorageEntity componentInChildren = ((Component)val2).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return null; } try { if (componentInChildren.ItemSlots == null || componentInChildren.ItemSlots.Count == 0) { return null; } } catch { return null; } return componentInChildren; } } } catch (Exception ex) { NDLog.DebugWarn("[GRIDPERSIST] FindStorageOnGrid: " + ex.Message); } return null; } private static void RestoreInto(StorageEntity storage, string contents) { try { List list = (((Object)(object)storage != (Object)null) ? storage.ItemSlots : null); if (list == null) { return; } string[] array = contents.Split(new string[1] { SLOT_SEP }, StringSplitOptions.None); int num = Math.Min(array.Length, list.Count); int num2 = 0; for (int i = 0; i < num; i++) { if (string.IsNullOrEmpty(array[i])) { continue; } ItemSlot val; try { val = list[i]; } catch { continue; } if (val == null) { continue; } try { if (val.ItemInstance != null) { continue; } } catch { } ItemInstance val2 = null; try { val2 = ItemDeserializer.LoadItem(array[i]); } catch { } if (val2 != null) { try { val.SetStoredItem(val2, false); num2++; } catch (Exception ex) { NDLog.DebugWarn("[GRIDPERSIST] SetStoredItem: " + ex.Message); } } } if (num2 > 0) { NDLog.Debug($"[GRIDPERSIST] restored {num2} item(s) into a storage ({list.Count} slots)."); } } catch (Exception ex2) { NDLog.Warn("[GRIDPERSIST] RestoreInto: " + ex2.Message); } } private static bool GridIsLive(GridKey key) { try { return key switch { GridKey.Lager => (Object)(object)LagerGrid.GridRef != (Object)null, GridKey.Terrace => (Object)(object)VillaRoom.TerraceGridRef != (Object)null, GridKey.Salon => (Object)(object)VillaRoom.SalonGridRef != (Object)null, _ => false, }; } catch { return false; } } public static void ResetReplayLatches() { for (int i = 0; i < _replayed.Length; i++) { _replayed[i] = false; } _pendingContents.Clear(); } } internal static class InformantiManager { private enum State { Idle, NotePlaced, Raid } private const float NOTE_MIN_DIST = 40f; private const float NOTE_MAX_DIST = 170f; private const float NOTE_TIMEOUT = 900f; private const float RAID_SECONDS = 180f; private const float COOLDOWN = 240f; private const int CASH_MIN = 2000; private const int CASH_MAX = 4000; private const float POLL_INTERVAL = 1f; private const int GUARD_MIN = 2; private const int GUARD_MAX = 3; private const int GUARD_POOL_RESERVE = 1; private const float GUARD_SIGHT_RANGE = 22f; private const float GUARD_GIVE_UP = 60f; private static State _state = State.Idle; private static readonly Random _rng = new Random(); private static GameObject _note; private static GameObject _noteBeacon; private static PizzoDropPicker.DropChoice _stash; private static int _amount; private static float _noteExpiresAt; private static float _raidEndsAt; private static float _pollCd; private static float _cooldownUntil; private static bool _lootSpawned; private static GoonPool _guardPool; private static readonly List _benzies = new List(); private static readonly List _benzieDefaults = new List(); private static bool _busyMsgSent; private static GameObject _clientNote; private static readonly Color RAID_GOLD = new Color(0.83f, 0.69f, 0.22f, 0.95f); private static readonly Color RAID_RED = new Color(0.92f, 0.26f, 0.22f, 1f); private const float RAID_BANNER_Y = 72f; private const float RAID_TIMER_Y = 112f; private static GUIStyle _raidHudStyle; private static GUIStyle _raidTimerStyle; public static void ResetForSceneReload() { AbortQuiet(removeLoot: true); ClientHideNote(); _cooldownUntil = 0f; } internal static void SweepStaleMarker() { if (_state == State.Idle && InformantiMarkerQuest.Instance != null) { NDLog.Debug("[INFORMANTI] cleaned up stale marker quest after reload."); InformantiMarkerQuest.CompleteAndClear(); } } public static bool StartFromChat() { //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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) //IL_020f: 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_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) try { NDLog.Debug("[INFORMANTI] StartFromChat."); if (!SessionGate.IsAuthority) { NDLog.Debug("[INFORMANTI] abort: not authority."); return false; } if (!TerritoryHandover.HandoverActive) { NDLog.Debug("[INFORMANTI] abort: handover not active."); return false; } if (_state != State.Idle) { NDLog.Debug($"[INFORMANTI] abort: state={_state}."); if (!_busyMsgSent) { DonMessaging.SendDon("The informant already left word. Go find that note."); _busyMsgSent = true; } return false; } if (Time.time < _cooldownUntil) { NDLog.Debug("[INFORMANTI] abort: cooldown."); if (!_busyMsgSent) { DonMessaging.SendDon("Our friends need time to sniff around. Check back later."); _busyMsgSent = true; } return false; } Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null) { NDLog.Debug("[INFORMANTI] abort: no local player."); return false; } Vector3 position = ((Component)local).transform.position; _stash = PickEmptyStash(); if (_stash == null) { NDLog.Debug("[INFORMANTI] abort: no stash drop pickable."); DonMessaging.SendDon("The informant came up empty. Later."); return false; } _amount = 2000 + _rng.Next(0, 21) * 100; if (!TryPickNoteSpot(position, out var spot)) { NDLog.Debug("[INFORMANTI] abort: no note spot (doors in ring?)."); DonMessaging.SendDon("No safe spot for a note right now. Later."); return false; } if (!SpawnNote(spot)) { NDLog.Debug("[INFORMANTI] abort: SpawnNote failed."); DonMessaging.SendDon("The informant got cold feet. Later."); return false; } _state = State.NotePlaced; _noteExpiresAt = Time.time + 900f; _lootSpawned = false; _busyMsgSent = false; InformantiMarkerQuest.EnsureCreated("Informanti: a note is waiting for you", spot); BossMarkerSync.Set("Informanti: follow the marker to the note", spot, 1); DonMessaging.SendDon("One of our friends left a note for you — pinned near a doorway " + DirectionHint(position, spot) + ". The marker's on your map. Read it before the rain does."); NDLog.Info($"[INFORMANTI] note placed {Vector3.Distance(spot, position):F0}m away; stash='{_stash.Name}' ${_amount}."); return true; } catch (Exception ex) { NDLog.Warn("Informanti.StartFromChat: " + ex.Message); AbortQuiet(removeLoot: false); return false; } } private static PizzoDropPicker.DropChoice PickEmptyStash() { for (int i = 0; i < 10; i++) { PizzoDropPicker.DropChoice dropChoice = PizzoDropPicker.PickRandom(_rng); if (dropChoice == null) { return null; } DeadDrop val = DeadDropCashHelper.FindDropByGuid(dropChoice.DropGuid); if (!((Object)(object)val == (Object)null)) { bool flag = true; try { flag = DeadDropCashHelper.HasAnyCashInDrop(val); } catch { } if (!flag) { return dropChoice; } } } NDLog.Debug("[INFORMANTI] abort: all reachable dead drops already contain cash (player stash?)."); return null; } private static bool TryPickNoteSpot(Vector3 around, out Vector3 spot) { //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_00f8: 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_006e: 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_0073: 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_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) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) spot = around; try { StaticDoor[] array = Object.FindObjectsOfType(); if (array == null || array.Length == 0) { return false; } List list = new List(); for (int i = 0; i < array.Length; i++) { try { StaticDoor val = array[i]; if ((Object)(object)val == (Object)null) { continue; } Transform accessPoint = val.AccessPoint; Vector3 val2 = (((Object)(object)accessPoint != (Object)null) ? accessPoint.position : ((Component)val).transform.position); if (!DoorLocator.IsLikelySewer(val2)) { float num = Vector3.Distance(val2, around); if (!(num < 40f) && !(num > 170f)) { list.Add(val2); } } } catch { } } if (list.Count == 0) { return false; } spot = list[_rng.Next(list.Count)]; return true; } catch (Exception ex) { NDLog.DebugWarn("TryPickNoteSpot: " + ex.Message); return false; } } private static GameObject BuildNoteVisual(Vector3 pos, string objName) { //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_0165: 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_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_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_0065: 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) GameObject val = null; try { DocumentOpener val2 = Object.FindObjectOfType(true); if ((Object)(object)val2 != (Object)null) { val = ((Component)val2).gameObject; } } catch { } GameObject val3; if ((Object)(object)val != (Object)null) { val3 = Object.Instantiate(val, pos + Vector3.up * 0.02f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f) * val.transform.rotation); ((Object)val3).name = objName; val3.SetActive(true); try { DocumentOpener[] componentsInChildren = val3.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } } catch { } try { InteractableObject[] componentsInChildren2 = val3.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Object.Destroy((Object)(object)componentsInChildren2[j]); } } catch { } NDLog.Debug("[INFORMANTI] cloned vanilla note ('" + ((Object)val).name + "') for '" + objName + "'."); } else { NDLog.DebugWarn("[INFORMANTI] no DocumentOpener in the scene — fallback primitive."); val3 = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val3).name = objName; val3.transform.position = pos + Vector3.up * 0.03f; val3.transform.localScale = new Vector3(0.22f, 0.012f, 0.3f); val3.transform.rotation = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f); try { val3.layer = LayerMask.NameToLayer("Default"); } catch { } PropVisuals.Apply(val3, new Color(0.93f, 0.91f, 0.84f)); } try { if ((Object)(object)val3.GetComponentInChildren(true) == (Object)null) { val3.AddComponent(); } } catch { } return val3; } private static bool SpawnNote(Vector3 pos) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) try { _note = BuildNoteVisual(pos, "Ndrangheta_InformantiNote"); InteractableObject val = _note.AddComponent(); val.SetMessage("Read note"); val.SetInteractionType((EInteractionType)0); val.SetInteractableState((EInteractableState)0); val.MaxInteractionRange = 3.5f; val.RequiresUniqueClick = true; val.Priority = 1; val.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)OnNoteRead)); return true; } catch (Exception ex) { NDLog.Warn("[INFORMANTI] SpawnNote: " + ex.Message); DestroyNote(); return false; } } private static void OnNoteRead() { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) try { if (_state != State.NotePlaced) { return; } DeadDrop val = DeadDropCashHelper.FindDropByGuid(_stash.DropGuid); if ((Object)(object)val == (Object)null || !DeadDropCashHelper.SpawnCashInDrop(val, _amount)) { DonMessaging.SendDon("The tip was stale — stash is already gone. No harm done."); AbortQuiet(removeLoot: false); LuckyChatController.RefreshIfHandoverActive(); return; } _lootSpawned = true; try { Singleton.Instance.ShowHint("

From a friend\nThe Benzies keep a cash stash at " + _stash.Name + ".\nNobody's watching it for the next few minutes. Take everything.\nBurn this note. — V.", 0f, (string)null); } catch (Exception ex) { NDLog.DebugWarn("[INFORMANTI] ShowHint: " + ex.Message); } DestroyNote(); _state = State.Raid; _raidEndsAt = Time.time + 180f; _pollCd = 0f; InformantiMarkerQuest.SetText("Informanti: empty the Benzies stash — 3 minutes!"); InformantiMarkerQuest.MoveTo(_stash.Position); BossMarkerSync.Set("Informanti: empty the Benzies stash — 3 minutes!", _stash.Position); SpawnBenzieGuards(_stash.Position); DonMessaging.SendDon("So the Benzies park cash at " + _stash.Name + ". Three minutes, boss — empty it before they move it. Watch yourself, they left men on it."); NDLog.Info($"[INFORMANTI] note read — raid started ({_stash.Name}, ${_amount}, {180f}s)."); } catch (Exception ex2) { NDLog.Warn("[INFORMANTI] OnNoteRead: " + ex2.Message); } } public static void Tick(float dt) { if (_state == State.Idle) { return; } if (!SessionGate.IsAuthority) { AbortQuiet(removeLoot: true); return; } if (_state == State.NotePlaced) { if (!(Time.time > _noteExpiresAt)) { return; } DonMessaging.SendDon("The note's gone — wind, rain, who knows. The informant will try again."); AbortQuiet(removeLoot: false); _cooldownUntil = Time.time + 60f; try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } _pollCd -= dt; if (!(_pollCd > 0f)) { _pollCd = 1f; try { BossMarkerSync.SetRaidSeconds(Mathf.CeilToInt(Mathf.Max(0f, _raidEndsAt - Time.time))); } catch { } TickBenzieGuards(); DeadDrop val = DeadDropCashHelper.FindDropByGuid(_stash.DropGuid); if ((Object)(object)val == (Object)null) { Finish(success: false, removeLoot: false); } else if (!DeadDropCashHelper.HasAnyCashInDrop(val)) { Finish(success: true, removeLoot: false); } else if (Time.time > _raidEndsAt) { Finish(success: false, removeLoot: true); } } } private static void Finish(bool success, bool removeLoot) { if (removeLoot && _lootSpawned) { try { DeadDrop val = DeadDropCashHelper.FindDropByGuid(_stash.DropGuid); if ((Object)(object)val != (Object)null) { DeadDropCashHelper.RemoveAllCashFromDrop(val); } } catch { } } try { DonMessaging.SendDon(success ? "Clean sweep. The Benzies will be counting fingers over that one." : "The Benzies moved the stash before we got it all, boss. We'll get the next tip faster."); } catch { } if (success) { try { if (SessionGate.IsAuthority) { FaidaState.RecordWin(); } } catch { } } DespawnBenzieGuards(); try { InformantiMarkerQuest.CompleteAndClear(); } catch { } try { BossMarkerSync.Clear(); } catch { } try { LuckyChatController.RefreshIfHandoverActive(); } catch { } _cooldownUntil = Time.time + 240f; _state = State.Idle; _lootSpawned = false; _busyMsgSent = false; NDLog.Info($"[INFORMANTI] finished (success={success})."); } private static void DestroyNote() { try { if ((Object)(object)_note != (Object)null) { Object.Destroy((Object)(object)_note); } } catch { } _note = null; try { if ((Object)(object)_noteBeacon != (Object)null) { Object.Destroy((Object)(object)_noteBeacon); } } catch { } _noteBeacon = null; } private static void SpawnNoteBeacon(Vector3 pos) { //IL_0027: 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_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_005b: 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) try { _noteBeacon = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)_noteBeacon).name = "Ndrangheta_InformantiBeacon"; _noteBeacon.transform.position = pos + Vector3.up * 1.1f; _noteBeacon.transform.localScale = new Vector3(0.12f, 1.1f, 0.12f); try { Collider component = _noteBeacon.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = true; } } catch { } PropVisuals.Apply(_noteBeacon, new Color(0.95f, 0.12f, 0.1f)); } catch (Exception ex) { NDLog.DebugWarn("[INFORMANTI] SpawnNoteBeacon: " + ex.Message); } } private static string DirectionHint(Vector3 from, Vector3 to) { //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_0004: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = to - from; val.y = 0f; int num = Mathf.Max(10, Mathf.RoundToInt(((Vector3)(ref val)).magnitude / 10f) * 10); float num2 = Mathf.Atan2(val.x, val.z) * 57.29578f; if (num2 < 0f) { num2 += 360f; } string[] array = new string[8] { "north", "north-east", "east", "south-east", "south", "south-west", "west", "north-west" }; string arg = array[Mathf.RoundToInt(num2 / 45f) % 8]; return $"about {num}m to the {arg}"; } catch { return "close by"; } } internal static void ClientShowNote(Vector3 pos) { //IL_0078: 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_0021: 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_002c: 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_003b: 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_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) try { if ((Object)(object)_clientNote != (Object)null) { Vector3 val = _clientNote.transform.position - (pos + Vector3.up * 0.03f); if (((Vector3)(ref val)).sqrMagnitude > 1f) { _clientNote.transform.position = pos + Vector3.up * 0.03f; } return; } _clientNote = BuildNoteVisual(pos, "Ndrangheta_InformantiNote_Client"); InteractableObject val2 = _clientNote.AddComponent(); val2.SetMessage("Read note"); val2.SetInteractionType((EInteractionType)0); val2.SetInteractableState((EInteractableState)0); val2.MaxInteractionRange = 3.5f; val2.RequiresUniqueClick = true; val2.Priority = 1; val2.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)OnClientNoteRead)); NDLog.Debug("[INFORMANTI] client note prop spawned."); } catch (Exception ex) { NDLog.DebugWarn("[INFORMANTI] ClientShowNote: " + ex.Message); } } internal static void ClientHideNote() { try { if ((Object)(object)_clientNote != (Object)null) { Object.Destroy((Object)(object)_clientNote); } } catch { } _clientNote = null; } private static void OnClientNoteRead() { try { ClientHideNote(); ClientActionNet.SendAction("readnote", ""); NDLog.Debug("[INFORMANTI] client read the note — sent 'readnote' to host."); } catch (Exception ex) { NDLog.DebugWarn("[INFORMANTI] OnClientNoteRead: " + ex.Message); } } public static void NotifyClientRead() { try { if (SessionGate.IsAuthority && _state == State.NotePlaced) { NDLog.Info("[INFORMANTI] client read the note — starting the raid."); OnNoteRead(); } } catch (Exception ex) { NDLog.DebugWarn("[INFORMANTI] NotifyClientRead: " + ex.Message); } } private static void AbortQuiet(bool removeLoot) { if (removeLoot && _lootSpawned) { try { DeadDrop val = ((_stash != null) ? DeadDropCashHelper.FindDropByGuid(_stash.DropGuid) : null); if ((Object)(object)val != (Object)null) { DeadDropCashHelper.RemoveAllCashFromDrop(val); } } catch { } } DestroyNote(); DespawnBenzieGuards(); try { InformantiMarkerQuest.CompleteAndClear(); } catch { } try { BossMarkerSync.Clear(); } catch { } _state = State.Idle; _lootSpawned = false; _busyMsgSent = false; } private static void SpawnBenzieGuards(Vector3 center) { //IL_008e: 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_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) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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) //IL_014e: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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) try { if ((Object)(object)_guardPool == (Object)null) { _guardPool = Object.FindObjectOfType(true); } if ((Object)(object)_guardPool == (Object)null) { NDLog.DebugWarn("[INFORMANTI] no GoonPool — no Benzie guards."); return; } int num = 2 + _rng.Next(0, 2); int num2 = _guardPool.UnspawnedGoonCount - 1; int num3 = Mathf.Clamp(num, 0, num2); if (num3 <= 0) { NDLog.DebugWarn($"[INFORMANTI] GoonPool too empty for Benzie guards (avail={num2})."); return; } Vector3 val = NavSnap(center, 8f); List list = _guardPool.SpawnMultipleGoons(val, num3, false); if (list == null) { NDLog.DebugWarn("[INFORMANTI] SpawnMultipleGoons returned null."); return; } for (int i = 0; i < list.Count; i++) { CartelGoon val2 = list[i]; if (!((Object)(object)val2 == (Object)null)) { LuckyBrawlManager.GoonDefaults item = LuckyBrawlManager.CaptureGoonDefaults(val2); ArmBenzie(val2); float num4 = 360f / (float)Mathf.Max(1, list.Count) * (float)i + (float)(_rng.NextDouble() * 30.0 - 15.0); Vector3 pos = NavSnap(val + Quaternion.Euler(0f, num4, 0f) * Vector3.forward * (1.6f + (float)_rng.NextDouble() * 1.4f), 4f); float faceYaw = num4; BenzieStandGuard(val2, pos, faceYaw); _benzies.Add(val2); _benzieDefaults.Add(item); } } NDLog.Debug($"[INFORMANTI] {_benzies.Count} armed Benzie guard(s) posted at {_stash?.Name}."); } catch (Exception ex) { NDLog.Warn("[INFORMANTI] SpawnBenzieGuards: " + ex.Message); } } private static void ArmBenzie(CartelGoon g) { try { CombatBehaviour val = ((g == null) ? null : ((NPC)g).Behaviour?.CombatBehaviour); if ((Object)(object)val == (Object)null) { return; } try { val.SetDefaultWeapon(LuckyWeaponVisual.LoadAvatarWeaponByPath("Avatar/Equippables/PumpShotgun")); } catch { } try { val.GiveUpRange = 60f; } catch { } try { val.DefaultSearchTime = 9999f; } catch { } try { val.SetWeapon("Avatar/Equippables/PumpShotgun"); } catch { } } catch { } } private static void BenzieStandGuard(CartelGoon g, Vector3 pos, float faceYaw) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)((g != null) ? ((Component)g).gameObject : null) == (Object)null) { return; } try { NPCScheduleManager componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { movement.Stop(); } catch { } try { movement.PauseMovement(); } catch { } } try { if ((Object)(object)((Component)g).transform != (Object)null) { ((Component)g).transform.position = pos; ((Component)g).transform.rotation = Quaternion.Euler(0f, faceYaw, 0f); } } catch { } } catch { } } private static void BenzieMakeReady(CartelGoon g) { try { NPCMovement val = ((g != null) ? ((NPC)g).Movement : null); if ((Object)(object)val != (Object)null) { try { val.ResumeMovement(); } catch { } try { val.SetAgentEnabled(true); } catch { } try { ((Behaviour)val).enabled = true; } catch { } } try { NPCBehaviour behaviour = ((NPC)g).Behaviour; if ((Object)(object)behaviour != (Object)null && !((Behaviour)behaviour).enabled) { ((Behaviour)behaviour).enabled = true; } } catch { } } catch { } } private static void TickBenzieGuards() { if (_benzies.Count == 0) { return; } for (int num = _benzies.Count - 1; num >= 0; num--) { bool flag = false; try { flag = (Object)(object)_benzies[num] != (Object)null && _benzies[num].IsGoonSpawned; } catch { } if (!flag) { try { LuckyBrawlManager.RestoreGoonDefaults(_benzies[num], (num < _benzieDefaults.Count) ? _benzieDefaults[num] : null); } catch { } _benzies.RemoveAt(num); if (num < _benzieDefaults.Count) { _benzieDefaults.RemoveAt(num); } } } for (int i = 0; i < _benzies.Count; i++) { CartelGoon val = _benzies[i]; if ((Object)(object)val == (Object)null) { continue; } bool flag2 = false; try { NPCHealth health = ((NPC)val).Health; flag2 = (Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut; } catch { flag2 = true; } if (!flag2) { Player val2 = NearestPlayerInSight(val, 22f); if (!((Object)(object)val2 == (Object)null)) { BenzieMakeReady(val); AttackPlayer(val, val2); } } } } private static Player NearestPlayerInSight(CartelGoon g, float range) { //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_00df: 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) try { if ((Object)(object)((g != null) ? ((Component)g).transform : null) == (Object)null) { return null; } Vector3 position = ((Component)g).transform.position; List playerList = Player.PlayerList; if (playerList == null) { return null; } Player result = null; float num = range * range; for (int i = 0; i < playerList.Count; i++) { Player val = playerList[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } try { if (val.IsArrested) { continue; } } catch { } try { if ((Object)(object)val.Health != (Object)null && !val.Health.IsAlive) { continue; } } catch { } Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } return result; } catch { return null; } } private static void AttackPlayer(CartelGoon attacker, Player victim) { try { ICombatTargetable val = GameCompat.CastTargetable((object)victim); if (val != null) { bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (flag) { attacker.AttackEntity(val, false); } } } catch { } } private static void DespawnBenzieGuards() { for (int i = 0; i < _benzies.Count; i++) { CartelGoon val = _benzies[i]; if ((Object)(object)val == (Object)null) { continue; } try { LuckyBrawlManager.RestoreGoonDefaults(val, (i < _benzieDefaults.Count) ? _benzieDefaults[i] : null); } catch { } bool flag = false; try { flag = val.IsGoonSpawned; } catch { } if (flag) { try { val.Despawn(); } catch { } } } _benzies.Clear(); _benzieDefaults.Clear(); } private static Vector3 NavSnap(Vector3 p, float maxDist) { //IL_0002: 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_0023: 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_0026: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(p, ref val, maxDist, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return p; } public static void OnGUI() { //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_0082: 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_0097: Expected O, but got Unknown //IL_00fd: 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_00bd: 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_00d2: Expected O, but got Unknown //IL_0143: 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) try { int num; if (SessionGate.IsAuthority) { if (_state != State.Raid) { return; } num = Mathf.CeilToInt(Mathf.Max(0f, _raidEndsAt - Time.time)); } else { num = QuestNetSync.RemoteRaidSeconds; if (num <= 0) { return; } } if (_raidHudStyle == null) { _raidHudStyle = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } if (_raidTimerStyle == null) { _raidTimerStyle = new GUIStyle(GUI.skin.label) { fontSize = 30, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } float num2 = 660f; float x = ((float)Screen.width - num2) * 0.5f; DrawRaidShadowed("INFORMANTI — EMPTY THE BENZIES STASH", x, 72f, num2, 40f, _raidHudStyle, RAID_GOLD); string text = $"{num / 60}:{num % 60:00}"; DrawRaidShadowed(text, x, 112f, num2, 44f, _raidTimerStyle, (num <= 10) ? RAID_RED : RAID_GOLD); } catch { } } private static void DrawRaidShadowed(string text, float x, float y, float w, float h, GUIStyle style, Color fill) { //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_001b: 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_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.Label(new Rect(x + 2f, y + 2f, w, h), text, style); GUI.color = fill; GUI.Label(new Rect(x, y, w, h), text, style); GUI.color = color; } } internal static class IntroController { public const float MeetRadius = 4f; private const float HEARTBEAT_INTERVAL = 0.5f; private static float _hbTimer; public static void ResetForSceneReload() { _hbTimer = 0f; RecruitmentState.ResetForSceneReload(); } public static void Tick(float deltaTime) { _hbTimer -= deltaTime; if (_hbTimer > 0f) { return; } _hbTimer = 0.5f; try { Step1_UnlockAndSendWelcome(); Step2_StartIntroQuest(); Step3_CheckMeetProximity(); } catch (Exception ex) { NDLog.DebugWarn("IntroController.Tick: " + ex.Message); } } private static void Step1_UnlockAndSendWelcome() { if (RecruitmentState.WelcomeSmsSent) { if (!RecruitmentState.ConversationReady && DonMessaging.ResolveConversation() != null) { RecruitmentState.ConversationReady = true; } DonMessaging.PatchAsSupplier(); } else if (!((Object)(object)DonMessaging.ResolveGameNpc() == (Object)null) && DonMessaging.SendWelcomeIfNotYet()) { RecruitmentState.ConversationReady = true; DonMessaging.PatchAsSupplier(); } } private static void Step2_StartIntroQuest() { if (RecruitmentState.WelcomeSmsSent && !RecruitmentState.HasMetDon) { IntroQuest.EnsureStarted(); } } private static void Step3_CheckMeetProximity() { //IL_0082: 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_00a4: 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_00c6: 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) if (!RecruitmentState.WelcomeSmsSent || RecruitmentState.HasMetDon) { return; } NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc == (Object)null || (Object)(object)((Component)cachedGameNpc).transform == (Object)null) { return; } Player local = Player.Local; if (!((Object)(object)local == (Object)null) && !((Object)(object)((Component)local).transform == (Object)null)) { float num = ((Component)local).transform.position.x - ((Component)cachedGameNpc).transform.position.x; float num2 = ((Component)local).transform.position.z - ((Component)cachedGameNpc).transform.position.z; float num3 = ((Component)local).transform.position.y - ((Component)cachedGameNpc).transform.position.y; num3 *= num3; float num4 = num * num + num2 * num2 + num3 * 0.25f; if (!(num4 > 16f)) { NDLog.Debug($"Player met Don (dist={Mathf.Sqrt(num4):F1}m)."); CompleteMeet(); } } } public static void NotifyClientMet() { try { if (SessionGate.IsAuthority && !RecruitmentState.HasMetDon && RecruitmentState.WelcomeSmsSent) { NDLog.Info("[INTRO] client reached the Don — recruiting the famiglia."); CompleteMeet(); } } catch (Exception ex) { NDLog.Warn("IntroController.NotifyClientMet: " + ex.Message); } } private static void CompleteMeet() { DonMessaging.SendMeetGreetingIfNotYet(); IntroQuest.CompleteOnPlayerProximity(); RecruitmentState.Recruited = true; try { NdranghetaSaveData.Instance?.PushNow(); } catch { } } } public static class ItemCatalog { public enum Legality { Legal, Restricted, Illegal } public enum Category { Drug, Weapon, Station, Furniture, Misc } public sealed class Entry { public string Id; public string DisplayName; public Category Cat; public Legality Legal; public int ApproxPrice; public EDrugType? DrugType; public string Notes; } public static readonly Entry[] Drugs = new Entry[9] { new Entry { Id = "ogkush", DisplayName = "OG Kush", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 38, DrugType = (EDrugType)0, Notes = "Vanilla strain, Default $38." }, new Entry { Id = "sourdiesel", DisplayName = "Sour Diesel", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 40, DrugType = (EDrugType)0, Notes = "Vanilla strain, Default $40." }, new Entry { Id = "greencrack", DisplayName = "Green Crack", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 43, DrugType = (EDrugType)0, Notes = "Vanilla strain, Default $43." }, new Entry { Id = "granddaddypurple", DisplayName = "Granddaddy Purple", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 44, DrugType = (EDrugType)0, Notes = "Vanilla strain, Default $44." }, new Entry { Id = "meth", DisplayName = "Methamphetamine", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 70, DrugType = (EDrugType)1, Notes = "Default $70. Moderate severity (PossessingModerateSeverityDrug)." }, new Entry { Id = "cocaine", DisplayName = "Cocaine", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 150, DrugType = (EDrugType)2, Notes = "Default $150. High severity drug." }, new Entry { Id = "mdma", DisplayName = "MDMA", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 0, DrugType = (EDrugType)3, Notes = "Enum-Eintrag, Vanilla-Item-ID nicht bestaetigt." }, new Entry { Id = "shrooms", DisplayName = "Magic Shrooms", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 0, DrugType = (EDrugType)4, Notes = "Enum-Eintrag, ID variiert (siehe ShroomProductData)." }, new Entry { Id = "heroin", DisplayName = "Heroin", Cat = Category.Drug, Legal = Legality.Illegal, ApproxPrice = 0, DrugType = (EDrugType)5, Notes = "Enum-Eintrag, Vanilla-Item-ID nicht bestaetigt." } }; public static readonly Entry[] Weapons = new Entry[6] { new Entry { Id = "revolver", DisplayName = "Revolver", Cat = Category.Weapon, Legal = Legality.Illegal, ApproxPrice = 0, Notes = "Contratto-Waffe. Spawnt im Famiglia-Stash." }, new Entry { Id = "m1911", DisplayName = "M1911 Pistol", Cat = Category.Weapon, Legal = Legality.Illegal, ApproxPrice = 0, Notes = "Revolver-Fallback." }, new Entry { Id = "pistol", DisplayName = "Pistol", Cat = Category.Weapon, Legal = Legality.Illegal, ApproxPrice = 0, Notes = "Generischer Pistol-Fallback." }, new Entry { Id = "baseballbat", DisplayName = "Baseball Bat", Cat = Category.Weapon, Legal = Legality.Restricted, ApproxPrice = 0, Notes = "Nahkampf, technisch legal." }, new Entry { Id = "machete", DisplayName = "Machete", Cat = Category.Weapon, Legal = Legality.Restricted, ApproxPrice = 0, Notes = "Nahkampf, drohende Sichtbarkeit." }, new Entry { Id = "pumpshotgun", DisplayName = "Pumpaction Shotgun", Cat = Category.Weapon, Legal = Legality.Illegal, ApproxPrice = 0, Notes = "FIX-080 (#8): verifizierte vanilla-ID (User) — Raterei entfernt." } }; public static readonly Entry[] ExpensiveStations = new Entry[6] { new Entry { Id = "brickpress", DisplayName = "Brick Press", Cat = Category.Station, Legal = Legality.Restricted, Notes = "Verarbeitung, Mid-Tier teuer." }, new Entry { Id = "chemistrystation", DisplayName = "Chemistry Station", Cat = Category.Station, Legal = Legality.Restricted, Notes = "Meth/Cocaine-Synthese — Use ist illegal." }, new Entry { Id = "cauldron", DisplayName = "Cauldron", Cat = Category.Station, Legal = Legality.Restricted, Notes = "Cocaine-Pipeline." }, new Entry { Id = "labovenmk2", DisplayName = "Lab Oven Mk2", Cat = Category.Station, Legal = Legality.Restricted, Notes = "Upgrade-Tier, hochpreisig." }, new Entry { Id = "mixingstationmk2", DisplayName = "Mixing Station Mk2", Cat = Category.Station, Legal = Legality.Restricted, Notes = "Premium-Mixing." }, new Entry { Id = "packagingstationmk2", DisplayName = "Packaging Station Mk2", Cat = Category.Station, Legal = Legality.Legal, Notes = "Upgrade-Variante." } }; private static Dictionary _byId; private static readonly object _lock = new object(); public static IReadOnlyDictionary ById { get { if (_byId != null) { return _byId; } lock (_lock) { if (_byId != null) { return _byId; } Dictionary d = new Dictionary(StringComparer.OrdinalIgnoreCase); Add(Drugs); Add(Weapons); Add(ExpensiveStations); _byId = d; void Add(Entry[] arr) { foreach (Entry entry in arr) { if (!string.IsNullOrEmpty(entry.Id) && !d.ContainsKey(entry.Id)) { d.Add(entry.Id, entry); } } } } return _byId; } } public static Entry GetById(string id) { if (string.IsNullOrEmpty(id)) { return null; } ById.TryGetValue(id, out var value); return value; } public static bool IsIllegal(string id) { Entry byId = GetById(id); return byId != null && byId.Legal == Legality.Illegal; } public static IEnumerable AllIllegal() { foreach (Entry e in ById.Values) { if (e.Legal == Legality.Illegal) { yield return e; } } } public static IEnumerable ByCategory(Category c) { foreach (Entry e in ById.Values) { if (e.Cat == c) { yield return e; } } } public static IEnumerable ByDrugType(EDrugType type) { //IL_0008: 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) foreach (Entry e in ById.Values) { if (e.DrugType.HasValue && e.DrugType.Value == type) { yield return e; } } } public static bool ExistsInRegistry(string id) { if (string.IsNullOrEmpty(id)) { return false; } try { return (Object)(object)Registry.GetItem(id) != (Object)null; } catch { return false; } } public static int GetRuntimePrice(string id) { if (string.IsNullOrEmpty(id)) { return 0; } try { ItemDefinition item = Registry.GetItem(id); if ((Object)(object)item == (Object)null) { return 0; } ProductDefinition val = GameCompat.Cast((Object)(object)item); if ((Object)(object)val != (Object)null) { try { ProductManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null && instance.ProductPrices != null && instance.ProductPrices.ContainsKey(val)) { return (int)instance.ProductPrices[val]; } } catch { } try { return (int)val.MarketValue; } catch { } try { return (int)val.Price; } catch { } } StorableItemDefinition val2 = GameCompat.Cast((Object)(object)item); if ((Object)(object)val2 != (Object)null) { try { return (int)val2.BasePurchasePrice; } catch { } } } catch { } return 0; } public static IEnumerable GetSmuggleRotationForRank(Rank rank) { switch (rank) { case Rank.Soldato: yield return GetById("ogkush"); yield return GetById("sourdiesel"); yield return GetById("greencrack"); yield return GetById("granddaddypurple"); break; case Rank.Capodecina: yield return GetById("cocaine"); break; case Rank.Sottocapo: yield return GetById("revolver"); yield return GetById("m1911"); yield return GetById("pistol"); yield return GetById("machete"); yield return GetById("pumpshotgun"); break; } } public static IEnumerable GetResolvableSmuggleRotation(Rank rank) { foreach (Entry e in GetSmuggleRotationForRank(rank)) { if (e != null && ExistsInRegistry(e.Id)) { yield return e; } } } public static IEnumerable<(string Id, int Price, ItemDefinition Def)> EnumerateExpensive(int minPrice) { Registry instance = Singleton.Instance; List all = ((instance != null) ? instance.GetAllItems() : null); if (all == null) { yield break; } for (int i = 0; i < all.Count; i++) { ItemDefinition def = null; try { def = all[i]; } catch { } if ((Object)(object)def == (Object)null) { continue; } string id = null; try { id = ((BaseItemDefinition)def).ID; } catch { } if (!string.IsNullOrEmpty(id)) { int price = GetRuntimePrice(id); if (price >= minPrice) { yield return (Id: id, Price: price, Def: def); } } } } } internal static class KidnapSackItem { private const string IconResource = "Ndrangheta.assets.trunk.kidnap-sack.png"; private const string SACK_ID = "ndrangheta_kidnap_sack"; private static StorableItemDefinition _def; private static readonly string[] KNOWN_SIMPLE = new string[8] { "bomb", "cuke", "wateringcan", "trashbag", "soil", "donut", "chips", "jar" }; private static StorableItemDefinition EnsureDef() { //IL_004c: 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) if ((Object)(object)_def == (Object)null) { try { StorableItemDefinition val = FindSourceStorable(); if ((Object)(object)val == (Object)null) { NDLog.Warn("[KIDNAP-SACK] no StorableItemDefinition in the registry — no sack item."); return null; } StorableItemDefinition val2 = Object.Instantiate(val); Object.DontDestroyOnLoad((Object)(object)val2); ((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20); ((Object)val2).name = "Ndrangheta_KidnapSack"; try { ((BaseItemDefinition)val2).ID = "ndrangheta_kidnap_sack"; } catch (Exception ex) { NDLog.DebugWarn("[KIDNAP-SACK] ID set: " + ex.Message); } NDLog.Debug("[KIDNAP-SACK] DIAG clone.ID after set = '" + TryId((ItemDefinition)(object)val2) + "' (expected 'ndrangheta_kidnap_sack')."); try { ((BaseItemDefinition)val2).Name = "Captive"; } catch { } try { ((BaseItemDefinition)val2).Description = "There's someone in here. Don't let them out."; } catch { } try { ((ItemDefinition)val2).CustomItemUI = null; } catch (Exception ex2) { NDLog.DebugWarn("[KIDNAP-SACK] CustomItemUI clear: " + ex2.Message); } try { ((ItemDefinition)val2).Equippable = null; } catch { } try { val2.BasePurchasePrice = 0f; val2.ResellMultiplier = 0f; } catch { } Sprite val3 = AssetLoader.LoadSprite("Ndrangheta.assets.trunk.kidnap-sack.png"); if ((Object)(object)val3 != (Object)null) { try { ((BaseItemDefinition)val2).Icon = val3; } catch (Exception ex3) { NDLog.DebugWarn("[KIDNAP-SACK] Icon set: " + ex3.Message); } } else { NDLog.Warn("[KIDNAP-SACK] icon 'Ndrangheta.assets.trunk.kidnap-sack.png' not loaded — sack uses the source icon."); } _def = val2; NDLog.Debug("[KIDNAP-SACK] clone definition built (ID=ndrangheta_kidnap_sack)."); } catch (Exception ex4) { NDLog.Warn("[KIDNAP-SACK] EnsureDef: " + ex4.Message); } } try { if ((Object)(object)_def != (Object)null && (Object)(object)Registry.GetItem("ndrangheta_kidnap_sack") == (Object)null) { Singleton.Instance.AddToRegistry((ItemDefinition)(object)_def); NDLog.Debug("[KIDNAP-SACK] AddToRegistry called."); } } catch (Exception ex5) { NDLog.Warn("[KIDNAP-SACK] AddToRegistry ERROR: " + ex5.Message); } bool flag = false; try { flag = (Object)(object)Registry.GetItem("ndrangheta_kidnap_sack") != (Object)null; } catch { } NDLog.Debug("[KIDNAP-SACK] DIAG Registry.GetItem('ndrangheta_kidnap_sack') -> " + (flag ? "FOUND" : "NULL") + "."); return _def; } private static string TryId(ItemDefinition d) { try { return ((Object)(object)d != (Object)null) ? (((BaseItemDefinition)d).ID ?? "") : ""; } catch { return ""; } } public static void EnsureRegistered() { try { EnsureDef(); } catch (Exception ex) { NDLog.DebugWarn("[KIDNAP-SACK] EnsureRegistered: " + ex.Message); } } public static void EnsureUnlocked(StorageEntity storage) { if ((Object)(object)storage == (Object)null || (Object)(object)_def == (Object)null) { return; } try { List itemSlots = storage.ItemSlots; if (itemSlots == null) { return; } for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val; try { val = itemSlots[i]; } catch { continue; } if (val == null) { continue; } ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance == null) { continue; } ItemDefinition definition; try { definition = itemInstance.Definition; } catch { continue; } if (!((Object)(object)definition != (Object)null) || !GameCompat.SameInstance((object)definition, (object)_def)) { continue; } try { if (val.IsRemovalLocked) { val.SetIsRemovalLocked(false); } } catch { } try { if (val.IsAddLocked) { val.SetIsAddLocked(false); } } catch { } } } catch { } } private static StorableItemDefinition FindSourceStorable() { for (int i = 0; i < KNOWN_SIMPLE.Length; i++) { try { StorableItemDefinition val = GameCompat.Cast((Object)(object)Registry.GetItem(KNOWN_SIMPLE[i])); if ((Object)(object)val != (Object)null) { NDLog.Debug("[KIDNAP-SACK] source item = '" + KNOWN_SIMPLE[i] + "' (known-simple)."); return val; } } catch { } } StorableItemDefinition val2 = null; StorableItemDefinition val3 = null; try { Registry instance = Singleton.Instance; List list = ((instance != null) ? instance.GetAllItems() : null); if (list == null) { return null; } for (int j = 0; j < list.Count; j++) { ItemDefinition val4 = null; try { val4 = list[j]; } catch { continue; } if ((Object)(object)val4 == (Object)null) { continue; } StorableItemDefinition val5 = GameCompat.Cast((Object)(object)val4); if (!((Object)(object)val5 == (Object)null)) { if ((Object)(object)val3 == (Object)null) { val3 = val5; } bool flag = false; bool flag2 = false; try { flag = (Object)(object)val5.StoredItem != (Object)null; } catch { } try { flag2 = (Object)(object)((BaseItemDefinition)val5).Icon != (Object)null; } catch { } if (flag && flag2) { return val5; } if (flag && (Object)(object)val2 == (Object)null) { val2 = val5; } } } } catch { } return val2 ?? val3; } public static bool Insert(StorageEntity storage) { if ((Object)(object)storage == (Object)null) { return false; } try { StorableItemDefinition val = EnsureDef(); if ((Object)(object)val == (Object)null) { return false; } StorableItemDefinition val2 = null; try { val2 = GameCompat.Cast((Object)(object)Registry.GetItem("ndrangheta_kidnap_sack")); } catch { } if ((Object)(object)val2 == (Object)null) { NDLog.Warn("[KIDNAP-SACK] Registry.GetItem('ndrangheta_kidnap_sack')==null → using clone directly (moving may fail)."); val2 = val; } ItemSlot val3 = FindEmptySlot(storage); if (val3 == null) { NDLog.Warn("[KIDNAP-SACK] no free trunk slot."); return false; } try { NDLog.Debug($"[KIDNAP-SACK] DIAG slot BEFORE insert: locked={val3.IsLocked} removalLocked={val3.IsRemovalLocked}"); } catch { } ItemInstance val4 = null; try { val4 = ((ItemDefinition)val2).GetDefaultInstance(1); } catch (Exception ex) { NDLog.DebugWarn("[KIDNAP-SACK] GetDefaultInstance: " + ex.Message); } if (val4 == null) { return false; } try { val3.SetStoredItem(val4, false); } catch (Exception ex2) { NDLog.DebugWarn("[KIDNAP-SACK] SetStoredItem: " + ex2.Message); return false; } try { val3.SetIsRemovalLocked(false); } catch { } try { val3.SetIsAddLocked(false); } catch { } try { ItemInstance itemInstance = val3.ItemInstance; NDLog.Debug(string.Format("[KIDNAP-SACK] DIAG slot AFTER insert: item.ID='{0}' locked={1} removalLocked={2}", (itemInstance != null) ? TryId(itemInstance.Definition) : "", val3.IsLocked, val3.IsRemovalLocked)); } catch { } NDLog.Debug("[KIDNAP-SACK] placed in the trunk."); return true; } catch (Exception ex3) { NDLog.Warn("[KIDNAP-SACK] Insert: " + ex3.Message); return false; } } public static bool IsPresent(StorageEntity storage) { if ((Object)(object)storage == (Object)null || (Object)(object)_def == (Object)null) { return false; } try { List itemSlots = storage.ItemSlots; if (itemSlots == null) { return false; } for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val; try { val = itemSlots[i]; } catch { continue; } if (val == null) { continue; } ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance != null) { ItemDefinition definition; try { definition = itemInstance.Definition; } catch { continue; } if ((Object)(object)definition != (Object)null && GameCompat.SameInstance((object)definition, (object)_def)) { return true; } } } } catch { } return false; } public static void Remove(StorageEntity storage) { if ((Object)(object)storage == (Object)null || (Object)(object)_def == (Object)null) { return; } try { List itemSlots = storage.ItemSlots; if (itemSlots == null) { return; } for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val; try { val = itemSlots[i]; } catch { continue; } if (val == null) { continue; } ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance == null) { continue; } ItemDefinition definition; try { definition = itemInstance.Definition; } catch { continue; } if ((Object)(object)definition != (Object)null && GameCompat.SameInstance((object)definition, (object)_def)) { try { val.ClearStoredInstance(false); } catch { } } } } catch { } } private static ItemSlot FindEmptySlot(StorageEntity storage) { try { List itemSlots = storage.ItemSlots; if (itemSlots == null) { return null; } for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val; try { val = itemSlots[i]; } catch { continue; } if (val != null) { ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance == null) { return val; } } } } catch { } return null; } } public static class KillDetector { public static bool IsDead(NPC npc) { if ((Object)(object)npc == (Object)null) { return false; } try { NPCHealth health = npc.Health; if ((Object)(object)health == (Object)null) { return false; } return health.IsDead; } catch { return false; } } } internal static class LaBombaManager { private enum State { Idle, Inbound, Planting, Armed } private const float FUSE_SECONDS = 45f; private const float BOMB_RADIUS = 8f; private const float BOMB_DAMAGE = 400f; private const float BOMB_PUSH = 1000f; private const float PLANT_SECONDS = 2.5f; private const float INBOUND_TIMEOUT = 60f; private const float ARRIVE_REACH = 2.5f; private const float EXIT_REACH = 3f; private const float REPATH_INTERVAL = 2f; private const int POOL_RESERVE = 1; private static State _state; private static GoonPool _pool; private static CartelGoon _courier; private static Vector3 _anchor; private static Vector3 _bombPos; private static Vector3 _exitDoor; private static bool _haveExitDoor; private static bool _courierGone; private static float _stateTimer; private static float _armedUntil; private static float _repathCd; private static float _timeSinceBeep; private static bool _blinkOn; private static GameObject _bombProp; private static AudioSourceController _bombAudio; private static bool _hasMark; private static Vector3 _markPos; private static GameObject _signalProp; private static Vector3 _entryDoor; private static LuckyBrawlManager.GoonDefaults _courierDefaults; private static GameObject _clientProp; private static bool _clientPropArmed; private static AudioSourceController _clientBombAudio; private static float _clientArmedAt; private static float _clientBeepSince; private static bool _clientBlinkOn; private static float _clientArmedSeatedY; public static bool IsActive => _state != State.Idle || _hasMark; internal static CartelGoon ActiveCourier => (_state == State.Idle) ? null : _courier; public static void ResetForSceneReload() { AbortQuiet(); try { ClientHideProp(); } catch { } } private static Player ResolveAnchorPlayer(string who) { try { if (!string.IsNullOrEmpty(who)) { List playerList = Player.PlayerList; if (playerList != null) { for (int i = 0; i < playerList.Count; i++) { Player val = playerList[i]; if (!((Object)(object)val == (Object)null)) { string text = null; try { text = val.PlayerCode; } catch { } if (text == who) { return val; } } } } NDLog.DebugWarn("[BOMBA] client '" + who + "' not resolvable — using host anchor."); } } catch { } return Player.Local; } public static void MarkSpotFromChat(string who = "") { //IL_00c9: 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_00d0: 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_00dc: 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_0115: 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_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_00a5: 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) try { if (!SessionGate.IsAuthority || !TerritoryHandover.HandoverActive) { return; } if (_state != State.Idle) { DonMessaging.SendDon("I'm still out with the last package, boss. Mark the next spot after."); return; } if (LuckyBrawlManager.IsBusy) { DonMessaging.SendDon("We're mid-brawl, boss — finish that before we scout a spot."); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } Player val = ResolveAnchorPlayer(who); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return; } Vector3 position = ((Component)val).transform.position; try { NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val2, 2.5f, -1)) { position = ((NavMeshHit)(ref val2)).position; } } catch { } position = (_markPos = GroundPos(position)); _hasMark = true; SpawnSignalProp(position); BombaMarkerQuest.EnsureCreated("Pacco Bomba: spot marked — say the word", position); try { BossMarkerSync.Set("Pacco Bomba: spot marked — say the word", position, 2); } catch { } DonMessaging.SendDon("Spot's marked, boss. Walk as far as you like — say the word and I bring the package."); NDLog.Debug($"[BOMBA] spot marked @ {position}."); } catch (Exception ex) { NDLog.Warn("LaBomba.MarkSpot: " + ex.Message); } } public static void StartFromChat(string who = "") { //IL_00de: 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_00f5: 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_0326: Unknown result type (might be due to invalid IL or missing references) //IL_025d: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: 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_01c6: 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_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0209: 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_0218: 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_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: 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_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) try { if (!SessionGate.IsAuthority || !TerritoryHandover.HandoverActive) { return; } if (_state != State.Idle) { DonMessaging.SendDon("I'm still out with the last package, boss. One at a time."); return; } if (LuckyBrawlManager.IsBusy) { DonMessaging.SendDon("We're mid-brawl, boss — finish that before we plant anything."); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } if (!_hasMark) { Player val = ResolveAnchorPlayer(who); if (!((Object)(object)val != (Object)null) || !((Object)(object)((Component)val).transform != (Object)null)) { DonMessaging.SendDon("Mark the spot first, boss — stand on it and hit 'Mark this spot'."); return; } Vector3 position = ((Component)val).transform.position; try { NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val2, 2.5f, -1)) { position = ((NavMeshHit)(ref val2)).position; } } catch { } _markPos = GroundPos(position); _hasMark = true; NDLog.Debug($"[BOMBA] no prior mark — anchoring plant at trigger player @ {_markPos}."); } _anchor = _markPos; _pool = Object.FindObjectOfType(true); if ((Object)(object)_pool != (Object)null && _pool.UnspawnedGoonCount <= 1) { try { LuckyBrawlManager.ReclaimExitGoons(); } catch { } } if ((Object)(object)_pool == (Object)null || _pool.UnspawnedGoonCount <= 1) { DonMessaging.SendDon("None of us can carry it right now, boss — we're stretched thin."); return; } if (!DoorLocator.TryGetNearestSpawnDoor(_anchor, null, out var doorPos)) { Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val3 = ((Vector2)(ref insideUnitCircle)).normalized; if (((Vector2)(ref val3)).sqrMagnitude < 0.01f) { val3 = Vector2.right; } doorPos = _anchor + new Vector3(val3.x, 0f, val3.y) * 25f; try { NavMeshHit val4 = default(NavMeshHit); if (NavMesh.SamplePosition(doorPos + Vector3.up * 1.5f, ref val4, 12f, -1)) { doorPos = ((NavMeshHit)(ref val4)).position; } } catch { } } List list = _pool.SpawnMultipleGoons(doorPos, 1, false); if (list == null || list.Count == 0 || (Object)(object)list[0] == (Object)null) { DonMessaging.SendDon("Couldn't get out the door, boss. Say it again in a moment."); return; } _courier = list[0]; PrepareCourier(_courier); _hasMark = false; _entryDoor = doorPos; _state = State.Inbound; _stateTimer = 0f; _repathCd = 0f; _courierGone = false; _haveExitDoor = false; _bombPos = _anchor; BombaMarkerQuest.EnsureCreated("Pacco Bomba: the package is on its way", _anchor); try { BossMarkerSync.Set("Pacco Bomba: the package is on its way", _anchor, 2); } catch { } DonMessaging.SendDon("Va bene, boss. I've got the package — heading for your spot now. Once I arm it: 45 seconds."); NDLog.Debug($"[BOMBA] courier dispatched: door {Vector3.Distance(doorPos, _anchor):F1} m from the spot."); } catch (Exception ex) { NDLog.Warn("LaBomba.StartFromChat: " + ex.Message); AbortQuiet(); } } private static void PrepareCourier(CartelGoon g) { try { _courierDefaults = LuckyBrawlManager.CaptureGoonDefaults(g); } catch { _courierDefaults = null; } try { NPCScheduleManager componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } try { FamigliaOutfit.Apply(g, 5, _pool); } catch { } try { LuckyBrawlManager.RenameToFamiglia(g); } catch { } try { LockCourierTriggers(g); } catch { } } private static void LockCourierTriggers(CartelGoon g) { if ((Object)(object)g == (Object)null) { return; } try { NPCBehaviour behaviour = ((NPC)g).Behaviour; if ((Object)(object)behaviour != (Object)null) { try { CombatBehaviour combatBehaviour = behaviour.CombatBehaviour; if ((Object)(object)combatBehaviour != (Object)null) { ((Behaviour)combatBehaviour).Deactivate(); } } catch { } DisableBeh((Behaviour)(object)behaviour.CombatBehaviour); DisableBeh((Behaviour)(object)behaviour.FleeBehaviour); DisableBeh((Behaviour)(object)behaviour.CoweringBehaviour); DisableBeh((Behaviour)(object)behaviour.HeavyFlinchBehaviour); try { ((Behaviour)behaviour).enabled = false; } catch { } } try { VisionCone componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } } catch { } NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { ((Behaviour)movement).enabled = true; } catch { } try { movement.SetAgentEnabled(true); } catch { } try { movement.ResumeMovement(); return; } catch { return; } } } catch { } } private static void UnlockCourierTriggers(CartelGoon g) { if ((Object)(object)g == (Object)null) { return; } try { try { VisionCone componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = true; } } catch { } NPCBehaviour behaviour = ((NPC)g).Behaviour; if (!((Object)(object)behaviour != (Object)null)) { return; } try { ((Behaviour)behaviour).enabled = true; } catch { } try { if ((Object)(object)behaviour.CombatBehaviour != (Object)null) { ((Behaviour)behaviour.CombatBehaviour).enabled = true; } } catch { } } catch { } } private static void DisableBeh(Behaviour b) { if ((Object)(object)b == (Object)null) { return; } try { b.Disable(); } catch { } try { ((Behaviour)b).enabled = false; } catch { } } public static void Tick(float dt) { if (_state == State.Idle) { return; } if (!SessionGate.IsAuthority) { AbortQuiet(); return; } _stateTimer += dt; switch (_state) { case State.Inbound: TickInbound(dt); break; case State.Planting: TickPlanting(); break; case State.Armed: TickArmed(dt); break; } } private static void TickInbound(float dt) { //IL_005c: 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_0097: 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_00cb: 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_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_0143: 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) if (!CourierAlive()) { DonMessaging.SendDon("We lost the package on the way, boss. No boom today."); Abort(); return; } _repathCd -= dt; if (_repathCd <= 0f) { _repathCd = 2f; LockCourierTriggers(_courier); Vector3 destination = _anchor; try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(_anchor, ref val, 5f, -1)) { destination = ((NavMeshHit)(ref val)).position; } } catch { } try { ((NPC)_courier).Movement.SetDestination(destination); } catch { } try { float num = (((Object)(object)((Component)_courier).transform != (Object)null) ? HorizontalDist(((Component)_courier).transform.position, _anchor) : (-1f)); NavMeshAgent val2 = (((Object)(object)((Component)_courier).gameObject != (Object)null) ? ((Component)_courier).gameObject.GetComponent() : null); string text = $"[BOMBA][courier] dist={num:0.0}m "; object obj3; if (!((Object)(object)val2 != (Object)null)) { obj3 = "no-agent"; } else { object arg = val2.isOnNavMesh; object arg2 = val2.hasPath; Vector3 velocity = val2.velocity; obj3 = $"onMesh={arg} hasPath={arg2} vel={((Vector3)(ref velocity)).magnitude:0.0}"; } NDLog.Debug(text + (string?)obj3); } catch { } } float num2 = float.MaxValue; try { if ((Object)(object)((Component)_courier).transform != (Object)null) { num2 = HorizontalDist(((Component)_courier).transform.position, _anchor); } } catch { } if (!(num2 <= 2.5f) && !(_stateTimer > 60f)) { return; } if (num2 > 2.5f) { _bombPos = _anchor; NDLog.Debug("[BOMBA] spot unreachable for the courier — arming at the MARKED spot anyway (co-op-safe)."); } try { ((NPC)_courier).Movement.Stop(); } catch { } try { ((NPC)_courier).Movement.PauseMovement(); } catch { } _state = State.Planting; _stateTimer = 0f; BombaMarkerQuest.SetText("Pacco Bomba: planting the package…"); try { BossMarkerSync.SetLabel("Pacco Bomba: planting the package…"); } catch { } } private static void TickPlanting() { //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_0020: 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_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_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_00ac: 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_00c3: Unknown result type (might be due to invalid IL or missing references) if (!(_stateTimer < 2.5f)) { _bombPos = GroundPos(_bombPos); DestroySignalProp(); SpawnBombProp(_bombPos); _armedUntil = Time.time + 45f; _state = State.Armed; _stateTimer = 0f; _repathCd = 0f; _timeSinceBeep = 1000f; try { ((NPC)_courier).Movement.ResumeMovement(); } catch { } _exitDoor = _entryDoor; _haveExitDoor = _entryDoor != Vector3.zero; BombaMarkerQuest.SetText("Pacco Bomba: ARMED — 45 seconds, get clear!"); BombaMarkerQuest.MoveTo(_bombPos); try { BossMarkerSync.SetLabel("Pacco Bomba: ARMED — 45 seconds, get clear!"); BossMarkerSync.SetPos(_bombPos); } catch { } DonMessaging.SendDon("Package armed. 45 seconds, boss — be somewhere with an alibi."); NDLog.Debug($"[BOMBA] armed @ {_bombPos} (fuse {45f}s)."); } } private static void TickArmed(float dt) { //IL_00b4: 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_0082: Unknown result type (might be due to invalid IL or missing references) if (!_courierGone) { bool flag = !CourierAlive() || _stateTimer > 30f || !_haveExitDoor; if (!flag) { _repathCd -= dt; if (_repathCd <= 0f) { _repathCd = 2f; LockCourierTriggers(_courier); try { ((NPC)_courier).Movement.SetDestination(_exitDoor); } catch { } } try { if ((Object)(object)((Component)_courier).transform != (Object)null && HorizontalDist(((Component)_courier).transform.position, _exitDoor) <= 3f) { flag = true; } } catch { flag = true; } } if (flag) { DespawnCourier(); } } float num = _armedUntil - Time.time; float num2 = Mathf.Clamp(45f - num, 0f, 45f); _timeSinceBeep += dt; float num3 = Mathf.Lerp(1f, 0.125f, num2 / 45f); if (_timeSinceBeep >= num3) { _timeSinceBeep = 0f; Beep(); } if (num <= 0f) { Detonate(); } } private static void Detonate() { //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_024b: 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_006d: 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_0085: 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_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) Vector3 bombPos = _bombPos; DestroyBombProp(); DespawnCourier(); BombaMarkerQuest.CompleteAndClear(); try { BossMarkerSync.Clear(); } catch { } try { ExplosionData val = new ExplosionData { DamageRadius = 8f, MaxDamage = 400f, PushForceRadius = 16f, MaxPushForce = 1000f, CheckLoS = false, ExplosionType = (EExplosionType)0 }; CombatManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null) { instance.CreateExplosion(bombPos, val); } } catch (Exception ex) { NDLog.Warn("[BOMBA] CreateExplosion: " + ex.Message); } try { if (SessionGate.IsAuthority) { List nPCRegistry = NPCManager.NPCRegistry; if (nPCRegistry != null) { int num = 0; for (int i = 0; i < nPCRegistry.Count; i++) { NPC val2 = nPCRegistry[i]; if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).transform == (Object)null) { continue; } NPCHealth health = val2.Health; if ((Object)(object)health == (Object)null || health.IsDead) { continue; } float num2 = Vector3.Distance(((Component)val2).transform.position, bombPos); if (!(num2 > 8f)) { float num3 = Mathf.Lerp(400f, 0f, Mathf.Clamp01(num2 / 8f)); try { health.TakeDamage(num3, true); num++; } catch { } } } NDLog.Debug($"[BOMBA] direct-damage pass @ {bombPos} r={8f}: {num} npc(s) hit."); } } } catch (Exception ex2) { NDLog.DebugWarn("[BOMBA] direct-damage: " + ex2.Message); } try { PlayerSingleton.Instance.StartCameraShake(2.5f, 1.5f, true); } catch { } try { DonMessaging.SendDon("Boom. We're clear, boss — the whole block heard that one."); } catch { } try { LuckyChatController.RefreshIfHandoverActive(); } catch { } _state = State.Idle; _courier = null; NDLog.Info($"[BOMBA] detonated @ {bombPos} (r={8f}, dmg={400f})."); } private static void SpawnBombProp(Vector3 pos) { //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0237: 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_003e: 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) //IL_006b: 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_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) _bombAudio = null; try { BombPlantLocation val = Object.FindObjectOfType(true); GameObject val2 = null; try { val2 = (((Object)(object)val != (Object)null) ? val.BombModel : null); } catch { } if ((Object)(object)val2 != (Object)null) { _bombProp = Object.Instantiate(val2, pos + Vector3.up * 0.03f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); ((Object)_bombProp).name = "Ndrangheta_PaccoBomba"; _bombProp.SetActive(true); PropVisuals.SeatOnGround(_bombProp, pos.y); try { _bombAudio = _bombProp.GetComponentInChildren(true); } catch { } if ((Object)(object)_bombAudio == (Object)null) { try { AudioSourceController componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Component)componentInChildren).gameObject != (Object)null) { GameObject val3 = Object.Instantiate(((Component)componentInChildren).gameObject, _bombProp.transform); val3.transform.localPosition = Vector3.zero; val3.SetActive(true); _bombAudio = val3.GetComponent(); } } catch { } } NDLog.Debug($"[BOMBA] cloned vanilla BombModel (beep-audio={(Object)(object)_bombAudio != (Object)null})."); return; } NDLog.DebugWarn("[BOMBA] BombPlantLocation/BombModel not found — fallback cube."); } catch (Exception ex) { NDLog.DebugWarn("[BOMBA] BombModel clone: " + ex.Message); } try { _bombProp = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)_bombProp).name = "Ndrangheta_PaccoBomba"; _bombProp.transform.position = pos; _bombProp.transform.localScale = new Vector3(0.35f, 0.16f, 0.22f); try { Collider component = _bombProp.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = true; } } catch { } PropVisuals.SeatOnGround(_bombProp, pos.y); PropVisuals.Apply(_bombProp, new Color(0.08f, 0.08f, 0.09f)); } catch (Exception ex2) { NDLog.DebugWarn("[BOMBA] SpawnBombProp: " + ex2.Message); } } private static void Beep() { //IL_006c: 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) bool flag = false; try { if ((Object)(object)_bombAudio != (Object)null) { _bombAudio.Play(); flag = true; } } catch { } if (!flag) { _blinkOn = !_blinkOn; TintBomb(_blinkOn ? new Color(0.9f, 0.05f, 0.05f) : new Color(0.08f, 0.08f, 0.09f)); } } private static void TintBomb(Color c) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)_bombProp == (Object)null)) { Renderer component = _bombProp.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.material != (Object)null) { component.material.color = c; } } } catch { } } private static void DestroyBombProp() { try { if ((Object)(object)_bombProp != (Object)null) { Object.Destroy((Object)(object)_bombProp); } } catch { } _bombProp = null; } private static bool CourierAlive() { try { if ((Object)(object)_courier == (Object)null || !_courier.IsGoonSpawned) { return false; } NPCHealth health = ((NPC)_courier).Health; return (Object)(object)health == (Object)null || (!health.IsDead && !health.IsKnockedOut); } catch { return false; } } private static void DespawnCourier() { if (_courierGone) { return; } try { UnlockCourierTriggers(_courier); } catch { } try { LuckyBrawlManager.RestoreGoonDefaults(_courier, _courierDefaults); } catch { } _courierDefaults = null; try { if ((Object)(object)_courier != (Object)null && _courier.IsGoonSpawned) { _courier.Despawn(); } } catch { } _courierGone = true; } private static Vector3 GroundPos(Vector3 pos) { //IL_0002: 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_006a: 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_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_0028: 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_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_003d: 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) //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) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(pos, ref val, 3f, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } try { RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(pos + Vector3.up * 0.5f, Vector3.down, ref val2, 6f, -5, (QueryTriggerInteraction)1)) { return ((RaycastHit)(ref val2)).point; } } catch { } return pos + Vector3.down * 1f; } private static float HorizontalDist(Vector3 a, Vector3 b) { //IL_0019: 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) a.y = 0f; b.y = 0f; return Vector3.Distance(a, b); } private static void Abort() { AbortQuiet(); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } internal static void ClientShowProp(Vector3 pos, bool armed) { //IL_0181: 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_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: 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_02c5: 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_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029c: 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_007a: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_clientProp != (Object)null && _clientPropArmed != armed) { ClientHideProp(); } if ((Object)(object)_clientProp == (Object)null) { if (!armed) { _clientProp = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)_clientProp).name = "Ndrangheta_BombaSignal_Client"; _clientProp.transform.localScale = new Vector3(0.12f, 0.4f, 0.12f); PropVisuals.Apply(_clientProp, new Color(0.95f, 0.12f, 0.1f)); try { Collider component = _clientProp.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = true; } } catch { } } else { _clientProp = CloneBombModel(pos, out _clientBombAudio); if ((Object)(object)_clientProp == (Object)null) { _clientProp = GameObject.CreatePrimitive((PrimitiveType)3); _clientProp.transform.localScale = new Vector3(0.42f, 0.26f, 0.56f); PropVisuals.Apply(_clientProp, new Color(0.1f, 0.1f, 0.12f)); try { Collider component2 = _clientProp.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.isTrigger = true; } } catch { } } ((Object)_clientProp).name = "Ndrangheta_PaccoBomba_Client"; float y = GroundPos(pos).y; PropVisuals.SeatOnGround(_clientProp, y); try { _clientArmedSeatedY = _clientProp.transform.position.y; } catch { _clientArmedSeatedY = y; } EnsureClientBombAudio(); _clientArmedAt = Time.time; _clientBeepSince = 0f; _clientBlinkOn = false; try { if ((Object)(object)_clientBombAudio != (Object)null) { _clientBombAudio.Play(); } } catch { } NDLog.Debug($"[BOMBA] client armed prop built (audio={(Object)(object)_clientBombAudio != (Object)null}, active={(Object)(object)_clientBombAudio != (Object)null && (Object)(object)((Component)_clientBombAudio).gameObject != (Object)null && ((Component)_clientBombAudio).gameObject.activeInHierarchy})."); } _clientPropArmed = armed; } if ((Object)(object)_clientProp != (Object)null) { if (armed) { _clientProp.transform.position = new Vector3(pos.x, _clientArmedSeatedY, pos.z); } else { _clientProp.transform.position = pos + Vector3.up * 0.4f; } } } catch (Exception ex) { NDLog.DebugWarn("LaBomba.ClientShowProp: " + ex.Message); } } internal static void ClientTickBeep() { if (!((Object)(object)_clientProp == (Object)null) && _clientPropArmed) { ClientBeepTick(); } } private static void ClientBeepTick() { //IL_0117: 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) try { _clientBeepSince += Time.deltaTime; float num = Mathf.Clamp(Time.time - _clientArmedAt, 0f, 45f); float num2 = Mathf.Lerp(1f, 0.125f, num / 45f); if (_clientBeepSince < num2) { return; } _clientBeepSince = 0f; bool flag = false; if ((Object)(object)_clientBombAudio != (Object)null) { try { _clientBombAudio.Play(); flag = true; } catch { } } if (flag) { return; } _clientBlinkOn = !_clientBlinkOn; try { if ((Object)(object)_clientProp != (Object)null) { Renderer component = _clientProp.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.material != (Object)null) { component.material.color = (_clientBlinkOn ? new Color(0.9f, 0.05f, 0.05f) : new Color(0.1f, 0.1f, 0.12f)); } } } catch { } } catch { } } private static AudioSourceController PickAudioWithClip(GameObject root) { try { if ((Object)(object)root == (Object)null) { return null; } AudioSourceController[] componentsInChildren = root.GetComponentsInChildren(true); if (componentsInChildren == null) { return null; } AudioSourceController val = null; foreach (AudioSourceController val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)val == (Object)null) { val = val2; } AudioSource val3 = null; try { val3 = ((Component)val2).GetComponent(); } catch { } if ((Object)(object)val3 != (Object)null && (Object)(object)val3.clip != (Object)null) { return val2; } } } return val; } catch { return null; } } private static void EnsureClientBombAudio() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_clientBombAudio == (Object)null && (Object)(object)_clientProp != (Object)null) { _clientBombAudio = PickAudioWithClip(_clientProp); } if ((Object)(object)_clientBombAudio == (Object)null && (Object)(object)_clientProp != (Object)null) { try { BombPlantLocation val = Object.FindObjectOfType(true); AudioSourceController val2 = (((Object)(object)val != (Object)null) ? PickAudioWithClip(((Component)val).gameObject) : null); if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null) { GameObject val3 = Object.Instantiate(((Component)val2).gameObject, _clientProp.transform); val3.transform.localPosition = Vector3.zero; val3.SetActive(true); _clientBombAudio = val3.GetComponent(); } } catch { } } if (!((Object)(object)_clientBombAudio != (Object)null)) { return; } try { if ((Object)(object)((Component)_clientBombAudio).gameObject != (Object)null && !((Component)_clientBombAudio).gameObject.activeSelf) { ((Component)_clientBombAudio).gameObject.SetActive(true); } } catch { } try { if (!((Behaviour)_clientBombAudio).enabled) { ((Behaviour)_clientBombAudio).enabled = true; } } catch { } try { AudioSource component = ((Component)_clientBombAudio).GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; component.spatialBlend = 1f; component.rolloffMode = (AudioRolloffMode)1; component.minDistance = 2f; component.maxDistance = 35f; NDLog.Debug(string.Format("[BOMBA] client beep audio: clip={0} 3D (pre-Play vol={1:0.00}).", ((Object)(object)component.clip != (Object)null) ? ((Object)component.clip).name : "NULL", component.volume)); } } catch { } } catch { } } private static GameObject CloneBombModel(Vector3 pos, out AudioSourceController audio) { //IL_003e: 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_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_006c: 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) audio = null; try { BombPlantLocation val = Object.FindObjectOfType(true); GameObject val2 = null; try { val2 = (((Object)(object)val != (Object)null) ? val.BombModel : null); } catch { } if ((Object)(object)val2 == (Object)null) { return null; } GameObject val3 = Object.Instantiate(val2, pos + Vector3.up * 0.03f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); val3.SetActive(true); try { audio = val3.GetComponentInChildren(true); } catch { } if ((Object)(object)audio == (Object)null && (Object)(object)val != (Object)null) { try { AudioSourceController componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Component)componentInChildren).gameObject != (Object)null) { GameObject val4 = Object.Instantiate(((Component)componentInChildren).gameObject, val3.transform); val4.transform.localPosition = Vector3.zero; val4.SetActive(true); audio = val4.GetComponent(); } } catch { } } return val3; } catch { return null; } } internal static void ClientHideProp() { try { if ((Object)(object)_clientProp != (Object)null) { Object.Destroy((Object)(object)_clientProp); } } catch { } _clientProp = null; _clientBombAudio = null; _clientArmedAt = 0f; _clientBeepSince = 0f; _clientBlinkOn = false; _clientArmedSeatedY = 0f; } private static void SpawnSignalProp(Vector3 pos) { //IL_002d: 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_0038: 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_0061: 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) DestroySignalProp(); try { _signalProp = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)_signalProp).name = "Ndrangheta_BombaSignal"; _signalProp.transform.position = pos + Vector3.up * 0.4f; _signalProp.transform.localScale = new Vector3(0.12f, 0.4f, 0.12f); try { Collider component = _signalProp.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = true; } } catch { } PropVisuals.Apply(_signalProp, new Color(0.95f, 0.12f, 0.1f)); } catch (Exception ex) { NDLog.DebugWarn("[BOMBA] SpawnSignalProp: " + ex.Message); } } private static void DestroySignalProp() { try { if ((Object)(object)_signalProp != (Object)null) { Object.Destroy((Object)(object)_signalProp); } } catch { } _signalProp = null; } internal static void SweepStaleMarker() { if (_state != State.Idle || BombaMarkerQuest.Instance == null) { return; } NDLog.Debug("[BOMBA] cleaned up stale marker quest after reload."); BombaMarkerQuest.CompleteAndClear(); try { BossMarkerSync.Clear(); } catch { } } private static void AbortQuiet() { DestroySignalProp(); _hasMark = false; DestroyBombProp(); try { UnlockCourierTriggers(_courier); } catch { } try { LuckyBrawlManager.RestoreGoonDefaults(_courier, _courierDefaults); } catch { } _courierDefaults = null; try { if ((Object)(object)_courier != (Object)null && _courier.IsGoonSpawned) { _courier.Despawn(); } } catch { } _courier = null; try { BombaMarkerQuest.CompleteAndClear(); } catch { } try { BossMarkerSync.Clear(); } catch { } _state = State.Idle; } } internal static class LagerDecor { private const float HALF = 5.5f; private static readonly Color WoodDark = new Color(0.26f, 0.19f, 0.15f, 1f); private static readonly Color WoodSlat = new Color(0.17f, 0.12f, 0.09f, 1f); private static readonly Color WoodBoard = new Color(0.42f, 0.3f, 0.2f, 1f); public static void Build(Transform parent, Vector3 center, float floorY) { //IL_0003: 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) try { BuildShelfWall(parent, center, floorY); BuildFloatingShelf(parent, center, floorY); NDLog.Debug("[LAGERDECOR] Shelf wall + floating shelf built (immersion)."); } catch (Exception ex) { NDLog.DebugWarn("[LAGERDECOR] Build: " + ex.Message); } } private static void BuildShelfWall(Transform parent, Vector3 c, float fy) { //IL_0001: 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_002e: 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_004e: 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_0082: 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_00a2: 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_00f5: 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_0117: Unknown result type (might be due to invalid IL or missing references) float num = c.z + 5.5f - 0.15f; GameObject go = Box(parent, "Decor_ShelfPanel", new Vector3(c.x, fy + 1.55f, num - 0.04f), new Vector3(8.6f, 2.6f, 0.08f)); Wood(go, WoodDark); for (int i = -7; i <= 7; i++) { GameObject go2 = Box(parent, "Decor_Slat", new Vector3(c.x + (float)i * 0.6f, fy + 1.55f, num - 0.1f), new Vector3(0.07f, 2.55f, 0.03f)); Wood(go2, WoodSlat); } for (int j = 0; j < 4; j++) { GameObject go3 = Box(parent, $"Decor_Shelf{j}", new Vector3(c.x, fy + 0.55f + (float)j * 0.65f, num - 0.22f), new Vector3(8.3f, 0.05f, 0.36f)); Wood(go3, WoodBoard); } } private static void BuildFloatingShelf(Transform parent, Vector3 c, float fy) { //IL_0001: 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_0047: 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_0067: Unknown result type (might be due to invalid IL or missing references) float num = c.x + 5.5f - 0.15f; for (int i = 0; i < 2; i++) { GameObject go = Box(parent, $"Decor_FloatShelf{i}", new Vector3(num - 0.2f, fy + 1.45f + (float)i * 0.62f, c.z), new Vector3(0.36f, 0.05f, 2.4f)); Wood(go, WoodBoard); } } private static GameObject Box(Transform parent, string name, Vector3 pos, Vector3 scale) { //IL_002f: 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) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = name; if ((Object)(object)parent != (Object)null) { val.transform.SetParent(parent, true); } val.transform.position = pos; val.transform.localScale = scale; try { Collider component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = false; } } catch { } try { val.isStatic = true; } catch { } return val; } private static void Wood(GameObject go, Color tint) { //IL_0007: 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) PropVisuals.ApplyVanilla(go, "wood", tint, tint); } } internal static class LagerGrid { private const string GUID_SEED = "Ndrangheta_LagerGrid"; private const float TILE = 0.5f; private const float TILE_LIFT = 0f; private const float WALL_MARGIN = 0.25f; private const float RECONCILE_INTERVAL = 0.3f; private const float RETRY_INTERVAL = 3f; private static int _mat = 20; private static float _off; private static bool _want; private static Vector3 _wantCenter; private static float _wantY; private static float _wantHalf = 5.5f; private static bool _built; private static float _retryAt; private static float _reconcileCd; private static GameObject _gridGo; private static Grid _grid; private static Property _prop; private static readonly List _tracked = new List(); public static bool IsBuilt => _built && (Object)(object)_grid != (Object)null && (Object)(object)_gridGo != (Object)null; public static Grid GridRef => _grid; public static void AttachToRoom(Vector3 center, float floorSurfaceY, float halfExtent) { //IL_0007: 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) _want = true; _wantCenter = center; _wantY = floorSurfaceY; _wantHalf = halfExtent; _retryAt = 0f; TryBuild(); } public static void DetachFromRoom() { _want = false; _built = false; _tracked.Clear(); try { if ((Object)(object)_gridGo != (Object)null) { Object.Destroy((Object)(object)_gridGo); } } catch { } _gridGo = null; _grid = null; _prop = null; try { GridPersistence.ResetReplayLatches(); } catch { } } public static void ResetForSceneReload() { DetachFromRoom(); } public static void Tick(float dt) { try { if (!_want) { return; } if (!_built || (Object)(object)_grid == (Object)null || (Object)(object)_gridGo == (Object)null) { _built = false; if (!(Time.time < _retryAt)) { _retryAt = Time.time + 3f; TryBuild(); } return; } GridPersistence.ReplayIfReady(GridKey.Lager, _grid); _reconcileCd -= dt; if (!(_reconcileCd > 0f)) { _reconcileCd = 0.3f; Reconcile(); } } catch (Exception ex) { NDLog.DebugWarn("[LAGERGRID] Tick: " + ex.Message); } } private static void TryBuild() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) try { if (!_built || !((Object)(object)_grid != (Object)null)) { Property val = ResolveOwnedProperty(); if ((Object)(object)val == (Object)null) { NDLog.DebugWarn("[LAGERGRID] keine besessene Property gefunden — Grid-Bau verschoben (retry)."); } else { Build(val, _wantCenter, _wantY); } } } catch (Exception ex) { NDLog.DebugWarn("[LAGERGRID] TryBuild: " + ex.Message); } } private static Property ResolveOwnedProperty() { try { return GameCompat.ResolvePropertyAnchor(RealEstateManager.AnyLagerOwnedView()); } catch (Exception ex) { NDLog.DebugWarn("[LAGERGRID] ResolveOwnedProperty: " + ex.Message); return null; } } private static void Build(Property prop, Vector3 center, float floorY) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) int num = LayerMask.NameToLayer("Tile"); if (num < 0) { NDLog.DebugWarn("[LAGERGRID] layer 'Tile' does not exist — build aborted (placement would not be detected)."); return; } _prop = prop; _mat = Mathf.Max(4, Mathf.RoundToInt((_wantHalf - 0.25f) * 2f / 0.5f)); _off = (float)(_mat - 1) * 0.5f * 0.5f; _gridGo = new GameObject("Ndrangheta_LagerGrid"); _gridGo.SetActive(false); try { _gridGo.transform.SetParent(((Component)prop).transform, true); } catch { } _gridGo.transform.position = new Vector3(center.x - _off, floorY + 0f, center.z - _off); _gridGo.transform.rotation = Quaternion.identity; _grid = _gridGo.AddComponent(); GameCompat.SetGridParentProperty(_grid, prop); GameCompat.SetGridGuidString(_grid, DeterministicGuid().ToString()); int num2 = 0; for (int i = 0; i < _mat; i++) { for (int j = 0; j < _mat; j++) { if (BuildTile(i, j, num)) { num2++; } } } BuildFoundation(); _gridGo.SetActive(true); _built = true; _reconcileCd = 0f; NDLog.Debug($"[LAGERGRID] Grid gebaut @ {_gridGo.transform.position} unter Property '{SafeName(prop)}' (owned), " + $"{num2}/{_mat * _mat} Tiles ({_mat}x{_mat}, ~{(float)_mat * 0.5f:0.0}m), Layer 'Tile'={num}, floorY={floorY:0.00}. " + "Buildable-Item ausruesten + im Raum stehen → platzieren."); } private static bool BuildTile(int gx, int gy, int layer) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0058: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0098: 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_00d5: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject($"Tile_{gx}_{gy}"); val.layer = layer; val.transform.SetParent(_gridGo.transform, false); val.transform.localPosition = new Vector3((float)gx * 0.5f, 0f, (float)gy * 0.5f); val.transform.localRotation = Quaternion.identity; GameObject val2 = new GameObject("Model"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = Vector3.zero; BoxCollider val3 = val.AddComponent(); val3.size = new Vector3(0.5f, 0.1f, 0.5f); val3.center = new Vector3(0f, -0.05f, 0f); ((Collider)val3).isTrigger = false; Tile val4 = val.AddComponent(); val4.InitializePropertyTile(gx, gy, 1000f, _grid); _grid.RegisterTile(val4); return true; } catch (Exception ex) { NDLog.DebugWarn($"[LAGERGRID] BuildTile {gx},{gy}: {ex.Message}"); return false; } } private static void BuildFoundation() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0041: 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_007f: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("Ndrangheta_LagerFoundation"); val.layer = 0; val.transform.SetParent(_gridGo.transform, false); val.transform.localPosition = new Vector3(_off, -0.02f, _off); val.transform.localRotation = Quaternion.identity; float num = (float)_mat * 0.5f + 1f; BoxCollider val2 = val.AddComponent(); val2.size = new Vector3(num, 0.04f, num); ((Collider)val2).isTrigger = false; } catch (Exception ex) { NDLog.DebugWarn("[LAGERGRID] BuildFoundation: " + ex.Message); } } private static void Reconcile() { if ((Object)(object)_grid == (Object)null || (Object)(object)_prop == (Object)null) { return; } List tiles = _grid.Tiles; if (tiles == null) { return; } int count = tiles.Count; for (int i = 0; i < count; i++) { Tile val = tiles[i]; if ((Object)(object)val == (Object)null) { continue; } List buildableOccupants = val.BuildableOccupants; if (buildableOccupants == null) { continue; } int count2 = buildableOccupants.Count; for (int j = 0; j < count2; j++) { GridItem val2 = buildableOccupants[j]; if ((Object)(object)val2 == (Object)null) { continue; } BuildableItem val3 = (BuildableItem)(object)val2; if (!IsTracked(val3)) { _tracked.Add(val3); try { val3.SetCulled(false); } catch { } try { FreezePlacedItem(val2); } catch { } NDLog.Debug("[LAGERGRID] platziertes Moebel sichtbar gehalten (" + SafeItemName(val3) + ")."); } } } } private static bool IsTracked(BuildableItem bi) { for (int i = 0; i < _tracked.Count; i++) { if ((Object)(object)_tracked[i] != (Object)null && GameCompat.SameInstance((object)_tracked[i], (object)bi)) { return true; } } return false; } private static void FreezePlacedItem(GridItem gi) { if ((Object)(object)gi == (Object)null || (Object)(object)((Component)gi).gameObject == (Object)null) { return; } Rigidbody[] componentsInChildren = ((Component)gi).gameObject.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } for (int i = 0; i < componentsInChildren.Length; i++) { try { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].isKinematic = true; } } catch { } } } private static Guid DeterministicGuid() { using MD5 mD = MD5.Create(); byte[] b = mD.ComputeHash(Encoding.UTF8.GetBytes("Ndrangheta_LagerGrid")); return new Guid(b); } private static string SafeName(Property p) { try { return ((Object)p).name; } catch { return "?"; } } private static string SafeItemName(BuildableItem b) { try { return ((Object)b).name; } catch { return "buildable"; } } } internal static class LagerRoom { private sealed class Entry { public int Idx; public Vector3 Surface; public GameObject Prop; } private const float ROOM_Y = -12f; private const float ROOM_HALF = 5.5f; private const float ROOM_HEIGHT = 3.2f; private const int FURNISH_IDX = 0; private static readonly Vector3 ROOM_ANCHOR = new Vector3(6.87f, -12f, -6.58f); private static readonly List _entries = new List(); private static GameObject _room; private static Vector3 _roomCenter = ROOM_ANCHOR; private static GameObject _floor; private static GameObject _ceiling; private static GameObject _wallN; private static GameObject _wallS; private static GameObject _wallE; private static GameObject _wallW; private static GameObject[] _furniture; private static bool _roomSited; private static int _lastEntryIdx = -1; private static bool _teleportBusy; private static bool _recovering; public static void ResetForSceneReload() { DestroyRoom(); for (int i = 0; i < _entries.Count; i++) { try { if ((Object)(object)_entries[i].Prop != (Object)null) { Object.Destroy((Object)(object)_entries[i].Prop); } } catch { } } _entries.Clear(); _lastEntryIdx = -1; _teleportBusy = false; _recovering = false; } private static void DestroyRoom() { //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) try { LagerGrid.DetachFromRoom(); } catch { } try { if ((Object)(object)_room != (Object)null) { Object.Destroy((Object)(object)_room); } } catch { } _room = null; _floor = (_ceiling = (_wallN = (_wallS = (_wallE = (_wallW = null))))); _furniture = null; _roomSited = false; _roomCenter = ROOM_ANCHOR; } public static void RemoveLager(int idx) { for (int num = _entries.Count - 1; num >= 0; num--) { if (_entries[num].Idx == idx) { try { if ((Object)(object)_entries[num].Prop != (Object)null) { Object.Destroy((Object)(object)_entries[num].Prop); } } catch { } _entries.RemoveAt(num); NDLog.Debug($"[LAGER] Entrance #{idx} removed (sold)."); } } if (_entries.Count == 0) { DestroyRoom(); } } public static void EnsureLager(int idx, Vector3 surfaceSpot) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_00aa: 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) try { EnsureRoom(); for (int i = 0; i < _entries.Count; i++) { if (_entries[i].Idx == idx) { if ((Object)(object)_entries[i].Prop == (Object)null) { _entries.RemoveAt(i); break; } return; } } Vector3 val = GroundSnap(surfaceSpot); Entry item = new Entry { Idx = idx, Surface = val, Prop = BuildEntry(idx, val) }; _entries.Add(item); NDLog.Debug($"[LAGER] Entrance #{idx} ready (@ {val}); room @ {_roomCenter}."); } catch (Exception ex) { NDLog.Warn($"[LAGER] EnsureLager({idx}): {ex.Message}"); } } private static void EnsureRoom() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0032: 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_0049: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_room != (Object)null)) { _roomCenter = (_roomSited ? _roomCenter : RoomSiting.FindFreeCenter("Lager", ROOM_ANCHOR, 5.5f, 5.5f, 3.2f)); _roomSited = true; BuildRoom(_roomCenter); try { Physics.SyncTransforms(); } catch { } NDLog.Debug($"[LAGER] shared room built @ {_roomCenter}."); } } private static void BuildRoom(Vector3 floorCenter) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_001a: 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_002d: 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_003c: 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_0064: 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_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_0080: 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_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_00b9: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_0106: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: 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_01e9: 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_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: 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_02be: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) _room = new GameObject("Ndrangheta_Lager"); _room.transform.position = floorCenter; float num = 11.4f; _floor = AddSlab("Floor", floorCenter + Vector3.down * 0.1f, new Vector3(11f, 0.2f, 11f)); _ceiling = AddSlab("Ceiling", floorCenter + Vector3.up * 3.2f, new Vector3(num, 0.2f, num)); _wallN = AddSlab("WallN", floorCenter + new Vector3(0f, 1.6f, 5.5f), new Vector3(num, 3.2f, 0.3f)); _wallS = AddSlab("WallS", floorCenter + new Vector3(0f, 1.6f, -5.5f), new Vector3(num, 3.2f, 0.3f)); _wallE = AddSlab("WallE", floorCenter + new Vector3(5.5f, 1.6f, 0f), new Vector3(0.3f, 3.2f, num)); _wallW = AddSlab("WallW", floorCenter + new Vector3(-5.5f, 1.6f, 0f), new Vector3(0.3f, 3.2f, num)); MakeLagerWallsVanilla(); GameObject val = GameCompat.SpawnVanillaPrefab("fluorescent", floorCenter + new Vector3(0f, 3.05f, 0f), Quaternion.identity); if ((Object)(object)val != (Object)null) { try { val.transform.SetParent(_room.transform, true); } catch { } RoomFurnish.MakeStatic(val); } AddLight(floorCenter + new Vector3(0f, 2.7f, 0f), new Color(1f, 0.97f, 0.92f), 1.1f, 18f); _furniture = (GameObject[])(object)new GameObject[FurnishCatalog.Objects.Length]; ApplyFurnishToRoom(); GameObject val2 = GameCompat.SpawnVanillaPrefab("steeldoor", floorCenter + new Vector3(0f, -0.1f, -5.22f), Quaternion.Euler(0f, 180f, 0f)); if ((Object)(object)val2 != (Object)null) { try { val2.transform.SetParent(_room.transform, true); } catch { } RoomFurnish.MakeStatic(val2); } else { val2 = RoomFurnish.BuildDoor(_room.transform, floorCenter + new Vector3(0f, 0f, -5.28f), 0f); } ((Object)val2).name = "Ndrangheta_LagerExit"; InteractableObject val3 = val2.AddComponent(); val3.SetMessage("Leave the deposito"); val3.SetInteractionType((EInteractionType)0); val3.MaxInteractionRange = 3.5f; val3.RequiresUniqueClick = true; val3.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)TeleportOut)); float num2 = _wallN.transform.position.y - _wallN.transform.localScale.y * 0.5f; try { LagerDecor.Build(_room.transform, floorCenter, num2); } catch (Exception ex) { NDLog.Warn("[LAGER] decor: " + ex.Message); } GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val4).name = "Ndrangheta_LagerTunnelToVilla"; try { val4.transform.SetParent(_room.transform, true); } catch { } val4.transform.position = floorCenter + new Vector3(0f, 0.8f, 5.3f); val4.transform.localScale = new Vector3(2.4f, 2.2f, 1f); try { Renderer component = val4.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } catch { } try { Collider component2 = val4.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.isTrigger = true; } } catch { } InteractableObject val5 = val4.AddComponent(); val5.SetMessage("Use the tunnel"); val5.SetInteractionType((EInteractionType)0); val5.MaxInteractionRange = 3f; val5.RequiresUniqueClick = true; val5.Priority = 2; val5.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)TeleportToVillaTunnel)); bool flag = true; try { LagerGrid.AttachToRoom(floorCenter, num2, 5.5f); } catch (Exception ex2) { NDLog.Warn("[LAGER] grid attach: " + ex2.Message); } } private static void MakeLagerWallsVanilla() { try { Property val = ResolveOwnedProperty(); if ((Object)(object)val == (Object)null) { NDLog.DebugWarn("[LAGER] no owned property — vanilla walls skipped."); return; } try { val.MinimumCullingDistance = 100000f; } catch { } try { val.ContentCullingEnabled = false; } catch { } try { val.SetContentCulled(false); } catch { } MakeWallVanilla(_wallN, val, "N"); MakeWallVanilla(_wallS, val, "S"); MakeWallVanilla(_wallE, val, "E"); MakeWallVanilla(_wallW, val, "W"); NDLog.Debug("[LAGER] 4 walls = vanilla Surface (pictures hangable) + content culling off (owned area)."); } catch (Exception ex) { NDLog.Warn("[LAGER] MakeLagerWallsVanilla: " + ex.Message); } } private static void MakeWallVanilla(GameObject wall, Property prop, string id) { if ((Object)(object)wall == (Object)null) { return; } try { wall.SetActive(false); GameCompat.MakePictureWall(wall, prop, LagerDeterministicGuid("Ndrangheta_LagerWall_" + id).ToString()); wall.SetActive(true); } catch (Exception ex) { NDLog.DebugWarn("[LAGER] MakeWallVanilla " + id + ": " + ex.Message); } } private static Property ResolveOwnedProperty() { try { Property[] array = Object.FindObjectsOfType(true); if (array != null) { foreach (Property val in array) { if (!((Object)(object)val == (Object)null)) { bool flag = false; try { flag = val.IsOwned; } catch { } if (flag) { return val; } } } } } catch (Exception ex) { NDLog.DebugWarn("[LAGER] ResolveOwnedProperty: " + ex.Message); } return null; } private static Guid LagerDeterministicGuid(string seed) { using MD5 mD = MD5.Create(); return new Guid(mD.ComputeHash(Encoding.UTF8.GetBytes(seed))); } private static GameObject BuildEntry(int idx, Vector3 surface) { //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_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_005b: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = $"Ndrangheta_LagerEntry_{idx}"; val.transform.position = surface + Vector3.up * 1.1f; val.transform.localScale = new Vector3(1.4f, 2.2f, 1f); try { Renderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } catch { } try { Collider component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.isTrigger = true; } } catch { } InteractableObject val2 = val.AddComponent(); val2.SetMessage("Enter the deposito"); val2.SetInteractionType((EInteractionType)0); val2.MaxInteractionRange = 3.5f; val2.RequiresUniqueClick = true; val2.Priority = 2; int entryIdx = idx; val2.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)delegate { TeleportIn(entryIdx); })); return val; } private static GameObject AddSlab(string name, Vector3 pos, Vector3 scale) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Ndrangheta_Lager_" + name; val.transform.SetParent(_room.transform, true); val.transform.position = pos; val.transform.localScale = scale; return val; } public static void ApplyFurnish(int idx) { if ((Object)(object)_room != (Object)null) { ApplyFurnishToRoom(); } } private static void ApplyFurnishToRoom() { try { if (!((Object)(object)_room == (Object)null)) { int furnishA = RealEstateManager.GetFurnishA(0); ApplySurface(_floor, FurnishCatalog.Mat(furnishA, 0), FurnishCatalog.Col(furnishA, 0)); int matIdx = FurnishCatalog.Mat(furnishA, 1); int colIdx = FurnishCatalog.Col(furnishA, 1); ApplySurface(_wallN, matIdx, colIdx); ApplySurface(_wallS, matIdx, colIdx); ApplySurface(_wallE, matIdx, colIdx); ApplySurface(_wallW, matIdx, colIdx); ApplySurface(_ceiling, FurnishCatalog.Mat(furnishA, 2), FurnishCatalog.Col(furnishA, 2)); } } catch (Exception ex) { NDLog.DebugWarn("[LAGER] ApplyFurnish: " + ex.Message); } } private static void ApplySurface(GameObject go, int matIdx, int colIdx) { //IL_0024: 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_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_006b: Unknown result type (might be due to invalid IL or missing references) //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_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_003c: 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_0043: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)go == (Object)null)) { matIdx = FurnishCatalog.ClampMat(matIdx); colIdx = FurnishCatalog.ClampCol(colIdx); MatDef val = FurnishCatalog.Materials[matIdx]; Color val2 = FurnishCatalog.ColorOf(colIdx); if (val.Textured) { PropVisuals.ApplyVanilla(go, val.Kind, val.Base, (Color)((val2.a > 0f) ? val2 : default(Color))); } else { PropVisuals.ApplyPreset(go, val.Base, val.Metallic, val.Smoothness, val2); } } } private static GameObject SpawnObject(int objIdx) { //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_000e: 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_0019: 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_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) //IL_0034: 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_006c: Unknown result type (might be due to invalid IL or missing references) try { ObjDef val = FurnishCatalog.Objects[objIdx]; GameObject val2 = GameCompat.SpawnVanillaPrefab(val.Kind, _roomCenter + val.Local, Quaternion.Euler(0f, val.Yaw, 0f)); if ((Object)(object)val2 == (Object)null) { NDLog.DebugWarn("[LAGER] Furniture '" + val.Name + "' (Kind '" + val.Kind + "') not spawnable."); return null; } try { val2.transform.SetParent(_room.transform, true); } catch { } RoomFurnish.MakeStatic(val2); return val2; } catch (Exception ex) { NDLog.DebugWarn($"[LAGER] SpawnObject {objIdx}: {ex.Message}"); return null; } } private static void AddLight(Vector3 pos, Color color, float intensity, float range) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_002a: 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) try { GameObject val = new GameObject("Ndrangheta_Lager_Light"); val.transform.SetParent(_room.transform, true); val.transform.position = pos; Light val2 = val.AddComponent(); val2.type = (LightType)2; val2.color = color; val2.intensity = intensity; val2.range = range; val2.shadows = (LightShadows)0; } catch (Exception ex) { NDLog.DebugWarn("[LAGER] AddLight: " + ex.Message); } } private static void TeleportIn(int idx) { //IL_0056: 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_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_007b: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (!RealEstateManager.LagerOwnedView(idx)) { NDLog.DebugWarn($"[LAGER] TeleportIn #{idx} blocked — deposito not owned."); return; } EnsureRoom(); if ((Object)(object)_room == (Object)null) { NDLog.Warn("[LAGER] room not buildable — teleport aborted."); return; } _lastEntryIdx = idx; _recovering = false; Vector3 val = _roomCenter + Vector3.up * 0.6f; NDLog.Debug($"[LAGER] teleport in (via entrance #{idx}) -> {val} (room @ {_roomCenter})"); TeleportTo(val, snapToNavMesh: false, float.NaN, recoverOutOnFail: true); } private static void TeleportOut() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) Entry entry = null; for (int i = 0; i < _entries.Count; i++) { if (_entries[i].Idx == _lastEntryIdx) { entry = _entries[i]; break; } } if (entry == null && _entries.Count > 0) { entry = _entries[0]; } if (entry != null) { TeleportTo(entry.Surface, snapToNavMesh: true); } } private static void TeleportToVillaTunnel() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (VillaRoom.TryGetSalonEntry(out var p)) { TeleportTo(p, snapToNavMesh: false); return; } try { Singleton.Instance.ShowHint("

Tunnel\nThe other end isn't dug yet — buy the Villa first.", 0f, (string)null); } catch { } } public static bool TryGetRoomEntry(out Vector3 p) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_room != (Object)null) { p = _roomCenter + Vector3.up * 0.15f; return true; } p = Vector3.zero; return false; } internal static void TeleportTo(Vector3 target, bool snapToNavMesh, float faceYaw = float.NaN, bool recoverOutOnFail = false) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (_teleportBusy) { return; } _teleportBusy = true; try { MelonCoroutines.Start(TeleportRoutine(target, snapToNavMesh, faceYaw, recoverOutOnFail)); } catch (Exception ex) { _teleportBusy = false; NDLog.Warn("[LAGER] Teleport: " + ex.Message); } } private static IEnumerator TeleportRoutine(Vector3 target, bool snapToNavMesh, float faceYaw, bool recoverOutOnFail) { //IL_0007: 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) PlayerMovement mv; try { mv = PlayerSingleton.Instance; if ((Object)(object)mv == (Object)null) { _teleportBusy = false; yield break; } if (snapToNavMesh) { try { NavMeshHit hit = default(NavMeshHit); if (NavMesh.SamplePosition(target, ref hit, 8f, -1)) { target = ((NavMeshHit)(ref hit)).position + Vector3.up * 0.2f; } } catch { } } try { Singleton.Instance.Open(0.05f); } catch { } try { mv.CanMove = false; } catch { } } catch (Exception ex) { Exception ex2 = ex; _teleportBusy = false; NDLog.Warn("[LAGER] TeleportRoutine setup: " + ex2.Message); yield break; } yield return (object)new WaitForSeconds(0.12f); try { mv.Teleport(target, true); } catch (Exception ex) { Exception ex3 = ex; NDLog.Warn("[LAGER] Teleport call: " + ex3.Message); } if (!float.IsNaN(faceYaw)) { try { mv.SetPlayerRotation(Quaternion.Euler(0f, faceYaw, 0f)); } catch (Exception ex) { Exception ex4 = ex; NDLog.DebugWarn("[LAGER] SetPlayerRotation: " + ex4.Message); } } yield return (object)new WaitForSeconds(0.2f); try { Singleton.Instance.Close(0.3f); } catch { } yield return (object)new WaitForSeconds(0.2f); try { mv.CanMove = true; } catch { } _teleportBusy = false; CheckArrival(target, 0f, recoverOutOnFail); yield return (object)new WaitForSeconds(2f); CheckArrival(target, 2f, recoverOutOnFail); } private static void CheckArrival(Vector3 target, float delay, bool recoverOutOnFail) { //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_003d: 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_0052: 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_005d: 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_0069: 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_00b3: Unknown result type (might be due to invalid IL or missing references) try { Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null) { return; } Vector3 position = ((Component)local).transform.position; bool flag = position.y < target.y - 2.5f; float num = Vector2.Distance(new Vector2(position.x, position.z), new Vector2(target.x, target.z)); bool flag2 = num > 20f; if (!flag && !flag2) { return; } NDLog.Warn($"[ROOM] Player {delay:0}s after teleport off-target: is {position}, should be {target} (fellThrough={flag}, horiz={num:0}m) — vanilla warp (water/y-limit) intervened!"); if (recoverOutOnFail && delay >= 2f && !_recovering && _entries.Count > 0) { _recovering = true; NDLog.Warn("[ROOM] recovering player to the deposito entrance (room volume unusable — likely water/solid at the room site)."); try { Singleton.Instance.ShowHint("

Deposito\nThe way in caved — try again from the entrance.", 0f, (string)null); } catch { } TeleportOut(); } } catch { } } internal static bool RescuePlayerIfInside() { //IL_00e9: 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_00d8: 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_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_006a: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) try { if (_teleportBusy) { return false; } Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null) { return false; } Vector3 position = ((Component)local).transform.position; if (position.y > -7f) { return false; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(position.x, 2f, position.z); bool flag = false; try { NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(val, ref val2, 40f, -1)) { val = ((NavMeshHit)(ref val2)).position + Vector3.up * 0.3f; flag = true; } } catch { } if (!flag) { try { if (DonSalvatoreNPC.ResolveGazeboPosition(out var pos)) { val = pos; } } catch { } } NDLog.Info($"[LAGER] player spawned inside the deposito on reload — rescuing to surface {val}."); _recovering = false; TeleportTo(val, snapToNavMesh: true); return true; } catch { return false; } } private static Vector3 GroundSnap(Vector3 pos) { //IL_0002: 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_0027: 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_001b: 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) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(pos, ref val, 3f, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return pos; } } [HarmonyPatch(typeof(LandVehicle), "SetVisible", new Type[] { typeof(bool) })] internal static class LandVehicleSetVisibleNREGuard { private static int _logBudget = 4; [HarmonyPrefix] private static bool Prefix(LandVehicle __instance) { bool flag = false; try { if ((Object)(object)__instance == (Object)null) { flag = true; } else if ((Object)(object)__instance.HumanoidColliderContainer == (Object)null) { flag = true; } else if ((Object)(object)__instance.boundingBox == (Object)null) { flag = true; } } catch { flag = true; } if (!flag) { return true; } if (_logBudget > 0) { _logBudget--; NDLog.DebugWarn("LandVehicle.SetVisible skipped on a torn-down vehicle (DestroyVehicle destroyed the collider container) — prevents the per-frame NRE storm."); } return false; } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { if (__exception == null) { return null; } string text = __exception.GetType().Name ?? string.Empty; string text2 = __exception.Message ?? string.Empty; if (text.IndexOf("NullReference", StringComparison.OrdinalIgnoreCase) < 0 && text2.IndexOf("NullReference", StringComparison.OrdinalIgnoreCase) < 0 && text2.IndexOf("not set to an instance", StringComparison.OrdinalIgnoreCase) < 0) { return __exception; } if (_logBudget > 0) { _logBudget--; NDLog.DebugWarn("LandVehicle.SetVisible NRE swallowed (wrecked vehicle)."); } return null; } } public static class LittleHelper { public const string BombItemId = "bomb"; private static readonly string[] M1912Candidates = new string[9] { "goldenm1911", "m1912", "m1912golden", "goldm1912", "goldenm1912", "m1911gold", "m1911", "revolver", "pistol" }; private static PlayerInventory Inv { get { try { return PlayerSingleton.Instance; } catch { return null; } } } public static bool GiveBomb() { return GivePlainItem("bomb", 1); } public static bool GiveCalabrianBrick() { try { PlayerInventory inv = Inv; if ((Object)(object)inv == (Object)null) { NDLog.DebugWarn("[SHOP] no PlayerInventory."); return false; } ProductRegistry.TryRegister(); ProductDefinition val = ProductRegistry.CalabrianCream; if ((Object)(object)val == (Object)null) { ItemDefinition item = Registry.GetItem("granddaddypurple"); val = (((Object)(object)item != (Object)null) ? GameCompat.Cast((Object)(object)item) : null); } if ((Object)(object)val == (Object)null) { NDLog.Warn("[SHOP] Calabrian product 'granddaddypurple' not resolvable."); return false; } ItemInstance val2 = null; try { val2 = ((ItemDefinition)val).GetDefaultInstance(1); } catch (Exception ex) { NDLog.DebugWarn("[SHOP] GetDefaultInstance cream: " + ex.Message); } if (val2 == null) { return false; } try { ProductItemInstance val3 = GameCompat.CastObj((object)val2); if (val3 != null) { PackagingDefinition val4 = RewardSpawner.ResolveBrickPackaging(val); if ((Object)(object)val4 != (Object)null) { val3.SetPackaging(val4); } try { ((QualityItemInstance)val3).SetQuality((EQuality)4); } catch (Exception ex2) { NDLog.DebugWarn("[SHOP] SetQuality cream: " + ex2.Message); } } } catch (Exception ex3) { NDLog.DebugWarn("[SHOP] cream packaging: " + ex3.Message); } if (!CanFit(inv, val2)) { NDLog.Debug("[SHOP] inventory full (Calabrian Cream)."); return false; } inv.AddItemToInventory(val2); NDLog.Debug("[SHOP] Calabrian Cream Brick (Q5) added to inventory."); return true; } catch (Exception ex4) { NDLog.Warn("[SHOP] GiveCalabrianBrick: " + ex4.Message); return false; } } public static bool GiveGoldenM1912() { try { PlayerInventory inv = Inv; if ((Object)(object)inv == (Object)null) { return false; } string text = null; string[] m1912Candidates = M1912Candidates; foreach (string text2 in m1912Candidates) { try { if ((Object)(object)Registry.GetItem(text2) != (Object)null) { text = text2; break; } } catch { } } if (text == null) { NDLog.Warn("[SHOP] no M1912 weapon ID found (tried: " + string.Join(", ", M1912Candidates) + "). There is no vanilla 'm1912' — please provide the real ID/skin ID."); return false; } ItemDefinition item = Registry.GetItem(text); ItemInstance val = null; try { val = item.GetDefaultInstance(1); } catch (Exception ex) { NDLog.DebugWarn("[SHOP] GetDefaultInstance(" + text + "): " + ex.Message); } if (val == null) { return false; } if (!CanFit(inv, val)) { NDLog.Debug("[SHOP] inventory full (M1912)."); return false; } inv.AddItemToInventory(val); NDLog.Debug("[SHOP] weapon '" + text + "' (golden-M1912 slot) added to inventory."); return true; } catch (Exception ex2) { NDLog.Warn("[SHOP] GiveGoldenM1912: " + ex2.Message); return false; } } public static Sprite GetItemIcon(string shopKey) { try { string text = ShopKeyToItemId(shopKey); if (string.IsNullOrEmpty(text)) { return null; } ItemDefinition item = Registry.GetItem(text); return ((Object)(object)item != (Object)null) ? ((BaseItemDefinition)item).Icon : null; } catch (Exception ex) { NDLog.DebugWarn("[SHOP] GetItemIcon(" + shopKey + "): " + ex.Message); return null; } } private static string ShopKeyToItemId(string shopKey) { return shopKey switch { "cream" => "granddaddypurple", "bomb" => "bomb", "m1912" => ResolveM1912Id(), _ => null, }; } private static string ResolveM1912Id() { string[] m1912Candidates = M1912Candidates; foreach (string text in m1912Candidates) { try { if ((Object)(object)Registry.GetItem(text) != (Object)null) { return text; } } catch { } } return null; } private static bool GivePlainItem(string id, int qty) { try { PlayerInventory inv = Inv; if ((Object)(object)inv == (Object)null) { return false; } ItemDefinition item = Registry.GetItem(id); if ((Object)(object)item == (Object)null) { NDLog.Warn("[SHOP] item '" + id + "' not in the registry."); return false; } ItemInstance val = null; try { val = item.GetDefaultInstance(qty); } catch (Exception ex) { NDLog.DebugWarn("[SHOP] GetDefaultInstance(" + id + "): " + ex.Message); } if (val == null) { return false; } if (!CanFit(inv, val, qty)) { NDLog.Debug("[SHOP] inventory full (" + id + ")."); return false; } inv.AddItemToInventory(val); NDLog.Debug($"[SHOP] {qty}x '{id}' added to inventory."); return true; } catch (Exception ex2) { NDLog.Warn("[SHOP] GivePlainItem(" + id + "): " + ex2.Message); return false; } } private static bool CanFit(PlayerInventory inv, ItemInstance inst, int qty = 1) { try { return inv.CanItemFitInInventory(inst, qty); } catch { return true; } } } public static class LoreStrings { public enum JobTrialKind { Normal, Heavier } public const string PizzoQuestName = "Il Pizzo"; public const string TrasportoQuestName = "Trasporto"; public const string ContrattoQuestName = "Contratto"; public const string CaricoQuestName = "Carico"; public const string ContrattoEntryReturn = "Collect your cut at the Famiglia stash (Gazebo) — returning the revolver is optional"; public const string CaricoEntryDropOff = "Collect your share from Don Salvatore at the Gazebo"; public const string PizzoCompleteSms = "Grazie. The family remembers. I'll text you again soon."; public const string PizzoCompleteSmsBoss = "The cassa is settled, Boss. The famiglia eats because of you."; public const string CaricoEntryDropOffBoss = "Report to the cassa at the Gazebo for your share"; public const string ContrattoCategoryCop = "A badge got too close to the family's books — finish them."; public const string ContrattoCategoryOwnDealer = "One of your dealers is talking to people who shouldn't hear. The 'Ndrina has decided."; public const string ContrattoCategoryShopkeeper = "A shopkeeper has been a problem. End it."; public const string ContrattoFailKoReason = "you knocked them out but didn't finish — that's not how the famiglia works."; public const string ContrattoFailDamageReason = "you bloodied them and walked away. That's worse than not trying at all."; public const string DeclineAckSms = "Capito. Job's off the table. I'll text you again in a minute."; public const string HandoverSms = "Cinque contratti, fratello. The 'Ndrina sees you. From here on you don't take orders from the streets — you give them. Hyland Point is your playground. My made-man (call him Lucky) takes care of the wet work when you point. Open the chat: famiglia run for the regular cut, or pick a target yourself and Lucky will make it happen. Capito?"; public const string LuckyMethodMelee = "knife, up close"; public const string LuckyMethodFirearm = "pumpaction, no questions"; public const string LuckyCancelSms = "Capito. Lucky stands down. Cycle again when you've made up your mind."; public static string PizzoTitle(string targetName) { return "Il Pizzo — " + targetName; } public static string PizzoDescription(string targetName, int cutAmount) { return targetName + " is behind on tribute. Pick up the envelope at the drop, " + $"then drop my ${cutAmount} cut in the famiglia stash at the Gazebo. Don't keep me waiting."; } public static string PizzoEntryPickup(string targetName, string dropName) { return "Collect " + targetName + "'s tribute at " + dropName; } public static string PizzoEntryDropOff(int cutAmount) { return $"Drop the Don's ${cutAmount} cut in the famiglia stash at the Gazebo"; } public static string TrasportoTitle(string aName, string bName) { return "Trasporto — " + aName + " -> " + bName; } public static string TrasportoDescription(string aName, string bName, int envelope, int bAmount, int donAmount, int reward) { return $"Move the carico. Pick up ${envelope} at {aName}. Drop ${bAmount} for the famiglia at {bName}, " + $"then drop the remaining ${donAmount} in the famiglia stash at the Gazebo. The famiglia adds ${reward} on top — " + "clean work, clean pay."; } public static string TrasportoEntryPickup(string aName, int envelope) { return $"Collect ${envelope} at {aName}"; } public static string TrasportoEntryDeliver(string bName, int bAmount) { return $"Drop ${bAmount} for the famiglia at {bName}"; } public static string TrasportoEntryDropOff(int donAmount) { return $"Drop the Don's ${donAmount} cut in the famiglia stash at the Gazebo"; } public static string ContrattoTitle(string targetName) { return "Contratto — " + targetName; } public static string ContrattoDescription(string targetName) { return "The famiglia has marked " + targetName + ". There's a revolver in the stash if you're unarmed — optional. Finish it, then come back."; } public static string ContrattoEntryKill(string targetName) { return "Eliminate " + targetName + " — unarmed? Grab the optional revolver from the Famiglia stash (Gazebo)"; } public static string ContrattoEntryBeatdown(string targetName) { return "Send Lucky to split " + targetName + "'s skull open"; } public static string ContrattoEntryHit(string targetName) { return "Send Lucky to flatline " + targetName; } public static string CaricoTitle(string itemDisplayName) { return "Carico — " + itemDisplayName; } public static string CaricoDescription(string itemDisplayName, string itemId, int quantity, string aName, string bName, int reward) { return $"A partita of {quantity}x {itemDisplayName}{PackageWord(itemId, quantity)} is waiting at {aName}. " + "Move it to " + bName + " for the famiglia, then come see me at the Gazebo — " + $"${reward} and a piece of the carico for the work."; } public static string CaricoEntryPickup(string itemDisplayName, string itemId, int quantity, string aName) { return $"Pick up {quantity}x {itemDisplayName}{PackageWord(itemId, quantity)} at {aName}"; } public static string CaricoEntryDeliver(string itemDisplayName, string itemId, int quantity, string bName) { return $"Drop {quantity}x {itemDisplayName}{PackageWord(itemId, quantity)} at {bName}"; } internal static string BrickWord(int quantity) { return (quantity == 1) ? "Brick" : "Bricks"; } internal static string PackageWord(string itemId, int quantity) { ItemCatalog.Entry byId = ItemCatalog.GetById(itemId); return (byId == null || byId.Cat == ItemCatalog.Category.Drug) ? (" " + BrickWord(quantity)) : ""; } public static string PizzoOrderSms(string greeting, string trialTag, string targetName, string targetHint, int envelope, int cut, string dropName) { return greeting + trialTag + ". " + targetName + " " + targetHint + " hasn't paid this week. " + $"Envelope with ${envelope} is at '{dropName}'. " + $"Pick it up, then drop my ${cut} cut in the famiglia stash at the Gazebo. " + "Don't make me ask twice."; } public static string PizzoPickupAckSms(int cut) { return $"Bene. Now drop my ${cut} cut in the famiglia stash — Gazebo in Suburbia. Walk fast."; } public static string PizzoOrderSmsBoss(string targetName, string targetHint, int envelope, int cut, string dropName) { return "Boss. " + targetName + " " + targetHint + " hasn't paid this week — the soldati squeezed him. " + $"Envelope with ${envelope} waits at '{dropName}'. " + $"The famiglia's ${cut} share goes in the books — drop it in the cassa stash at the Gazebo, " + "I keep the cassa for you."; } public static string PizzoPickupAckSmsBoss(int cut) { return $"Bene, Boss. Drop the famiglia's ${cut} in the cassa stash at the Gazebo — the books stay clean."; } public static string PizzoEntryDropOffBoss(int cutAmount) { return $"Drop the famiglia's ${cutAmount} in the cassa stash at the Gazebo"; } public static string TrasportoEntryDropOffBoss(int donAmount) { return $"Drop the famiglia's ${donAmount} in the cassa stash at the Gazebo"; } public static string TrasportoOrderSms(string greeting, string trialTag, int envelope, string aName, int bAmount, string bName, int donAmount, int reward) { return $"{greeting}{trialTag}. Trasporto job. Pick up ${envelope} at '{aName}'. " + $"Drop ${bAmount} for the famiglia at '{bName}', then drop the remaining ${donAmount} " + $"in the famiglia stash at the Gazebo. The famiglia pays you ${reward} on top."; } public static string CurfewTrasportoOrderSms(string greeting, int envelope, string aName, int bAmount, string bName, int donAmount, int reward) { return greeting + ". Curfew run — double pay, dead streets, but the cruisers " + $"are out. Pick up ${envelope} at '{aName}'. Drop ${bAmount} at '{bName}', " + $"drop the remaining ${donAmount} in the famiglia stash at the Gazebo. Get caught, no " + $"famiglia help. The famiglia pays you ${reward} on top."; } public static string TrasportoPickupAckSms(int bAmount, string bName, int cut) { return $"Got it. Drop ${bAmount} at '{bName}', then drop the " + $"remaining ${cut} in the famiglia stash at the Gazebo. Don't get followed."; } public static string TrasportoDeliverAckSms(int reward) { return $"Consegna effettuata. Come to the Gazebo — your ${reward} reward is waiting with me."; } public static string TrasportoCompleteSms(int reward) { return $"Grazie. The famiglia pays you ${reward} for the work. I'll text you again soon."; } public static string ContrattoOrderSms(string greeting, string targetName, string categoryHint, int env, int playerShare) { return greeting + ". Contratto. Target: " + targetName + ". " + categoryHint + " No iron on you? There's a revolver in the famiglia stash — optional. " + $"Get it done, then come back for your ${playerShare} cut."; } public static string ContrattoKillAckSms(int playerShare) { return $"Heard it on the wire. Clean work. Come back to the stash — your ${playerShare} is waiting."; } public static string ContrattoCompleteSms(int reward) { return $"${reward} in the stash — your share. The revolver goes back where it came from."; } public static string ContrattoCompleteSmsOnline(int reward) { return $"${reward} hit your account — your share. The revolver goes back where it came from."; } public static string ContrattoFailedSms(string reason) { return "You flinched — " + reason + " Cool off. I'll text you in a bit."; } public static string CaricoOrderSms(string greeting, string itemDisplayName, string itemId, int quantity, string aName, string bName, int reward, int bonusBricks) { string arg = ((bonusBricks > 0) ? $" A piece of the carico ({bonusBricks}x {BrickWord(bonusBricks)}) goes in the stash for you after." : ""); return $"{greeting}. Carico run. {quantity}x {itemDisplayName}{PackageWord(itemId, quantity)} sitting at '{aName}'. " + "Move it to '" + bName + "' — famiglia operation, don't lose a single piece. " + $"Come see me at the Gazebo after. ${reward} for the work.{arg}"; } public static string CaricoPickupAckSms(int quantity, string itemDisplayName, string itemId, string bName) { return $"Got eyes on you. {quantity}x {itemDisplayName}{PackageWord(itemId, quantity)} to '{bName}'. " + "No detours, no taste-tests."; } public static string CaricoDeliverAckSms() { return "Consegna pulita. Come to the Gazebo — the famiglia pays its men in person."; } public static string CaricoCompleteSms(int reward, int bonusBricks, string itemDisplayName) { if (bonusBricks > 0) { return $"${reward} for the work, and {bonusBricks}x {itemDisplayName} {BrickWord(bonusBricks)} in the stash — " + "your taste of the carico. Move it, smoke it, doesn't matter. The 'Ndrina takes care of its own."; } return $"${reward} for the work. I'll text you again soon."; } public static string TrialTag(Rank rank, JobTrialKind kind) { if (rank >= Rank.Capodecina) { return ""; } if (kind == JobTrialKind.Heavier) { return " — heavier trial"; } return " — another trial"; } public static string FamigliaContrattoOrderSms(string targetName, string categoryHint, int env, int playerShare) { return "La famiglia has marked " + targetName + ". " + categoryHint + " There's a revolver in the stash if you're unarmed — optional. " + $"${playerShare} for you when it's done."; } public static string LuckyTargetPreviewSms(string targetName, string regionLabel, string categoryLabel) { return "Target: " + targetName + ". Region: " + regionLabel + ". Category: " + categoryLabel + ". Send Lucky, or cycle for someone else."; } public static string LuckyTargetPreviewSms(string targetName, string categoryLabel) { return "Target: " + targetName + ". Category: " + categoryLabel + ". Send Lucky, or show next for someone else."; } public static string LuckyDispatchedSms(string targetName, string method) { return "Lucky's on the move. " + targetName + " won't see him coming. Method: " + method + ". Sit tight, fratello — your cut comes when it's done."; } public static string LuckyDispatchedRaidSms(string targetName) { return "Lucky's on " + targetName + " with the knife. He'll cut the throat clean — no coming back from that. Sit tight, fratello."; } public static string LuckyDispatchedFlatlineSms(string targetName) { return "Lucky's hunting " + targetName + ". Pumpaction, cold blood, no ID. Sit tight — your cut comes when it's done."; } public static string LuckyKilledSms(string targetName, int reward) { return $"Lucky did it clean. {targetName} is off the books. ${reward} — your cut's handled."; } public static string LuckyBeatdownDoneSms(string targetName, int reward) { return $"Lucky split {targetName} open — done and buried. ${reward} — your cut's handled."; } public static string LuckyDownSms(string targetName) { return "Lucky took one for the famiglia — he's down. Job's off, no cut. He'll be back on his feet for the next one. " + targetName + " got lucky this time."; } } public static class LouisAvatarCloner { public struct LouisSnapshot { public bool Valid; public Color32 SkinColor; public Color LeftEyeLidColor; public Color RightEyeLidColor; public Color EyeBallTint; public string EyeballMaterialIdentifier; public float PupilDilation; public float EyebrowScale; public float EyebrowThickness; public float EyebrowRestingHeight; public float EyebrowRestingAngle; public float Gender; public string[] FaceLayerPaths; public Color[] FaceLayerColors; } private static readonly string[] LouisNpcIds = new string[4] { "louis", "louis_fourier", "Louis", "Louis Fourier" }; public static LouisSnapshot LastSnapshot { get; private set; } public static bool HasSnapshot => LastSnapshot.Valid; public static bool TryCaptureSnapshot() { //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_0091: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) if (LastSnapshot.Valid) { return true; } try { NPC val = ResolveLouisNpc(); if ((Object)(object)val == (Object)null) { return false; } Avatar avatar = val.Avatar; if ((Object)(object)avatar == (Object)null) { return false; } AvatarSettings currentSettings = avatar.CurrentSettings; if ((Object)(object)currentSettings == (Object)null) { return false; } LouisSnapshot lastSnapshot = new LouisSnapshot { Valid = true, SkinColor = Color32.op_Implicit(currentSettings.SkinColor), LeftEyeLidColor = currentSettings.LeftEyeLidColor, RightEyeLidColor = currentSettings.RightEyeLidColor, EyeBallTint = currentSettings.EyeBallTint, EyeballMaterialIdentifier = (currentSettings.EyeballMaterialIdentifier ?? "Default"), PupilDilation = currentSettings.PupilDilation, EyebrowScale = currentSettings.EyebrowScale, EyebrowThickness = currentSettings.EyebrowThickness, EyebrowRestingHeight = currentSettings.EyebrowRestingHeight, EyebrowRestingAngle = currentSettings.EyebrowRestingAngle, Gender = currentSettings.Gender }; CaptureFaceLayers(currentSettings, out lastSnapshot.FaceLayerPaths, out lastSnapshot.FaceLayerColors); LastSnapshot = lastSnapshot; object[] obj = new object[4] { lastSnapshot.SkinColor.r, lastSnapshot.SkinColor.g, lastSnapshot.SkinColor.b, null }; string[] faceLayerPaths = lastSnapshot.FaceLayerPaths; obj[3] = ((faceLayerPaths != null) ? faceLayerPaths.Length : 0); NDLog.Debug(string.Format("Louis snapshot captured: skin=({0},{1},{2}) faceLayers={3}", obj)); return true; } catch (Exception ex) { NDLog.DebugWarn("LouisAvatarCloner.TryCaptureSnapshot: " + ex.Message); return false; } } private static NPC ResolveLouisNpc() { string[] louisNpcIds = LouisNpcIds; foreach (string text in louisNpcIds) { try { NPC nPC = NPCManager.GetNPC(text); if ((Object)(object)nPC != (Object)null) { return nPC; } } catch { } } try { Louis val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null) { GameObject gameObject = ((Component)val).gameObject; NPC val2 = ((gameObject != null) ? gameObject.GetComponent() : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } catch { } return null; } private static void CaptureFaceLayers(AvatarSettings settings, out string[] paths, out Color[] colors) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) paths = Array.Empty(); colors = Array.Empty(); try { List faceLayerSettings = settings.FaceLayerSettings; if (faceLayerSettings == null || faceLayerSettings.Count == 0) { return; } int count = faceLayerSettings.Count; string[] array = new string[count]; Color[] array2 = (Color[])(object)new Color[count]; for (int i = 0; i < count; i++) { LayerSetting val = faceLayerSettings[i]; if (!GameCompat.IsNullBoxed(val)) { array[i] = val.layerPath ?? string.Empty; array2[i] = val.layerTint; } } paths = array; colors = array2; } catch (Exception ex) { NDLog.DebugWarn("CaptureFaceLayers: " + ex.Message); } } } internal static class LuckyBrawlManager { public enum Mode { None, Officers, Benzies } internal sealed class GoonDefaults { public string FirstName; public string LastName; public bool HasLastName = true; public bool Invincible; public float GiveUpRange = 20f; public float DefaultSearchTime = 30f; public AvatarWeapon DefaultWeapon; public bool SchedCompEnabled = true; } private const int MAX_CREW = 8; private const int MEN_PER_TARGET = 2; private const int RIVAL_SIZE = 3; private const int POOL_RESERVE = 1; private const float BRAWL_DURATION = 120f; private const float BRAWL_COOLDOWN = 120f; private const float CREW_SPAWN_DIST = 16f; private const float RIVAL_SPAWN_DIST = 24f; private const float RETARGET_INTERVAL = 1.5f; private const float GOON_GIVE_UP = 200f; private static float _endsAt; private static float _cooldownUntil; private static float _retargetCd; private static GoonPool _pool; private static readonly List _crew = new List(); private static readonly List _rivals = new List(); private static readonly List _crewTargets = new List(); private static readonly List _engagedOfficers = new List(); private static readonly List _crewPosts = new List(); private static readonly List _rivalPosts = new List(); private static readonly List _exitGoons = new List(); private static readonly List _exitGoonDefaults = new List(); private static float _exitDeadline; private static readonly Random _weaponRng = new Random(); private const float EXIT_TIMEOUT = 45f; private static readonly List _crewDefaults = new List(); private static int _pendingMode; private static Vector3 _pendingAnchor; private static float _pendingExpiresAt; private static int _stagedMode; private static float _stagedExpiresAt; private static Vector3 _stagedAnchor; private const float STAGED_TIMEOUT = 180f; private static string _triggerWho = ""; private const int MAX_TARGET_PINS = 6; private static int _targetPinCount; private static readonly List _forcedActive = new List(); private static CartelGoon[] _goonScanCache; private static float _goonScanCacheAt = -999f; private const float GOON_SCAN_CACHE_TTL = 4.5f; private static float ScanRadius => Mathf.Clamp((float)ModConfig.BrawlRadius, 15f, 300f); private static float LiveScanRadius => Mathf.Clamp(ScanRadius + 25f, 15f, 325f); public static Mode CurrentMode { get; private set; } = Mode.None; public static bool IsRunning => CurrentMode != Mode.None; public static bool IsBusy => IsRunning || _pendingMode != 0 || _stagedMode != 0; public static int BrawlPhase => (_stagedMode != 0) ? 2 : ((_pendingMode != 0) ? 1 : 0); public static void ResetForSceneReload() { AbortBrawl(); FlushExitGoons(); ClearPending(); _cooldownUntil = 0f; _goonScanCache = null; } internal static void SweepStaleMarker() { if (IsRunning || _stagedMode != 0 || _pendingMode != 0 || BrawlMarkerQuest.Instance == null) { return; } NDLog.Debug("[BRAWL] stale marker quest cleaned up after reload."); BrawlMarkerQuest.CompleteAndClear(); try { BossMarkerSync.Clear(); } catch { } } public static bool StartBrawlFromChat(bool officers) { return StartBrawlFromChat(officers, ""); } public static bool StartBrawlFromChat(bool officers, string who) { //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority) { return false; } if (IsRunning || _stagedMode != 0 || _pendingMode != 0) { DonMessaging.SendDon("We're already on a job, boss. One brawl at a time."); LuckyChatController.RefreshIfHandoverActive(); return false; } if (LaBombaManager.IsActive) { DonMessaging.SendDon("There's a package ticking, boss — let it go off first, then we crack heads."); LuckyChatController.RefreshIfHandoverActive(); return false; } if (Time.time < _cooldownUntil) { DonMessaging.SendDon("We're still icing our knuckles, boss. Give us a minute."); LuckyChatController.RefreshIfHandoverActive(); return false; } _pool = Object.FindObjectOfType(true); if ((Object)(object)_pool == (Object)null || _pool.UnspawnedGoonCount <= 1) { DonMessaging.SendDon("We're short on hands right now, boss."); LuckyChatController.RefreshIfHandoverActive(); return false; } _triggerWho = who ?? ""; Player val = RapimentoManager.ResolvePlayerByCode(who) ?? Player.Local; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { LuckyChatController.RefreshIfHandoverActive(); return false; } if (officers) { List list = CollectOfficersNear(((Component)val).transform.position, ScanRadius); if (list.Count == 0) { DonMessaging.SendDon("No badges around here, boss. Take us where they are."); LuckyChatController.RefreshIfHandoverActive(); return false; } _pendingMode = 1; _pendingAnchor = ((Component)list[0]).transform.position; DonMessaging.SendDon(string.Format("We spotted {0} badge{1} — marker's on your map. Send us in?", list.Count, (list.Count == 1) ? "" : "s")); } else { List list2 = CollectSpawnedEnemyGoons(); if (list2.Count == 0) { DonMessaging.SendDon("No Benzies on the streets right now, boss. Nothing for us to crash."); LuckyChatController.RefreshIfHandoverActive(); return false; } _pendingMode = 2; Vector3 position = ((Component)val).transform.position; try { if ((Object)(object)list2[0] != (Object)null && (Object)(object)((Component)list2[0]).transform != (Object)null) { position = ((Component)list2[0]).transform.position; } } catch { } _pendingAnchor = position; DonMessaging.SendDon("Benzies spotted — marker's on your map. Send us in?"); } _pendingExpiresAt = Time.time + 60f; BrawlMarkerQuest.EnsureCreated("Brawl: target spotted — give the word?", _pendingAnchor); BossMarkerSync.Set("Brawl: target spotted — give the word?", _pendingAnchor); LuckyChatController.ShowBrawlConfirmMenu(); return true; } catch (Exception ex) { NDLog.Warn("StartBrawlFromChat: " + ex.Message); AbortBrawl(); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } return false; } } public static void ConfirmPendingBrawl() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00c5: 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_00d7: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority) { return; } if (_pendingMode == 0 || IsRunning) { try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } if (Time.time > _pendingExpiresAt) { DonMessaging.SendDon("Moment's gone — the targets moved on. Scout again."); ClearPending(); LuckyChatController.RefreshIfHandoverActive(); return; } _pool = Object.FindObjectOfType(true); if ((Object)(object)_pool == (Object)null || _pool.UnspawnedGoonCount <= 1) { DonMessaging.SendDon("We're short on hands right now, boss."); ClearPending(); LuckyChatController.RefreshIfHandoverActive(); return; } bool flag = _pendingMode == 1; Vector3 anchorPos = (_stagedAnchor = _pendingAnchor); _pendingMode = 0; if (flag) { StageOfficers(anchorPos); } else { StageBenzies(anchorPos); } } catch (Exception ex) { NDLog.Warn("ConfirmPendingBrawl: " + ex.Message); AbortBrawl(); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } } private static void MakeStagedStationary(CartelGoon g) { try { if ((Object)(object)g == (Object)null || (Object)(object)((Component)g).gameObject == (Object)null) { return; } try { NPCScheduleManager componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } NPCMovement movement = ((NPC)g).Movement; if (!((Object)(object)movement != (Object)null)) { return; } try { movement.Stop(); } catch { } try { movement.PauseMovement(); } catch { } } catch { } } private static void MakeBattleReady(CartelGoon g) { try { if ((Object)(object)g == (Object)null) { return; } NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { movement.ResumeMovement(); } catch { } try { movement.SetAgentEnabled(true); } catch { } try { ((Behaviour)movement).enabled = true; } catch { } } try { NPCBehaviour behaviour = ((NPC)g).Behaviour; if ((Object)(object)behaviour != (Object)null && !((Behaviour)behaviour).enabled) { ((Behaviour)behaviour).enabled = true; } } catch { } } catch { } } private static void EnterStaged(int mode, string sms) { _stagedMode = mode; _stagedExpiresAt = Time.time + 180f; _retargetCd = 1.5f; try { DonMessaging.SendDon(sms); } catch { } try { BrawlMarkerQuest.SetText("Brawl: we're in position — give the word"); } catch { } try { BossMarkerSync.SetLabel("Brawl: we're in position — give the word"); } catch { } try { LuckyChatController.ShowBrawlAttackMenu(); } catch { } NDLog.Debug($"Brawl staged: mode={mode} crew={_crew.Count} rivals={_rivals.Count}"); } public static void LaunchStagedAttack() { //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority || IsRunning) { return; } if (_stagedMode == 0) { DonMessaging.SendDon("We're not in position anymore, boss. Scout again."); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } int stagedMode = _stagedMode; _stagedMode = 0; PruneCrew(); if (_crew.Count == 0) { DonMessaging.SendDon("We got scattered before it started, boss. Another time."); StandDown(); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } for (int i = 0; i < _crew.Count; i++) { MakeBattleReady(_crew[i]); } for (int j = 0; j < _rivals.Count; j++) { MakeBattleReady(_rivals[j]); } Vector3 val = Vector3.zero; try { if ((Object)(object)_crew[0] != (Object)null && (Object)(object)((Component)_crew[0]).transform != (Object)null) { val = ((Component)_crew[0]).transform.position; } } catch { } if (val == Vector3.zero) { val = _stagedAnchor; } if (stagedMode == 1) { List list = CollectOfficersNear(val, LiveScanRadius); if (list.Count == 0) { DonMessaging.SendDon("The badges moved on. We're coming home."); StandDown(); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } for (int k = 0; k < _crew.Count; k++) { AssignBestTarget(k, list); } Activate(Mode.Officers, "We're giving the badges a lesson, boss. Sit back and enjoy the show."); return; } List list2 = CollectBenziesFoes(); if (list2.Count == 0) { DonMessaging.SendDon("The Benzies slipped away. We're coming home."); StandDown(); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } for (int l = 0; l < _crew.Count; l++) { AssignCrewTarget(l, list2[l % list2.Count]); } for (int m = 0; m < list2.Count; m++) { SicGoonOn(list2[m], (NPC)(object)_crew[m % _crew.Count]); } Activate(Mode.Benzies, "We found the Benzies. Time to settle accounts."); } catch (Exception ex) { NDLog.Warn("LaunchStagedAttack: " + ex.Message); AbortBrawl(); } } public static void CallOffStaged() { try { if (!SessionGate.IsAuthority || _stagedMode == 0) { return; } _stagedMode = 0; Teardown(exitWalk: true); DonMessaging.SendDon("We pulled back. No blood today."); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } catch { } } private static void StandDown() { _stagedMode = 0; Teardown(exitWalk: true); } private static List CollectBenziesFoes(bool allowCache = false) { //IL_0090: 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_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) List list = CollectSpawnedEnemyGoons(allowCache); for (int i = 0; i < _rivals.Count; i++) { CartelGoon val = _rivals[i]; if (SafeIsSpawned(val)) { bool flag = true; try { NPCHealth health = ((NPC)val).Health; flag = (Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut; } catch { } if (!flag) { list.Add((NPC)(object)val); } } } try { Vector3 tp = TriggerPos(); if (tp != Vector3.zero && list.Count > 1) { list.Sort((NPC a, NPC b) => SqrToSafe(a, tp).CompareTo(SqrToSafe(b, tp))); } } catch { } return list; } public static void CancelPendingBrawl() { if (SessionGate.IsAuthority) { ClearPending(); } } private static void ClearPending() { _pendingMode = 0; _pendingExpiresAt = 0f; if (!IsRunning) { try { RestoreForcedOfficers(); } catch { } try { BrawlMarkerQuest.CompleteAndClear(); } catch { } try { BossMarkerSync.Clear(); } catch { } } } private static void StageOfficers(Vector3 anchorPos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) List list = CollectOfficersNear(anchorPos, ScanRadius); if (list.Count == 0) { DonMessaging.SendDon("The badges moved on. Scout again."); ClearPending(); LuckyChatController.RefreshIfHandoverActive(); return; } int num = Mathf.Min(list.Count * 2, 8); int n = Mathf.Clamp(num, 1, _pool.UnspawnedGoonCount - 1); if (!SpawnCrew(anchorPos, n)) { DonMessaging.SendDon("Couldn't rally enough of us, boss."); ClearPending(); LuckyChatController.RefreshIfHandoverActive(); } else { EnterStaged(1, "We're in position, eyes on the badges. Give the word."); } } private static List CollectOfficersNear(Vector3 pos, float radius) { //IL_0007: 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_0230: 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_00c0: 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) List list = new List(); int num = 0; int num2 = 0; int num3 = 0; try { List officers = PoliceOfficer.Officers; if (officers == null) { return list; } num = officers.Count; float num4 = radius * radius; for (int i = 0; i < officers.Count; i++) { try { PoliceOfficer val = officers[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } NPCHealth health = ((NPC)val).Health; if ((Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut) { continue; } Vector3 val2 = ((Component)val).transform.position - pos; if (((Vector3)(ref val2)).sqrMagnitude > num4) { continue; } num2++; try { val.AutoDeactivate = false; } catch { } try { val.Activate(); } catch { } try { ((NPC)val).SetVisible(true, false); } catch { } if (IsRunning || _stagedMode != 0) { try { CheckpointBehaviour checkpointBehaviour = val.CheckpointBehaviour; if ((Object)(object)checkpointBehaviour != (Object)null && ((Behaviour)checkpointBehaviour).Enabled) { val.UnassignFromCheckpoint(); } } catch { } } _forcedActive.Add(val); bool flag = true; try { flag = ((NPC)val).IsCurrentlyTargetable; } catch { } if (flag) { num3++; list.Add(val); } } catch { } } } catch (Exception ex) { NDLog.DebugWarn("CollectOfficersNear: " + ex.Message); } try { if (list.Count > 1) { list.Sort((PoliceOfficer a, PoliceOfficer b) => SqrToSafe(a, pos).CompareTo(SqrToSafe(b, pos))); } } catch { } if (list.Count == 0) { NDLog.Debug($"[BRAWL] officer scan @ {pos} r={radius:F0}: total={num} inRange={num2} targetable={num3} -> 0 (no badges)."); } return list; } private static void RestoreForcedOfficers() { try { for (int i = 0; i < _forcedActive.Count; i++) { PoliceOfficer val = _forcedActive[i]; if (!((Object)(object)val == (Object)null)) { try { val.AutoDeactivate = true; } catch { } } } } catch { } _forcedActive.Clear(); } private static bool AnyOfficerOnTheWarpath() { //IL_0002: 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_0008: 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_007a: 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_0093: 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_0070: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = _stagedAnchor; if (val == Vector3.zero && _crew.Count > 0) { try { if ((Object)(object)_crew[0] != (Object)null && (Object)(object)((Component)_crew[0]).transform != (Object)null) { val = ((Component)_crew[0]).transform.position; } } catch { } } if (val == Vector3.zero) { return false; } List list = CollectOfficersNear(val, ScanRadius); for (int i = 0; i < list.Count; i++) { try { PoliceOfficer obj2 = list[i]; CombatBehaviour val2 = ((obj2 == null) ? null : ((NPC)obj2).Behaviour?.CombatBehaviour); if ((Object)(object)val2 != (Object)null && (((Behaviour)val2).Active || ((Behaviour)val2).Enabled)) { return true; } } catch { } } } catch { } return false; } private static void EngageOfficerCounterAttack(PoliceOfficer officer, CartelGoon goon) { try { object obj; if (goon == null) { obj = null; } else { GameObject gameObject = ((Component)goon).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent() : null); } NetworkObject val = (NetworkObject)obj; CombatBehaviour val2 = ((officer == null) ? null : ((NPC)officer).Behaviour?.CombatBehaviour); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } val2.SetTargetAndEnable_Server(val); bool flag = false; for (int i = 0; i < _engagedOfficers.Count; i++) { if (flag) { break; } flag = (Object)(object)_engagedOfficers[i] != (Object)null && GameCompat.SameInstance((object)_engagedOfficers[i], (object)officer); } if (!flag) { _engagedOfficers.Add(officer); } } catch (Exception ex) { NDLog.DebugWarn("OfficerCounterAttack: " + ex.Message); } } private static void StageBenzies(Vector3 anchorPos) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) List list = CollectSpawnedEnemyGoons(); int num = _pool.UnspawnedGoonCount - 1; if (list.Count == 0) { DonMessaging.SendDon("The Benzies moved on. Scout again."); ClearPending(); LuckyChatController.RefreshIfHandoverActive(); return; } int n = Mathf.Clamp(Mathf.Min(list.Count * 2, 8), 1, num); if (!SpawnCrew(anchorPos, n)) { DonMessaging.SendDon("Couldn't rally enough of us, boss."); ClearPending(); LuckyChatController.RefreshIfHandoverActive(); } else { EnterStaged(2, "We're set up next to the Benzies. Give the word."); } } private static List CollectSpawnedEnemyGoons(bool allowCache = false) { List list = new List(); try { CartelGoon[] array; if (allowCache && _goonScanCache != null && Time.time - _goonScanCacheAt < 4.5f) { array = _goonScanCache; } else { array = (_goonScanCache = Object.FindObjectsOfType(true)); _goonScanCacheAt = Time.time; } if (array == null) { return list; } for (int i = 0; i < array.Length; i++) { try { CartelGoon val = array[i]; if (!((Object)(object)val == (Object)null) && val.IsGoonSpawned && !IsOwnGoon(val)) { NPCHealth health = ((NPC)val).Health; if (!((Object)(object)health == (Object)null) && !health.IsDead && !health.IsKnockedOut) { list.Add((NPC)(object)val); } } } catch { } } } catch (Exception ex) { NDLog.DebugWarn("CollectSpawnedEnemyGoons: " + ex.Message); } return list; } internal static bool IsFriendlyGoon(CartelGoon g) { return IsOwnGoon(g); } private static bool IsOwnGoon(CartelGoon g) { try { CartelGoon activeLuckyGoon = LuckyCombatDriver.ActiveLuckyGoon; if ((Object)(object)activeLuckyGoon != (Object)null && GameCompat.SameInstance((object)g, (object)activeLuckyGoon)) { return true; } CartelGoon activeCourier = LaBombaManager.ActiveCourier; if ((Object)(object)activeCourier != (Object)null && GameCompat.SameInstance((object)g, (object)activeCourier)) { return true; } for (int i = 0; i < _crew.Count; i++) { if ((Object)(object)_crew[i] != (Object)null && GameCompat.SameInstance((object)g, (object)_crew[i])) { return true; } } for (int j = 0; j < _rivals.Count; j++) { if ((Object)(object)_rivals[j] != (Object)null && GameCompat.SameInstance((object)g, (object)_rivals[j])) { return true; } } for (int k = 0; k < _exitGoons.Count; k++) { if ((Object)(object)_exitGoons[k] != (Object)null && GameCompat.SameInstance((object)g, (object)_exitGoons[k])) { return true; } } if (RealEstateManager.IsEstateGuard(g)) { return true; } } catch { } return false; } private static void SicGoonOn(NPC attackerGoon, NPC victim) { try { CartelGoon val = GameCompat.Cast((Object)(object)attackerGoon); ICombatTargetable val2 = GameCompat.CastTargetable((object)victim); if (!((Object)(object)val == (Object)null) && val2 != null) { bool flag = false; try { flag = !val2.IsNull() && val2.IsCurrentlyTargetable; } catch { } if (flag) { val.AttackEntity(val2, false); } } } catch (Exception ex) { NDLog.DebugWarn("SicGoonOn: " + ex.Message); } } private static bool SpawnCrew(Vector3 around, int n) { //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_000d: 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_001c: 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_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: 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) //IL_01c9: 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_01d0: 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_0207: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = FindNavPointNear(around + RandomRingDir() * 16f); List list = _pool.SpawnMultipleGoons(val, n, false); if (list == null || list.Count == 0) { return false; } for (int i = 0; i < list.Count; i++) { CartelGoon val2 = list[i]; if ((Object)(object)val2 == (Object)null) { continue; } GoonDefaults item = CaptureGoonDefaults(val2); try { NPCHealth health = ((NPC)val2).Health; if ((Object)(object)health != (Object)null) { health.npc.NPCData.Health.Invincible = ModConfig.BrawlCrewInvincible; } } catch { } try { CombatBehaviour val3 = ((NPC)val2).Behaviour?.CombatBehaviour; if ((Object)(object)val3 != (Object)null) { AvatarWeapon defaultWeapon = null; if (ModConfig.BrawlArmed) { try { defaultWeapon = LuckyWeaponVisual.LoadRandomBrawlMelee(_weaponRng); } catch { } } val3.SetDefaultWeapon(defaultWeapon); val3.GiveUpRange = 200f; try { val3.DefaultSearchTime = 9999f; } catch { } } } catch { } TryReskinGoonToCrew(val2, i); RenameToFamiglia(val2); MakeStagedStationary(val2); _crew.Add(val2); _crewTargets.Add(null); _crewDefaults.Add(item); float num = 360f / (float)Mathf.Max(1, list.Count) * (float)i + Random.Range(-20f, 20f); Vector3 val4 = Quaternion.Euler(0f, num, 0f) * Vector3.forward * Random.Range(1.7f, 2.8f); Vector3 val5 = FindNavPointNear(val + val4); try { if ((Object)(object)((Component)val2).transform != (Object)null) { ((Component)val2).transform.position = val5; } } catch { } _crewPosts.Add(val5); } return _crew.Count > 0; } catch (Exception ex) { NDLog.Warn("SpawnCrew: " + ex.Message); return false; } } private static void TryReskinGoonToCrew(CartelGoon goon, int idx) { FamigliaOutfit.Apply(goon, idx, _pool); } internal static void RenameToFamiglia(CartelGoon g) { try { ((NPC)g).NPCData.BasicInfo.FirstName = "Famiglia"; ((NPC)g).NPCData.BasicInfo.HasLastName = false; ((NPC)g).NPCData.BasicInfo.LastName = string.Empty; } catch (Exception ex) { NDLog.DebugWarn("RenameToFamiglia: " + ex.Message); } } private static bool AssignCrewTarget(int idx, NPC npcTarget) { try { ICombatTargetable val = GameCompat.CastTargetable((object)npcTarget); if (val == null) { return false; } bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (!flag) { return false; } _crew[idx].AttackEntity(val, false); _crewTargets[idx] = npcTarget; return true; } catch (Exception ex) { NDLog.DebugWarn("AssignCrewTarget: " + ex.Message); return false; } } public static void Tick(float dt) { //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: 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_0440: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: 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_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_05c2: Unknown result type (might be due to invalid IL or missing references) //IL_05de: Unknown result type (might be due to invalid IL or missing references) //IL_05df: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Unknown result type (might be due to invalid IL or missing references) //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_061f: Unknown result type (might be due to invalid IL or missing references) //IL_0620: Unknown result type (might be due to invalid IL or missing references) //IL_07ad: Unknown result type (might be due to invalid IL or missing references) //IL_0633: Unknown result type (might be due to invalid IL or missing references) //IL_0669: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) //IL_07f1: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_08dd: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _crew.Count; i++) { CartelGoon val = _crew[i]; if ((Object)(object)val == (Object)null) { continue; } try { if (((NPC)val).FirstName != "Famiglia") { RenameToFamiglia(val); } } catch { } } if (_exitGoons.Count > 0) { for (int num = _exitGoons.Count - 1; num >= 0; num--) { CartelGoon val2 = _exitGoons[num]; GoonDefaults d = ((num < _exitGoonDefaults.Count) ? _exitGoonDefaults[num] : null); bool flag = false; try { flag = (Object)(object)val2 != (Object)null && val2.IsGoonSpawned; } catch { } if (!flag) { RestoreExitGoonName(val2, d); try { FamigliaReskinSync.Unregister(val2); } catch { } DropExitGoon(num); } else if (Time.time > _exitDeadline) { RestoreExitGoonName(val2, d); try { FamigliaReskinSync.Unregister(val2); } catch { } try { val2.Despawn(); } catch { } DropExitGoon(num); } else { try { if (((NPC)val2).FirstName != "Famiglia") { RenameToFamiglia(val2); } } catch { } } } } if (_pendingMode != 0 && !IsRunning && _stagedMode == 0 && Time.time > _pendingExpiresAt) { try { DonMessaging.SendDon("Moment's gone, boss — the targets moved on."); } catch { } ClearPending(); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } if (!IsRunning && _stagedMode != 0) { if (!SessionGate.IsAuthority) { AbortBrawl(); return; } _retargetCd -= dt; if (_retargetCd > 0f) { return; } _retargetCd = 1.5f; PruneCrew(); if (_crew.Count == 0) { try { DonMessaging.SendDon("We got scattered before it started, boss."); } catch { } StandDown(); try { LuckyChatController.RefreshIfHandoverActive(); return; } catch { return; } } Vector3 val4; for (int j = 0; j < _crew.Count; j++) { CartelGoon val3 = _crew[j]; if (!SafeIsSpawned(val3)) { continue; } MakeStagedStationary(val3); try { if (j < _crewPosts.Count && (Object)(object)((Component)val3).transform != (Object)null) { val4 = ((Component)val3).transform.position - _crewPosts[j]; if (((Vector3)(ref val4)).sqrMagnitude > 9f) { ((Component)val3).transform.position = _crewPosts[j]; } } } catch { } } for (int k = 0; k < _rivals.Count; k++) { CartelGoon val5 = _rivals[k]; if (!SafeIsSpawned(val5)) { continue; } MakeStagedStationary(val5); try { if (k < _rivalPosts.Count && (Object)(object)((Component)val5).transform != (Object)null) { val4 = ((Component)val5).transform.position - _rivalPosts[k]; if (((Vector3)(ref val4)).sqrMagnitude > 9f) { ((Component)val5).transform.position = _rivalPosts[k]; } } } catch { } } if (_stagedAnchor != Vector3.zero) { BrawlMarkerQuest.MoveTo(_stagedAnchor); BossMarkerSync.SetPos(_stagedAnchor); } if (_stagedMode == 1 && AnyOfficerOnTheWarpath()) { try { DonMessaging.SendDon("The badges drew first — we're stepping in!"); } catch { } LaunchStagedAttack(); } else if (Time.time > _stagedExpiresAt) { try { DonMessaging.SendDon("We got tired of waiting, boss. Went home."); } catch { } StandDown(); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } } else { if (!IsRunning) { return; } if (!SessionGate.IsAuthority) { AbortBrawl(); return; } if (Time.time >= _endsAt) { EndBrawl("time up"); return; } _retargetCd -= dt; if (_retargetCd > 0f) { return; } _retargetCd = 1.5f; PruneCrew(); if (_crew.Count == 0) { EndBrawl("crew down"); return; } if (AllCrewDown()) { FailBrawl("crew wiped out"); return; } Vector3 val6 = ((_crew.Count > 0 && (Object)(object)_crew[0] != (Object)null && (Object)(object)((Component)_crew[0]).transform != (Object)null) ? ((Component)_crew[0]).transform.position : Vector3.zero); Vector3 val7 = ((val6 != Vector3.zero) ? val6 : ((_stagedAnchor != Vector3.zero) ? _stagedAnchor : TriggerPos())); if (CurrentMode == Mode.Officers) { List list = ((val7 != Vector3.zero) ? CollectOfficersNear(val7, LiveScanRadius) : new List()); if (list.Count == 0) { EndBrawl("badges down"); return; } UpdateOfficerPins(list); PoliceOfficer val8 = NearestOfficer(val7, list); if ((Object)(object)val8 != (Object)null && (Object)(object)((Component)val8).transform != (Object)null) { BrawlMarkerQuest.MoveTo(((Component)val8).transform.position); BossMarkerSync.SetPos(((Component)val8).transform.position); } for (int l = 0; l < _crew.Count; l++) { if ((NeedsNewTarget(l) || CrewCombatIdle(l)) && SafeIsSpawned(_crew[l]) && !((Object)(object)((Component)_crew[l]).transform == (Object)null)) { PoliceOfficer val9 = PickReactiveOrNearestOfficer(l, list); if ((Object)(object)val9 != (Object)null && AssignCrewTarget(l, (NPC)(object)val9) && ModConfig.BrawlOfficersFightBack) { EngageOfficerCounterAttack(val9, _crew[l]); } } } return; } List list2 = CollectBenziesFoes(allowCache: true); if (list2.Count == 0) { EndBrawl("Benzies down"); return; } UpdateFoePins(list2); NPC val10 = NearestFoe(val7, list2); if ((Object)(object)val10 != (Object)null && (Object)(object)((Component)val10).transform != (Object)null) { BrawlMarkerQuest.MoveTo(((Component)val10).transform.position); BossMarkerSync.SetPos(((Component)val10).transform.position); } for (int m = 0; m < _crew.Count; m++) { if ((NeedsNewTarget(m) || CrewCombatIdle(m)) && SafeIsSpawned(_crew[m]) && !((Object)(object)((Component)_crew[m]).transform == (Object)null)) { NPC val11 = PickReactiveOrNearestFoe(m, list2); if ((Object)(object)val11 != (Object)null) { AssignCrewTarget(m, val11); } } } for (int n = 0; n < list2.Count; n++) { NPC val12 = list2[n]; if (!((Object)(object)val12 == (Object)null) && !((Object)(object)((Component)val12).transform == (Object)null) && FoeNeedsTarget(val12)) { NPC val13 = NearestCrew(((Component)val12).transform.position); if ((Object)(object)val13 != (Object)null) { SicGoonOn(val12, val13); } } } } } private static Vector3 TriggerPos() { //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) //IL_0050: 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_003d: Unknown result type (might be due to invalid IL or missing references) try { Player val = RapimentoManager.ResolvePlayerByCode(_triggerWho) ?? Player.Local; if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform != (Object)null) { return ((Component)val).transform.position; } } catch { } return _stagedAnchor; } private static NetworkObject NobOf(NPC n) { try { return ((Object)(object)n != (Object)null && (Object)(object)((Component)n).gameObject != (Object)null) ? ((Component)n).gameObject.GetComponent() : null; } catch { return null; } } private static float SqrToSafe(NPC n, Vector3 from) { //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_0031: Unknown result type (might be due to invalid IL or missing references) try { float result; if (!((Object)(object)n != (Object)null) || !((Object)(object)((Component)n).transform != (Object)null)) { result = float.MaxValue; } else { Vector3 val = ((Component)n).transform.position - from; result = ((Vector3)(ref val)).sqrMagnitude; } return result; } catch { return float.MaxValue; } } private static float SqrToSafe(PoliceOfficer o, Vector3 from) { //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_0031: Unknown result type (might be due to invalid IL or missing references) try { float result; if (!((Object)(object)o != (Object)null) || !((Object)(object)((Component)o).transform != (Object)null)) { result = float.MaxValue; } else { Vector3 val = ((Component)o).transform.position - from; result = ((Vector3)(ref val)).sqrMagnitude; } return result; } catch { return float.MaxValue; } } private static NetworkObject TargetNobOfCb(CombatBehaviour cb) { try { ICombatTargetable val = (((Object)(object)cb != (Object)null) ? cb.Target : null); if (val == null || val.IsNull()) { return null; } return val.NetworkObject; } catch { return null; } } private static PoliceOfficer NearestOfficer(Vector3 from, List cands) { //IL_0057: 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) //IL_0062: Unknown result type (might be due to invalid IL or missing references) PoliceOfficer result = null; float num = float.MaxValue; for (int i = 0; i < cands.Count; i++) { PoliceOfficer val = cands[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } try { if (!((NPC)val).IsCurrentlyTargetable) { continue; } } catch { } Vector3 val2 = ((Component)val).transform.position - from; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } return result; } private static NPC NearestFoe(Vector3 from, List cands) { //IL_0057: 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) //IL_0062: Unknown result type (might be due to invalid IL or missing references) NPC result = null; float num = float.MaxValue; for (int i = 0; i < cands.Count; i++) { NPC val = cands[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } try { if (!val.IsCurrentlyTargetable) { continue; } } catch { } Vector3 val2 = ((Component)val).transform.position - from; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } return result; } private static NPC NearestCrew(Vector3 from) { //IL_007c: 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) //IL_0082: 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) NPC result = null; float num = float.MaxValue; for (int i = 0; i < _crew.Count; i++) { CartelGoon val = _crew[i]; if (!SafeIsSpawned(val) || (Object)(object)((Component)val).transform == (Object)null) { continue; } try { NPCHealth health = ((NPC)val).Health; if ((Object)(object)health != (Object)null && (health.IsDead || health.IsKnockedOut)) { continue; } } catch { } Vector3 val2 = ((Component)val).transform.position - from; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = (NPC)(object)val; } } return result; } private static NPC PickReactiveOrNearestFoe(int crewIdx, List foes) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = NobOf((NPC)(object)_crew[crewIdx]); if ((Object)(object)val != (Object)null) { for (int i = 0; i < foes.Count; i++) { NPC val2 = foes[i]; if (!((Object)(object)val2 == (Object)null)) { NetworkObject val3 = TargetNobOfCb(val2.Behaviour?.CombatBehaviour); if ((Object)(object)val3 != (Object)null && GameCompat.SameInstance((object)val3, (object)val)) { return val2; } } } } return NearestFoe(((Component)_crew[crewIdx]).transform.position, foes); } private static PoliceOfficer PickReactiveOrNearestOfficer(int crewIdx, List cops) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = NobOf((NPC)(object)_crew[crewIdx]); if ((Object)(object)val != (Object)null) { for (int i = 0; i < cops.Count; i++) { PoliceOfficer val2 = cops[i]; if (!((Object)(object)val2 == (Object)null)) { NetworkObject val3 = TargetNobOfCb(((NPC)val2).Behaviour?.CombatBehaviour); if ((Object)(object)val3 != (Object)null && GameCompat.SameInstance((object)val3, (object)val)) { return val2; } } } } return NearestOfficer(((Component)_crew[crewIdx]).transform.position, cops); } private static bool FoeNeedsTarget(NPC foe) { try { CombatBehaviour val = ((foe == null) ? null : foe.Behaviour?.CombatBehaviour); if ((Object)(object)val == (Object)null) { return true; } if (!((Behaviour)val).Active && !((Behaviour)val).Enabled) { return true; } ICombatTargetable target = val.Target; return target == null || target.IsNull(); } catch { return true; } } private static void UpdateOfficerPins(List cops) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(cops.Count, 6); Sprite icon = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); for (int i = 0; i < num; i++) { PoliceOfficer val = cops[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { try { DoorPoiMarker.Set($"brawl_t{i}", ((Component)val).transform.position, "Brawl target", icon); } catch { } } } for (int j = num; j < _targetPinCount; j++) { try { DoorPoiMarker.Remove($"brawl_t{j}"); } catch { } } _targetPinCount = num; } private static void UpdateFoePins(List foes) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(foes.Count, 6); Sprite icon = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); for (int i = 0; i < num; i++) { NPC val = foes[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { try { DoorPoiMarker.Set($"brawl_t{i}", ((Component)val).transform.position, "Brawl target", icon); } catch { } } } for (int j = num; j < _targetPinCount; j++) { try { DoorPoiMarker.Remove($"brawl_t{j}"); } catch { } } _targetPinCount = num; } private static void ClearTargetPins() { for (int i = 0; i < 6; i++) { try { DoorPoiMarker.Remove($"brawl_t{i}"); } catch { } } _targetPinCount = 0; } private static bool NeedsNewTarget(int i) { try { NPC val = _crewTargets[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return true; } NPCHealth health = val.Health; if ((Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut) { return true; } try { if (!val.IsCurrentlyTargetable) { return true; } } catch { } return false; } catch { return true; } } private static bool CrewCombatIdle(int i) { try { CartelGoon obj = _crew[i]; CombatBehaviour val = ((obj == null) ? null : ((NPC)obj).Behaviour?.CombatBehaviour); return (Object)(object)val == (Object)null || (!((Behaviour)val).Active && !((Behaviour)val).Enabled); } catch { return false; } } private static bool AssignBestTarget(int crewIdx, List candidates) { for (int i = 0; i < candidates.Count; i++) { PoliceOfficer val = candidates[(crewIdx + i) % candidates.Count]; if (AssignCrewTarget(crewIdx, (NPC)(object)val)) { if (ModConfig.BrawlOfficersFightBack) { EngageOfficerCounterAttack(val, _crew[crewIdx]); } return true; } } return false; } private static void PruneCrew() { for (int num = _crew.Count - 1; num >= 0; num--) { if (!SafeIsSpawned(_crew[num])) { RestoreGoonDefaults(_crew[num], (num < _crewDefaults.Count) ? _crewDefaults[num] : null); _crew.RemoveAt(num); _crewTargets.RemoveAt(num); if (num < _crewDefaults.Count) { _crewDefaults.RemoveAt(num); } if (num < _crewPosts.Count) { _crewPosts.RemoveAt(num); } } } for (int num2 = _rivals.Count - 1; num2 >= 0; num2--) { if (!SafeIsSpawned(_rivals[num2])) { _rivals.RemoveAt(num2); if (num2 < _rivalPosts.Count) { _rivalPosts.RemoveAt(num2); } } } } private static bool SafeIsSpawned(CartelGoon g) { try { return (Object)(object)g != (Object)null && g.IsGoonSpawned; } catch { return false; } } private static bool AllCrewDown() { if (_crew.Count == 0) { return false; } for (int i = 0; i < _crew.Count; i++) { CartelGoon val = _crew[i]; if (SafeIsSpawned(val)) { bool flag = true; try { NPCHealth health = ((NPC)val).Health; flag = (Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut; } catch { flag = true; } if (!flag) { return false; } } } return true; } private static void Activate(Mode m, string sms) { CurrentMode = m; _endsAt = Time.time + 120f; _retargetCd = 1.5f; try { DonMessaging.SendDon(sms); } catch { } try { BrawlMarkerQuest.SetText("Brawl underway — follow the marker"); } catch { } try { BossMarkerSync.SetLabel("Brawl underway — follow the marker"); } catch { } NDLog.Info($"Brawl started: mode={m} crew={_crew.Count} rivals={_rivals.Count}"); } private static void EndBrawl(string reason) { Teardown(exitWalk: true); _cooldownUntil = Time.time + 120f; try { DonMessaging.SendDon("Brawl's over, boss. We walked away grinning."); } catch { } try { LuckyChatController.RefreshIfHandoverActive(); } catch { } NDLog.Info("Brawl ended (" + reason + ")."); } private static void FailBrawl(string reason) { try { BrawlMarkerQuest.FailAndClear(); } catch { } Teardown(exitWalk: true); _cooldownUntil = Time.time + 120f; try { DonMessaging.SendDon("They put our men in the dirt, boss. We lost this one — we'll make it right."); } catch { } try { LuckyChatController.RefreshIfHandoverActive(); } catch { } NDLog.Info("Brawl FAILED (" + reason + ")."); } private static void AbortBrawl() { if (IsRunning || _stagedMode != 0 || _crew.Count > 0 || _rivals.Count > 0) { Teardown(); } FlushExitGoons(); } private static void Teardown(bool exitWalk = false) { try { RestoreForcedOfficers(); } catch { } for (int i = 0; i < _engagedOfficers.Count; i++) { try { PoliceOfficer obj2 = _engagedOfficers[i]; CombatBehaviour val = ((obj2 == null) ? null : ((NPC)obj2).Behaviour?.CombatBehaviour); if ((Object)(object)val != (Object)null) { try { ((Behaviour)val).Deactivate(); } catch { } try { ((Behaviour)val).Disable(); } catch { } } } catch { } } _engagedOfficers.Clear(); ReleaseCrew(_crew, _crewDefaults, exitWalk); ReleaseCrew(_rivals, null, exitWalk: false); _crewTargets.Clear(); _crewPosts.Clear(); _rivalPosts.Clear(); _pool = null; CurrentMode = Mode.None; _stagedMode = 0; try { BrawlMarkerQuest.CompleteAndClear(); } catch { } try { BossMarkerSync.Clear(); } catch { } try { ClearTargetPins(); } catch { } } private static void ReleaseCrew(List list, List defaults, bool exitWalk) { for (int i = 0; i < list.Count; i++) { CartelGoon val = list[i]; if ((Object)(object)val == (Object)null) { continue; } bool flag = false; try { flag = val.IsGoonSpawned; } catch { } bool flag2 = false; if (exitWalk && flag) { try { NPCHealth health = ((NPC)val).Health; flag2 = (Object)(object)health != (Object)null && !health.IsDead && !health.IsKnockedOut; } catch { } } RestoreGoonDefaults(val, (defaults != null && i < defaults.Count) ? defaults[i] : null, flag2); if (!flag) { continue; } if (flag2) { try { CombatBehaviour val2 = ((NPC)val).Behaviour?.CombatBehaviour; if ((Object)(object)val2 != (Object)null) { try { ((Behaviour)val2).Deactivate(); } catch { } try { ((Behaviour)val2).Disable(); } catch { } } } catch { } _exitGoons.Add(val); _exitGoonDefaults.Add((defaults != null && i < defaults.Count) ? defaults[i] : null); } else { try { val.Despawn(); } catch { } } } list.Clear(); defaults?.Clear(); if (_exitGoons.Count > 0) { _exitDeadline = Time.time + 45f; } } internal static void ReclaimExitGoons() { FlushExitGoons(); } private static void DropExitGoon(int e) { if (e >= 0 && e < _exitGoons.Count) { _exitGoons.RemoveAt(e); } if (e >= 0 && e < _exitGoonDefaults.Count) { _exitGoonDefaults.RemoveAt(e); } } private static void FlushExitGoons() { for (int i = 0; i < _exitGoons.Count; i++) { CartelGoon val = _exitGoons[i]; RestoreExitGoonName(val, (i < _exitGoonDefaults.Count) ? _exitGoonDefaults[i] : null); try { FamigliaReskinSync.Unregister(val); } catch { } try { if ((Object)(object)val != (Object)null && val.IsGoonSpawned) { val.Despawn(); } } catch { } } _exitGoons.Clear(); _exitGoonDefaults.Clear(); } internal static GoonDefaults CaptureGoonDefaults(CartelGoon g) { GoonDefaults goonDefaults = new GoonDefaults(); try { try { goonDefaults.FirstName = ((NPC)g).FirstName; goonDefaults.LastName = ((NPC)g).LastName; goonDefaults.HasLastName = ((NPC)g).NPCData.BasicInfo.HasLastName; } catch { } try { NPCHealth health = ((NPC)g).Health; if ((Object)(object)health != (Object)null) { goonDefaults.Invincible = health.npc.NPCData.Health.Invincible; } } catch { } try { CombatBehaviour val = ((NPC)g).Behaviour?.CombatBehaviour; if ((Object)(object)val != (Object)null) { goonDefaults.GiveUpRange = val.GiveUpRange; goonDefaults.DefaultWeapon = val._defaultWeapon; try { goonDefaults.DefaultSearchTime = val.DefaultSearchTime; } catch { } } } catch { } try { NPCScheduleManager val2 = (((Object)(object)((Component)g).gameObject != (Object)null) ? ((Component)g).gameObject.GetComponentInChildren(true) : null); if ((Object)(object)val2 != (Object)null) { goonDefaults.SchedCompEnabled = ((Behaviour)val2).enabled; } } catch { } } catch { } return goonDefaults; } internal static void RestoreGoonDefaults(CartelGoon g, GoonDefaults d) { RestoreGoonDefaults(g, d, keepFamiglia: false); } private static void RestoreExitGoonName(CartelGoon g, GoonDefaults d) { if ((Object)(object)g == (Object)null || d == null) { return; } try { if (d.FirstName != null) { ((NPC)g).NPCData.BasicInfo.FirstName = d.FirstName; } ((NPC)g).NPCData.BasicInfo.HasLastName = d.HasLastName; if (d.LastName != null) { ((NPC)g).NPCData.BasicInfo.LastName = d.LastName; } } catch { } } internal static void RestoreGoonDefaults(CartelGoon g, GoonDefaults d, bool keepFamiglia) { if ((Object)(object)g == (Object)null) { return; } if (!keepFamiglia) { try { FamigliaReskinSync.Unregister(g); } catch { } } try { NPCMovement movement = ((NPC)g).Movement; if ((Object)(object)movement != (Object)null) { try { movement.ResumeMovement(); } catch { } try { movement.SetAgentEnabled(true); } catch { } try { ((Behaviour)movement).enabled = true; } catch { } } } catch { } try { NPCScheduleManager val = (((Object)(object)((Component)g).gameObject != (Object)null) ? ((Component)g).gameObject.GetComponentInChildren(true) : null); if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = d?.SchedCompEnabled ?? true; try { val.EnableSchedule(); } catch { } } } catch { } if (d == null) { return; } try { if (keepFamiglia) { RenameToFamiglia(g); } else { if (d.FirstName != null) { ((NPC)g).NPCData.BasicInfo.FirstName = d.FirstName; } ((NPC)g).NPCData.BasicInfo.HasLastName = d.HasLastName; if (d.LastName != null) { ((NPC)g).NPCData.BasicInfo.LastName = d.LastName; } } } catch { } try { NPCHealth health = ((NPC)g).Health; if ((Object)(object)health != (Object)null) { health.npc.NPCData.Health.Invincible = d.Invincible; } } catch { } try { CombatBehaviour val2 = ((NPC)g).Behaviour?.CombatBehaviour; if ((Object)(object)val2 != (Object)null) { val2.GiveUpRange = d.GiveUpRange; val2.SetDefaultWeapon(d.DefaultWeapon); try { val2.DefaultSearchTime = d.DefaultSearchTime; return; } catch { return; } } } catch { } } private static Vector3 RandomRingDir() { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized; if (((Vector2)(ref val)).sqrMagnitude < 0.01f) { val = Vector2.right; } return new Vector3(val.x, 0f, val.y); } private static Vector3 FindNavPointNear(Vector3 p) { //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_000d: 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_003a: 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_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_003e: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(p + Vector3.up * 1.5f, ref val, 12f, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return p; } } internal static class LuckyChatController { private static int _groupIdx; private static int _groupPage; private static char _pickedLetter = 'A'; private static List _currentPool; private static int _poolIdx; private const int GROUP_SIZE = 4; private const int GROUPS_PER_PAGE = 4; private const string BOSS_CATEGORY = "all"; private static bool? _cartelEnforcerLoaded; private static int _clientBrawlPhaseShown = 0; private static bool _clientPhoneWasOpen; private static int GroupCount => (LuckyTargetPicker.Letters.Length + 4 - 1) / 4; public static void Reset() { _groupIdx = 0; _groupPage = 0; _pickedLetter = 'A'; _currentPool = null; _poolIdx = 0; } public static void OpenMainMenu() { DonMessaging.ClearChoiceButtons(); Reset(); List list = new List { "Contratto Famiglia", "Contratto Boss" }; List list2 = new List(); list2.Add(StartFamigliaContratto); list2.Add(ShowBossEntry); List list3 = list2; if (TerritoryHandover.IsBossForLocalPeer) { list.Add("Headquarter"); list3.Add(ShowHeadquarterMenu); } DonMessaging.RegisterChoiceButtons(list, list3); } private static bool Relay(string key) { if (SessionGate.IsAuthority) { return false; } try { ClientActionNet.SendAction("chat", key); } catch { } return true; } internal static void HostTriggerChat(string data, string who = "") { try { if (!SessionGate.IsAuthority || string.IsNullOrEmpty(data)) { return; } if (data.StartsWith("sendlucky;", StringComparison.Ordinal)) { string[] array = data.Split(new char[1] { ';' }); if (array.Length >= 3) { HostSendLuckyById(array[1], int.TryParse(array[2], out var result) ? result : 0); } return; } switch (data) { case "FamigliaContratto": PizzoJobManager.StartFamigliaContrattoFromChat(); break; case "Protection": PizzoJobManager.StartProtectionFromChat(); break; case "SmugWeapons": PizzoJobManager.StartSmugglingFromChat(weapons: true); break; case "SmugDrugs": PizzoJobManager.StartSmugglingFromChat(weapons: false); break; case "Informanti": InformantiManager.StartFromChat(); break; case "BrawlOfficers": LuckyBrawlManager.StartBrawlFromChat(officers: true, who); break; case "BrawlBenzies": LuckyBrawlManager.StartBrawlFromChat(officers: false, who); break; case "BrawlSend": LuckyBrawlManager.ConfirmPendingBrawl(); break; case "BrawlAttack": LuckyBrawlManager.LaunchStagedAttack(); break; case "BrawlCancel": LuckyBrawlManager.CancelPendingBrawl(); break; case "BrawlCallOff": LuckyBrawlManager.CallOffStaged(); break; case "ToggleEscort": RealEstateManager.ToggleEscortFromChat(); break; case "Status": RealEstateManager.StatusFromChat(); break; case "CarBomb": CarBombManager.BeginPlacementFromChat(); break; case "Rapimento": RapimentoManager.HostStartForClient(who, null); break; case "Tortura": RapimentoManager.StartTorturaFromChat(); break; case "Esecuzione": RapimentoManager.StartEsecuzioneFromChat(); break; case "MarkBomba": LaBombaManager.MarkSpotFromChat(who); break; case "PlantBomba": LaBombaManager.StartFromChat(who); break; default: NDLog.DebugWarn("[CHAT] unknown client trigger '" + data + "'."); break; } NDLog.Debug("[CHAT] client-requested '" + data + "' executed on host."); } catch (Exception ex) { NDLog.Warn("HostTriggerChat(" + data + "): " + ex.Message); } } private static void HostSendLuckyById(string npcId, int method) { try { if (!string.IsNullOrEmpty(npcId)) { NPC nPC = NPCManager.GetNPC(npcId); if ((Object)(object)nPC == (Object)null) { NDLog.DebugWarn("[CHAT] sendlucky: NPC '" + npcId + "' not resolvable on host."); return; } string text = LuckyTargetPicker.SafeName(nPC); LuckyTargetPicker.Choice pick = new LuckyTargetPicker.Choice { Npc = nPC, DisplayName = (string.IsNullOrEmpty(text) ? npcId : text), Category = LuckyTargetPicker.ClassifyCategory(nPC) }; PizzoJobManager.StartContrattoBossFromChat(pick, method); } } catch (Exception ex) { NDLog.Warn("HostSendLuckyById(" + npcId + "): " + ex.Message); } } private static void ShowHeadquarterMenu() { List texts = new List { "Smuggling", "Protection", "Brawl", "Informanti", "Guards", "Back" }; List list = new List(); list.Add(ShowSmugglingMenu); list.Add(StartProtection); list.Add(ShowBrawlMenu); list.Add(StartInformanti); list.Add(ShowRealEstateMenu); list.Add(OpenMainMenu); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions); } private static void ShowRealEstateMenu() { List list = new List(); List list2 = new List(); if (!RealEstateManager.VillaOwned) { list.Add("How do we buy?"); list2.Add(RealEstateAppHint); } else { list.Add(RealEstateManager.HasEscort ? "Back to posts" : "Walk with me"); list2.Add(ToggleCircoloEscort); list.Add("Status"); list2.Add(CircoloStatus); } list.Add("Back"); list2.Add(ShowHeadquarterMenu); DonMessaging.RegisterChoiceButtons(list, list2); } private static void RealEstateAppHint() { try { DonMessaging.SendDon("Open the FAMIGLIA app on your phone, boss — Real Estate. The Villa and the depositi are waiting for your signature."); } catch (Exception ex) { NDLog.Warn("RealEstateAppHint: " + ex.Message); } ShowRealEstateMenu(); } private static void ToggleCircoloEscort() { if (!Relay("ToggleEscort")) { try { RealEstateManager.ToggleEscortFromChat(); } catch (Exception ex) { NDLog.Warn("ToggleCircoloEscort: " + ex.Message); } } ShowRealEstateMenu(); } private static void CircoloStatus() { if (!Relay("Status")) { try { RealEstateManager.StatusFromChat(); } catch (Exception ex) { NDLog.Warn("CircoloStatus: " + ex.Message); } } ShowRealEstateMenu(); } private static void StartInformanti() { if (!Relay("Informanti")) { try { InformantiManager.StartFromChat(); } catch (Exception ex) { NDLog.Warn("StartInformanti: " + ex.Message); } } ShowHeadquarterMenu(); } private static void ShowSmugglingMenu() { List texts = new List { "Weapons (Pump Shotgun)", "Drugs (Brick Cocaine)", "Back" }; List list = new List(); list.Add(delegate { StartSmuggling(weapons: true); }); list.Add(delegate { StartSmuggling(weapons: false); }); list.Add(ShowHeadquarterMenu); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions); } private static void StartSmuggling(bool weapons) { if (!Relay(weapons ? "SmugWeapons" : "SmugDrugs")) { try { PizzoJobManager.StartSmugglingFromChat(weapons); Reset(); } catch (Exception ex) { NDLog.Warn("StartSmuggling: " + ex.Message); } } ShowHeadquarterMenu(); } private static void StartProtection() { if (!Relay("Protection")) { try { PizzoJobManager.StartProtectionFromChat(); Reset(); } catch (Exception ex) { NDLog.Warn("StartProtection: " + ex.Message); } } ShowHeadquarterMenu(); } private static void ShowBrawlMenu() { List list = new List { "Officers", "Benzies" }; List list2 = new List { delegate { StartBrawl(officers: true); }, delegate { StartBrawl(officers: false); } }; if (IsCartelEnforcerLoaded()) { list.Add("Cartel Enforcer"); list2.Add(ShowBrawlMenu); } list.Add("Back"); list2.Add(ShowHeadquarterMenu); DonMessaging.RegisterChoiceButtons(list, list2); } private static bool IsCartelEnforcerLoaded() { if (_cartelEnforcerLoaded.HasValue) { return _cartelEnforcerLoaded.Value; } bool flag = false; try { ReadOnlyCollection registeredMelons = MelonBase.RegisteredMelons; if (registeredMelons != null) { foreach (MelonBase item in registeredMelons) { string text = null; try { object obj; if (item == null) { obj = null; } else { MelonInfoAttribute info = item.Info; obj = ((info != null) ? info.Name : null); } text = (string)obj; } catch { } if (!string.IsNullOrEmpty(text) && text.Replace(" ", "").IndexOf("CartelEnforcer", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } } } catch (Exception ex) { NDLog.DebugWarn("IsCartelEnforcerLoaded: " + ex.Message); } _cartelEnforcerLoaded = flag; if (flag) { NDLog.Debug("Cartel Enforcer detected — Brawl menu shows the placeholder button."); } return flag; } private static void StartBrawl(bool officers) { if (Relay(officers ? "BrawlOfficers" : "BrawlBenzies")) { ShowHeadquarterMenu(); return; } try { LuckyBrawlManager.StartBrawlFromChat(officers); Reset(); } catch (Exception ex) { NDLog.Warn("StartBrawl: " + ex.Message); try { RefreshIfHandoverActive(); } catch { } } } public static void ShowBrawlConfirmMenu() { List texts = new List { "Send the men", "Not yet" }; List list = new List(); list.Add(ConfirmBrawl); list.Add(CancelBrawlScout); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions); } private static void ConfirmBrawl() { if (Relay("BrawlSend")) { return; } try { LuckyBrawlManager.ConfirmPendingBrawl(); Reset(); } catch (Exception ex) { NDLog.Warn("ConfirmBrawl: " + ex.Message); } } private static void CancelBrawlScout() { if (Relay("BrawlCancel")) { ShowHeadquarterMenu(); return; } try { LuckyBrawlManager.CancelPendingBrawl(); } catch { } ShowHeadquarterMenu(); } public static void ShowBrawlAttackMenu() { List texts = new List { "Attack", "Call them back" }; List list = new List(); list.Add(LaunchBrawlAttack); list.Add(CallOffBrawl); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions); } private static void LaunchBrawlAttack() { if (Relay("BrawlAttack")) { _clientBrawlPhaseShown = 0; OpenMainMenu(); return; } try { LuckyBrawlManager.LaunchStagedAttack(); Reset(); } catch (Exception ex) { NDLog.Warn("LaunchBrawlAttack: " + ex.Message); } OpenMainMenu(); } private static void CallOffBrawl() { if (Relay("BrawlCallOff")) { _clientBrawlPhaseShown = 0; ShowHeadquarterMenu(); return; } try { LuckyBrawlManager.CallOffStaged(); } catch { } ShowHeadquarterMenu(); } public static void ClientBrawlMenuTick() { try { if (SessionGate.IsAuthority || !TerritoryHandover.IsBossForLocalPeer) { return; } int remoteBrawlPhase = QuestNetSync.RemoteBrawlPhase; bool flag = false; try { flag = DonMessaging.IsPhoneOpen(); } catch { } bool flag2 = flag && !_clientPhoneWasOpen; _clientPhoneWasOpen = flag; if (remoteBrawlPhase != _clientBrawlPhaseShown || (flag2 && remoteBrawlPhase != 0)) { _clientBrawlPhaseShown = remoteBrawlPhase; switch (remoteBrawlPhase) { case 1: ShowBrawlConfirmMenu(); break; case 2: ShowBrawlAttackMenu(); break; default: OpenMainMenu(); break; } } } catch (Exception ex) { NDLog.DebugWarn("ClientBrawlMenuTick: " + ex.Message); } } private static void StartFamigliaContratto() { if (!Relay("FamigliaContratto")) { try { PizzoJobManager.StartFamigliaContrattoFromChat(); } catch (Exception ex) { NDLog.Warn("StartFamigliaContratto: " + ex.Message); } } OpenMainMenu(); } private static void ShowBossEntry() { _groupPage = 0; List texts = new List { "Lista Nera", "Pacco Bomba", "Operations", "Back" }; List list = new List(); list.Add(delegate { ShowGroupPage(0); }); list.Add(ShowBombaMenu); list.Add(ShowOperazioniMenu); list.Add(OpenMainMenu); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions); } private static void ShowOperazioniMenu() { List texts = new List { "Car Bomb", "Kidnapping", "Torture", "Execution", "Back" }; List list = new List(); list.Add(StartCarBomb); list.Add(StartRapimento); list.Add(StartTortura); list.Add(StartEsecuzione); list.Add(ShowBossEntry); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions); } private static void StartCarBomb() { try { CarBombManager.BeginPlacementFromChat(); } catch (Exception ex) { NDLog.Warn("StartCarBomb: " + ex.Message); } DonMessaging.CloseChoiceMenu(); } private static void StartRapimento() { if (!Relay("Rapimento")) { try { RapimentoManager.StartRapimentoFromChat(); } catch (Exception ex) { NDLog.Warn("StartRapimento: " + ex.Message); } } DonMessaging.CloseChoiceMenu(); } private static void StartTortura() { if (!Relay("Tortura")) { try { RapimentoManager.StartTorturaFromChat(); } catch (Exception ex) { NDLog.Warn("StartTortura: " + ex.Message); } } DonMessaging.CloseChoiceMenu(); } private static void StartEsecuzione() { if (!Relay("Esecuzione")) { try { RapimentoManager.StartEsecuzioneFromChat(); } catch (Exception ex) { NDLog.Warn("StartEsecuzione: " + ex.Message); } } DonMessaging.CloseChoiceMenu(); } private static void OperazioneComingSoon(string what) { try { DonMessaging.SendDon(what + "? Pazienza, boss — that one's still in the works. Soon."); } catch (Exception ex) { NDLog.Warn("OperazioneComingSoon(" + what + "): " + ex.Message); } ShowOperazioniMenu(); } private static void ShowBombaMenu() { DonMessaging.SendDon("Pacco Bomba: stand on the spot and mark it — then give the word from wherever you like. 45 seconds of fuse."); ShowBombaButtons(); } private static void ShowBombaButtons() { List texts = new List { "Mark this spot", "Plant the bomb", "Back" }; List list = new List(); list.Add(MarkBombaSpot); list.Add(PlantBomba); list.Add(ShowBossEntry); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions); } private static void MarkBombaSpot() { if (!Relay("MarkBomba")) { try { LaBombaManager.MarkSpotFromChat(); } catch (Exception ex) { NDLog.Warn("MarkBombaSpot: " + ex.Message); } } ShowBombaButtons(); } private static void PlantBomba() { if (!Relay("PlantBomba")) { try { LaBombaManager.StartFromChat(); } catch (Exception ex) { NDLog.Warn("PlantBomba: " + ex.Message); } } ShowBossEntry(); } private static void ComingSoon() { try { DonMessaging.SendDon("Pazienza. That one's still in the works."); } catch { } ShowHeadquarterMenu(); } private static void ShowGroupPage(int page) { int groupCount = GroupCount; int num = (groupCount + 4 - 1) / 4; if (num <= 0) { num = 1; } page = (page % num + num) % num; _groupPage = page; List list = new List(); List list2 = new List(); int num2 = page * 4; int num3 = Math.Min(num2 + 4, groupCount); for (int i = num2; i < num3; i++) { int gi = i; int num4 = i * 4; int num5 = Math.Min(num4 + 4, LuckyTargetPicker.Letters.Length) - 1; char c = LuckyTargetPicker.Letters[num4]; char c2 = LuckyTargetPicker.Letters[num5]; list.Add((c == c2) ? $"{c}" : $"{c}-{c2}"); list2.Add(delegate { ShowLetterMenu(gi); }); } if (num > 1) { int cur = page; list.Add("More ▶"); list2.Add(delegate { ShowGroupPage(cur + 1); }); } list.Add("Back"); list2.Add(ShowBossEntry); DonMessaging.RegisterChoiceButtons(list, list2); } private static void ShowLetterMenu(int groupIdx) { _groupIdx = groupIdx; List list = new List(); List list2 = new List(); int num = groupIdx * 4; int num2 = Math.Min(num + 4, LuckyTargetPicker.Letters.Length); for (int i = num; i < num2; i++) { char letter = LuckyTargetPicker.Letters[i]; list.Add($"{letter}"); list2.Add(delegate { OnLetterPicked(letter); }); } list.Add("Back"); list2.Add(delegate { ShowGroupPage(_groupPage); }); DonMessaging.RegisterChoiceButtons(list, list2); } private static void OnLetterPicked(char letter) { _pickedLetter = letter; _currentPool = LuckyTargetPicker.BuildPoolByLetter(letter, "all"); _poolIdx = 0; if (_currentPool == null || _currentPool.Count == 0) { DonMessaging.SendDon($"Nobody whose name starts with '{letter}' right now. Pick another letter."); ShowLetterMenu(_groupIdx); } else { ShowCurrentTarget(); } } private static void ShowCurrentTarget() { if (_currentPool == null || _currentPool.Count == 0) { ShowLetterMenu(_groupIdx); return; } if (_poolIdx >= _currentPool.Count) { _poolIdx = 0; } LuckyTargetPicker.Choice choice = _currentPool[_poolIdx]; DonMessaging.SendDon(LoreStrings.LuckyTargetPreviewSms(choice.DisplayName, LuckyTargetPicker.CategoryLabel(choice.Category))); List texts = new List { "Show next", "Melee - Raid", "Cold Blood - Flatline", "Back" }; List list = new List(); list.Add(ShowNextTarget); list.Add(delegate { SendLucky(1); }); list.Add(delegate { SendLucky(2); }); list.Add(delegate { ShowLetterMenu(_groupIdx); }); List actions = list; DonMessaging.RegisterChoiceButtons(texts, actions, expandAfter: false); } private static void ShowNextTarget() { if (_currentPool == null || _currentPool.Count == 0) { ShowLetterMenu(_groupIdx); return; } _poolIdx = (_poolIdx + 1) % _currentPool.Count; ShowCurrentTarget(); } private static void SendLucky(int method) { if (!SessionGate.IsAuthority) { try { if (_currentPool != null && _poolIdx < _currentPool.Count) { LuckyTargetPicker.Choice choice = _currentPool[_poolIdx]; string text = null; try { text = (((Object)(object)choice.Npc != (Object)null) ? choice.Npc.ID : null); } catch { } if (!string.IsNullOrEmpty(text)) { ClientActionNet.SendAction("chat", $"sendlucky;{text};{method}"); } else { DonMessaging.SendDon("Can't reach that one from here, boss."); } } } catch (Exception ex) { NDLog.DebugWarn("SendLucky(client): " + ex.Message); } Reset(); OpenMainMenu(); return; } try { if (_currentPool == null || _poolIdx >= _currentPool.Count) { return; } LuckyTargetPicker.Choice pick = _currentPool[_poolIdx]; PizzoJobManager.StartContrattoBossFromChat(pick, method); Reset(); } catch (Exception ex2) { NDLog.Warn("SendLucky: " + ex2.Message); } OpenMainMenu(); } public static void RefreshIfHandoverActive() { if (TerritoryHandover.HandoverActive && !DonMessaging.IsPhoneOpen()) { OpenMainMenu(); } } } internal static class LuckyCombatDriver { public enum State { Idle, Spawning, Fighting, Despawning, Done, Failed } public enum Fail { None, LuckyDown, Timeout, NoTarget, NoCombat } private const float SPAWN_RADIUS = 32f; private const float DESPAWN_REACH = 3f; private const float REPATH_INTERVAL = 0.4f; private const float SPAWN_TIMEOUT = 6f; private const float SPAWN_GRACE = 8f; private const float FIGHT_TIMEOUT = 120f; private const float DESPAWN_TIMEOUT = 25f; private const float MAX_JOB_SECONDS = 170f; private const float GIVE_UP_RANGE = 1000f; private const float ENGAGE_RANGE_FIREARM = 14f; private const float ENGAGE_RANGE_MELEE = 4f; private const float SHOOTABLE_RECHECK = 0.2f; private static float _shootableCd; private static bool _firearmShootableCached; private const float FALLBACK_REACHABLE_AFTER = 15f; private const float FALLBACK_UNREACHABLE_AFTER = 22f; private const float LOS_NUDGE_AFTER = 2.5f; private const float LOS_NUDGE_RANGE = 8f; private static NPC _targetNpc; private static Player _targetPlayer; private static int _method; private static int _posSyncTick; private static float _stateTimer; private static float _jobTimer; private static float _repathCd; private static float _reactionCd; private static bool _engaged; private static float _engageStallTimer; private static bool _hitConfirmed; private static bool _rangedKicked; private static Vector3 _approachDest; private static bool _approachSet; private static int _swingSeq; private static float _fireVisCd; private const float FIRE_VIS_INTERVAL = 0.8f; private static bool _weaponRaised; private static float _meleeVisCd; private const float MELEE_VIS_INTERVAL = 0.7f; private static VisionCone _visionCone; private static Vector3 _despawnDoor; private static bool _haveDoor; private static string _targetName; private static bool _spawnFirstTick; private static bool _resolveLogged; private static MethodInfo _removePanickedMi; private static bool _removePanickedResolved; public static State CurrentState { get; private set; } public static Fail FailReason { get; private set; } public static bool IsRunning => CurrentState != State.Idle && CurrentState != State.Done && CurrentState != State.Failed; public static bool Succeeded => CurrentState == State.Done; public static bool HasFailed => CurrentState == State.Failed; internal static CartelGoon ActiveLuckyGoon => null; public static int CurrentMethod => _method; public static void Begin(NPC npc, Player player, int method, string targetName) { _targetNpc = npc; _targetPlayer = player; _method = method; _targetName = targetName; _stateTimer = 0f; _jobTimer = 0f; _repathCd = 0f; _reactionCd = 0f; _engaged = false; _engageStallTimer = 0f; _hitConfirmed = false; _haveDoor = false; _spawnFirstTick = true; _resolveLogged = false; _rangedKicked = false; _approachSet = false; _swingSeq = 0; _fireVisCd = 0f; _weaponRaised = false; _meleeVisCd = 0f; _visionCone = null; FailReason = Fail.None; CurrentState = State.Spawning; NDLog.Debug($"LuckyCombatDriver.Begin: method={method} target='{SafeName()}' (player={(Object)(object)player != (Object)null})."); } public static void Reset() { CurrentState = State.Idle; FailReason = Fail.None; _targetNpc = null; _targetPlayer = null; _method = 0; _haveDoor = false; _targetName = null; _spawnFirstTick = false; _resolveLogged = false; } public static void Abort() { TeardownAndPark(); Reset(); } public static void Tick(float dt) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (!IsRunning || !SessionGate.IsAuthority) { return; } _jobTimer += dt; _stateTimer += dt; if (LuckyNPC.IsDownAndOut) { if (_hitConfirmed) { FinishDespawn(); } else { Failt(Fail.LuckyDown); } return; } NPC npc = LuckyNPC.GetNpc(); if ((Object)(object)npc == (Object)null || (Object)(object)((Component)npc).transform == (Object)null) { return; } if (++_posSyncTick >= 6) { _posSyncTick = 0; try { LuckyNetSync.PublishState(active: true, _method, _swingSeq, ((Component)npc).transform.position); } catch { } } switch (CurrentState) { case State.Spawning: TickSpawning(npc); break; case State.Fighting: TickFighting(npc, dt); break; case State.Despawning: TickDespawning(npc, dt); break; } } private static void TickSpawning(NPC lucky) { //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: 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_00df: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0352: 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_0263: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_0165: 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_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: 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) //IL_0200: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: 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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022f: 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_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_031d: 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_0338: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0300: 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) if (_spawnFirstTick) { _spawnFirstTick = false; DiagnoseTargetOnce(); if ((Object)(object)_targetPlayer == (Object)null) { NPCHealth val = SafeTargetHealth(); if ((Object)(object)val != (Object)null && SafeIsDead(val)) { NDLog.Warn("LuckyCombatDriver: mark already dead at dispatch — NoTarget (no reward for a corpse)."); Failt(Fail.NoTarget); return; } } } if ((Object)(object)_targetPlayer != (Object)null) { if (!TargetExists()) { Failt(Fail.NoTarget); return; } } else if (!TargetExists() && !TryReResolveTarget()) { if (!(_stateTimer < 8f)) { OffScreenComplete(lucky); } return; } Vector3 val2 = TargetPos(); Vector3 doorPos = val2; bool flag = false; try { flag = (Object)(object)_targetNpc != (Object)null && (Object)(object)_targetNpc.CurrentBuilding != (Object)null; } catch { } bool flag2 = flag && DoorLocator.TryGetTargetOwnDoor(_targetNpc, out doorPos); if (flag2) { NDLog.Debug("Lucky spawn = target's OWN building door (indoor target, #9a)."); } else { flag2 = DoorLocator.TryGetNearestSpawnDoor(val2, _targetNpc, out doorPos); } bool flag3; if (flag2) { try { NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(doorPos + Vector3.up * 1f, ref val3, 6f, -1)) { doorPos = ((NavMeshHit)(ref val3)).position; } } catch { } flag3 = IsPathComplete(doorPos, val2); NDLog.Debug(string.Format("Lucky spawn door {0:F1} m from target ({1}).", HorizontalDist(doorPos, val2), flag3 ? "path ok" : "no path")); } else { flag3 = TryFindReachableSpawn(val2, out doorPos); if (!flag3) { if (_stateTimer < 6f) { return; } Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val4 = ((Vector2)(ref insideUnitCircle)).normalized; if (((Vector2)(ref val4)).sqrMagnitude < 0.01f) { val4 = Vector2.right; } doorPos = val2 + new Vector3(val4.x, 0f, val4.y) * 32f; } } if ((Object)(object)_targetPlayer == (Object)null) { Vector3 val5 = val2; if (StageTargetForExecution(out var stagedPos, out var outwardDir)) { val2 = stagedPos; Vector3 awayDir = outwardDir; awayDir.y = 0f; if (((Vector3)(ref awayDir)).sqrMagnitude < 0.01f) { awayDir = val2 - val5; awayDir.y = 0f; } if (((Vector3)(ref awayDir)).sqrMagnitude < 0.01f) { awayDir = val2 - ((Component)lucky).transform.position; awayDir.y = 0f; } if (((Vector3)(ref awayDir)).sqrMagnitude < 0.01f) { awayDir = Vector3.right; } Vector3 val6 = FindLosGroundPlacement(val2, awayDir, 5f); doorPos = val6; flag3 = true; bool flag4 = HasLineOfSightFrom(val6, val2); NDLog.Debug($"Lucky: target staged at its OWN door, frozen — Lucky placed @ {val6} (LOS={flag4}, {HorizontalDist(doorPos, val2):F1} m)."); } } if (!LuckyNPC.PlaceForCombat(doorPos, val2)) { return; } LuckyNPC.EnableCombatSystems(); if (!StartRealCombat(lucky)) { Failt(Fail.NoCombat); return; } try { LuckyNetSync.PublishState(active: true, _method, 0); } catch { } float num = HorizontalDist(((Component)lucky).transform.position, val2); NDLog.Debug(string.Format("Lucky spawned {0:F1} m from target ({1}) — real combat starting.", num, flag3 ? "reachable" : "best-effort")); if (_method == 2) { AimVisionConeAtTarget(lucky, val2); } ToState(State.Fighting); } private static void TickFighting(NPC lucky, float dt) { //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: 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_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_029d: 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_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: 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_0141: 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_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: 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_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0215: 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_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) if (IsTargetNeutralized()) { NDLog.Debug("Lucky: target '" + SafeName() + "' eliminated in real combat (no fallback)."); BeginDespawn(lucky); return; } if (!TargetAlive()) { BeginDespawn(lucky); return; } if (_engaged) { _engageStallTimer = 0f; } else if ((Object)(object)_targetPlayer == (Object)null) { _engageStallTimer += dt; if (_engageStallTimer >= 30f) { NDLog.Warn("Lucky: unreachable indoor mark '" + SafeName() + "' (never engaged in 30s) — off-screen finish."); _engageStallTimer = 0f; OffScreenComplete(lucky); return; } } Vector3 val = TargetPos(); float num = HorizontalDist(((Component)lucky).transform.position, val); bool flag = _method == 2; if (flag) { _shootableCd -= dt; if (_shootableCd <= 0f) { _shootableCd = 0.2f; _firearmShootableCached = HasLineOfSight(lucky, val) && PathIsDirect(((Component)lucky).transform.position, val) && !GlassBetween(((Component)lucky).transform.position, val); } } bool flag2 = flag && num <= 14f && _firearmShootableCached; bool flag3 = (flag ? flag2 : (num <= 4f)); if (flag3) { _engaged = true; } if (flag) { if (!_rangedKicked && HasLineOfSight(lucky, val)) { TryKickRangedRoutine(GetCombat(lucky)); } ApplyCloseRangeBand(GetCombat(lucky)); if (flag3) { Vector3 val2 = val - ((Component)lucky).transform.position; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.01f) { try { ((Component)lucky).transform.rotation = Quaternion.Slerp(((Component)lucky).transform.rotation, Quaternion.LookRotation(val2), 0.5f); } catch { } } AimVisionConeAtTarget(lucky, val); _fireVisCd -= dt; if (_fireVisCd <= 0f) { _fireVisCd = 0.8f; _swingSeq++; FireRealShot(lucky); } } else { _fireVisCd = 0f; } if (!flag2) { SuppressVanillaFiring(lucky, val); if (_approachSet) { Vector3 val3 = val - _approachDest; if (!(((Vector3)(ref val3)).sqrMagnitude > 0.25f)) { goto IL_0408; } } _approachDest = val; _approachSet = true; try { LuckyNPC.SetMoveTarget(val); } catch { } } else { _approachSet = false; } } else if (flag3 && HasLineOfSight(lucky, val)) { Vector3 val4 = val - ((Component)lucky).transform.position; val4.y = 0f; if (((Vector3)(ref val4)).sqrMagnitude > 0.01f) { try { ((Component)lucky).transform.rotation = Quaternion.Slerp(((Component)lucky).transform.rotation, Quaternion.LookRotation(val4), 0.5f); } catch { } } _meleeVisCd -= dt; if (_meleeVisCd <= 0f) { _meleeVisCd = 0.7f; _swingSeq++; try { LuckyWeaponVisual.TriggerAttack(lucky); } catch { } try { LuckyNPC.KeepFearless(); } catch { } try { LuckyNetSync.PublishState(active: true, _method, _swingSeq, ((Component)lucky).transform.position); } catch { } } } else { _meleeVisCd = 0f; } goto IL_0408; IL_0408: _reactionCd -= dt; if (_reactionCd <= 0f) { _reactionCd = 1f; LuckyNPC.KeepFearless(); if ((Object)(object)_targetNpc != (Object)null && !IsTargetNeutralized()) { PacifyTarget(_targetNpc); try { NPCMovement movement = _targetNpc.Movement; if ((Object)(object)movement != (Object)null) { movement.PauseMovement(); } } catch { } } } _repathCd -= dt; if (_repathCd <= 0f) { _repathCd = 4f; EnsureTargetSet(lucky); } } private static bool PathIsDirect(Vector3 from, Vector3 to) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0008: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0065: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) try { NavMeshPath val = new NavMeshPath(); if (!NavMesh.CalculatePath(from, to, -1, val)) { return false; } if ((int)val.status > 0) { return false; } Vector3[] corners = val.corners; if (corners == null || corners.Length < 2) { return true; } float num = 0f; for (int i = 1; i < corners.Length; i++) { num += Vector3.Distance(corners[i - 1], corners[i]); } float num2 = Vector3.Distance(from, to); return num <= num2 * 1.35f + 2f; } catch { return true; } } private static bool GlassBetween(Vector3 fromPos, Vector3 targetPos) { //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_000d: 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_0018: 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_0023: 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) //IL_002e: 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_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_0051: 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_0058: 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_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_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_0091: 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) try { Vector3 val = fromPos + Vector3.up * 0.6f; Vector3 val2 = targetPos + Vector3.up * 0.6f; Vector3 val3 = val2 - val; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude < 1.2f) { return false; } val3 /= magnitude; val += val3 * 0.6f; float num = magnitude - 0.6f - 0.6f; if (num <= 0.1f) { return false; } RaycastHit val4 = default(RaycastHit); return Physics.Raycast(val, val3, ref val4, num, -1, (QueryTriggerInteraction)1); } catch { return false; } } private static bool HasLineOfSight(NPC a, Vector3 targetPos) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((a != null) ? ((Component)a).transform : null) == (Object)null) { return true; } return HasLineOfSightFrom(((Component)a).transform.position, targetPos); } private static bool HasLineOfSightFrom(Vector3 fromPos, Vector3 targetPos) { //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_000d: 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_0018: 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_0023: 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) //IL_002e: 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_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_0051: 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_0058: 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_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_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_0091: 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) try { Vector3 val = fromPos + Vector3.up * 1.4f; Vector3 val2 = targetPos + Vector3.up * 1.4f; Vector3 val3 = val2 - val; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude < 1.2f) { return true; } val3 /= magnitude; val += val3 * 0.6f; float num = magnitude - 0.6f - 0.6f; if (num <= 0.1f) { return true; } RaycastHit val4 = default(RaycastHit); if (Physics.Raycast(val, val3, ref val4, num, -1, (QueryTriggerInteraction)1)) { return false; } return true; } catch { return true; } } private static Vector3 FindLosGroundPlacement(Vector3 tp, Vector3 awayDir, float dist) { //IL_0016: 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_0027: 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_0030: 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_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_006f: 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) //IL_0091: 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_009b: 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_00b4: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00c9: 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_00dc: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_0110: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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_013e: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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) Vector3 val; if (!(((Vector3)(ref awayDir)).sqrMagnitude > 0.01f)) { val = Vector3.right; } else { Vector3 val2 = new Vector3(awayDir.x, 0f, awayDir.z); val = ((Vector3)(ref val2)).normalized; } Vector3 val3 = val; List list = new List { val3 }; for (int i = 0; i < 8; i++) { float num = (float)i * 45f * ((float)Math.PI / 180f); list.Add(new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num))); } bool flag = false; Vector3 result = tp + val3 * dist; NavMeshHit val5 = default(NavMeshHit); foreach (Vector3 item in list) { Vector3 current = item; Vector3 val4 = tp + ((Vector3)(ref current)).normalized * dist; if (!NavMesh.SamplePosition(new Vector3(val4.x, tp.y + 0.5f, val4.z), ref val5, 3f, -1)) { continue; } Vector3 position = ((NavMeshHit)(ref val5)).position; if (!(Mathf.Abs(position.y - tp.y) > 2.5f)) { if (!flag) { result = position; flag = true; } if (HasLineOfSightFrom(position, tp)) { return position; } } } return result; } private static bool StageTargetForExecution(out Vector3 stagedPos, out Vector3 outwardDir) { //IL_0002: 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_000d: 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_01d6: 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_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_0181: 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_00c9: 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_00bf: 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_00e9: 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) stagedPos = Vector3.zero; outwardDir = Vector3.zero; try { if ((Object)(object)_targetNpc == (Object)null || (Object)(object)((Component)_targetNpc).transform == (Object)null) { return false; } object obj = null; try { obj = _targetNpc.CurrentBuilding; } catch { } if (obj == null) { NDLog.Debug("Lucky: target '" + SafeName() + "' is in the open / a walkable shop (no building) — NOT staging, Lucky paths to it directly (#8)."); return false; } if (!DoorLocator.TryGetTargetOwnDoorOriented(_targetNpc, out var doorPos, out outwardDir) && !DoorLocator.TryGetTargetOwnDoor(_targetNpc, out doorPos)) { doorPos = ((Component)_targetNpc).transform.position; } Vector3 val = doorPos; try { NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(doorPos + Vector3.up, ref val2, 5f, -1)) { val = ((NavMeshHit)(ref val2)).position; } } catch { } try { _targetNpc.ExitBuilding(""); } catch { } try { NPCScheduleManager componentInChildren = ((Component)_targetNpc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } try { ((Behaviour)componentInChildren).enabled = false; } catch { } } } catch { } bool flag = false; try { NPCMovement movement = _targetNpc.Movement; if ((Object)(object)movement != (Object)null) { movement.Warp(val); try { movement.PauseMovement(); } catch { } flag = true; } } catch { } if (!flag) { try { ((Component)_targetNpc).transform.position = val; } catch { } } PacifyTarget(_targetNpc); stagedPos = val; NDLog.Debug($"Lucky: target '{SafeName()}' staged at its OWN door @ {val} (out of building, frozen, pacified)."); return true; } catch (Exception ex) { NDLog.DebugWarn("StageTargetForExecution: " + ex.Message); return false; } } private static void PacifyTarget(NPC npc) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)npc == (Object)null) { return; } try { NPCResponses responses = npc.Responses; NPCResponses_Civilian val = (NPCResponses_Civilian)(object)((responses is NPCResponses_Civilian) ? responses : null); if ((Object)(object)val != (Object)null) { ((NPCResponses)val).npc.NPCData.Behaviour.CanCallPolice = false; val.OverrideThreatResponses = true; val.ThreatResponseOverride = (EAttackResponse)0; } } catch { } try { npc.NPCData.Behaviour.DefaultAggression = 0f; } catch { } NPCBehaviour behaviour = npc.Behaviour; if ((Object)(object)behaviour != (Object)null) { try { CallPoliceBehaviour callPoliceBehaviour = behaviour.CallPoliceBehaviour; if ((Object)(object)callPoliceBehaviour != (Object)null && ((Behaviour)callPoliceBehaviour).Enabled) { ((Behaviour)callPoliceBehaviour).Disable_Server(); } } catch { } try { FleeBehaviour fleeBehaviour = behaviour.FleeBehaviour; if ((Object)(object)fleeBehaviour != (Object)null && ((Behaviour)fleeBehaviour).Enabled) { ((Behaviour)fleeBehaviour).Disable_Server(); } } catch { } try { CoweringBehaviour coweringBehaviour = behaviour.CoweringBehaviour; if ((Object)(object)coweringBehaviour != (Object)null && ((Behaviour)coweringBehaviour).Enabled) { ((Behaviour)coweringBehaviour).Disable_Server(); } } catch { } } bool flag = false; try { flag = npc.IsPanicked; } catch { } if (flag) { ClearPanic(npc); } } catch (Exception ex) { NDLog.DebugWarn("PacifyTarget: " + ex.Message); } } private static void ClearPanic(NPC npc) { try { if (!_removePanickedResolved) { _removePanickedResolved = true; _removePanickedMi = typeof(NPC).GetMethod("RemovePanicked", BindingFlags.Instance | BindingFlags.NonPublic); } _removePanickedMi?.Invoke(npc, null); } catch (Exception ex) { NDLog.DebugWarn("ClearPanic: " + ex.Message); } } private static void TickDespawning(NPC lucky, float dt) { //IL_006b: 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_0059: Unknown result type (might be due to invalid IL or missing references) if (_stateTimer > 25f) { FinishDespawn(); return; } if (!_haveDoor) { FinishDespawn(); return; } _repathCd -= dt; if (_repathCd <= 0f) { _repathCd = 0.4f; LuckyNPC.SetMoveTarget(_despawnDoor); } if (HorizontalDist(((Component)lucky).transform.position, _despawnDoor) <= 3f) { FinishDespawn(); } } private static CombatBehaviour GetCombat(NPC lucky) { try { return (lucky == null) ? null : lucky.Behaviour?.CombatBehaviour; } catch { return null; } } private static bool StartRealCombat(NPC lucky) { try { CombatBehaviour combat = GetCombat(lucky); if ((Object)(object)combat == (Object)null) { NDLog.Warn("LuckyCombatDriver: Lucky has no CombatBehaviour!"); return false; } if (_method == 2) { EnsureTargetVelocityTracker(lucky, combat); } try { AvatarWeapon val = LuckyWeaponVisual.LoadAvatarWeapon(_method); if ((Object)(object)val != (Object)null) { combat.SetDefaultWeapon(val); } } catch (Exception ex) { NDLog.DebugWarn("DefaultWeapon: " + ex.Message); } try { combat.GiveUpRange = 1000f; } catch { } try { combat.DefaultSearchTime = 9999f; } catch { } string text = LuckyWeaponVisual.ResolveWeaponPath(_method); if (!string.IsNullOrEmpty(text)) { try { combat.SetWeapon(text); } catch (Exception ex2) { NDLog.DebugWarn("SetWeapon: " + ex2.Message); } } NetworkObject targetNob = GetTargetNob(); if ((Object)(object)targetNob == (Object)null) { NDLog.Warn("LuckyCombatDriver: target has no S1NetworkObject."); return false; } combat.SetTargetAndEnable_Server(targetNob); NDLog.Debug("LuckyCombatDriver: SetTargetAndEnable_Server (weapon='" + text + "')."); return true; } catch (Exception ex3) { NDLog.Warn("LuckyCombatDriver.StartRealCombat: " + ex3.Message); return false; } } private static void EnsureTargetSet(NPC lucky) { try { CombatBehaviour combat = GetCombat(lucky); if ((Object)(object)combat == (Object)null) { return; } bool flag = false; try { flag = combat.Target != null; } catch { } if (!flag) { NetworkObject targetNob = GetTargetNob(); if ((Object)(object)targetNob != (Object)null) { combat.SetTargetAndEnable_Server(targetNob); _rangedKicked = false; } } } catch { } } private static void EnsureTargetVelocityTracker(NPC lucky, CombatBehaviour cb) { try { if (!((Object)(object)cb.TargetVelocityTracker != (Object)null)) { SmoothedVelocityCalculator targetVelocityTracker = ((Component)lucky).gameObject.AddComponent(); cb.TargetVelocityTracker = targetVelocityTracker; NDLog.Debug("LuckyCombatDriver: TargetVelocityTracker injected (firearm)."); } } catch (Exception ex) { NDLog.DebugWarn("TargetVelocityTracker inject: " + ex.Message); } } private static void TryKickRangedRoutine(CombatBehaviour cb) { if (_rangedKicked || (Object)(object)cb == (Object)null) { return; } try { bool flag = true; try { flag = cb.IsCurrentWeaponMelee(); } catch { } bool flag2 = false; try { flag2 = (Object)(object)cb.currentWeapon != (Object)null; } catch { } if (!flag2 || flag) { return; } try { cb.EnsureRangedWeaponRoutineIsRunning(); _rangedKicked = true; NDLog.Debug("LuckyCombatDriver: ranged weapon routine kicked (shoot-from-distance)."); } catch (Exception ex) { NDLog.DebugWarn("EnsureRangedWeaponRoutineIsRunning: " + ex.Message); } } catch (Exception ex2) { NDLog.DebugWarn("TryKickRangedRoutine: " + ex2.Message); } } private static void ApplyCloseRangeBand(CombatBehaviour cb) { if ((Object)(object)cb == (Object)null) { return; } try { AvatarWeapon currentWeapon = cb.currentWeapon; if ((Object)(object)currentWeapon == (Object)null) { return; } try { currentWeapon.MinUseRange = 0f; } catch { } try { currentWeapon.MaxUseRange = 14f; } catch { } AvatarRangedWeapon val = GameCompat.Cast((Object)(object)currentWeapon); if (!((Object)(object)val != (Object)null)) { return; } try { val.RepositionAfterHit = false; } catch { } try { val.MaxStationaryShotsBeforeReposition = 9999; } catch { } try { val.CanShootWhileMoving = false; } catch { } } catch (Exception ex) { NDLog.DebugWarn("ApplyCloseRangeBand: " + ex.Message); } } private static void AimVisionConeAtTarget(NPC lucky, Vector3 tp) { //IL_0090: 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_009b: 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_00a6: 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_00b0: 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_00c9: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)lucky == (Object)null || (Object)(object)((Component)lucky).gameObject == (Object)null) { return; } if ((Object)(object)_visionCone == (Object)null || (Object)(object)((Component)_visionCone).gameObject == (Object)null) { _visionCone = ((Component)lucky).gameObject.GetComponentInChildren(true); } if (!((Object)(object)_visionCone == (Object)null)) { Transform val = (((Object)(object)_visionCone.VisionOrigin != (Object)null) ? _visionCone.VisionOrigin : ((Component)lucky).transform); Vector3 val2 = tp + Vector3.up * 1f - val.position; if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f)) { val.rotation = Quaternion.LookRotation(val2); } } } catch { } } private static void AimVisionConeAway(NPC lucky, Vector3 tp) { //IL_0091: 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_0097: 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_00a6: 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_00b0: 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_00c9: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)lucky == (Object)null || (Object)(object)((Component)lucky).gameObject == (Object)null) { return; } if ((Object)(object)_visionCone == (Object)null || (Object)(object)((Component)_visionCone).gameObject == (Object)null) { _visionCone = ((Component)lucky).gameObject.GetComponentInChildren(true); } if (!((Object)(object)_visionCone == (Object)null)) { Transform val = (((Object)(object)_visionCone.VisionOrigin != (Object)null) ? _visionCone.VisionOrigin : ((Component)lucky).transform); Vector3 val2 = val.position - (tp + Vector3.up * 1f); if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f)) { val.rotation = Quaternion.LookRotation(val2); } } } catch { } } private static void SuppressVanillaFiring(NPC lucky, Vector3 tp) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) AimVisionConeAway(lucky, tp); try { CombatBehaviour combat = GetCombat(lucky); AvatarWeapon val = (((Object)(object)combat != (Object)null) ? combat.currentWeapon : null); if ((Object)(object)val != (Object)null) { val.MaxUseRange = 0f; } } catch { } } private static void FireRealShot(NPC lucky) { //IL_0074: 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_0089: 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_0093: 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_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_005d: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_targetNpc == (Object)null) { return; } NPCHealth health = _targetNpc.Health; if ((Object)(object)health == (Object)null) { return; } try { LuckyNPC.KeepFearless(); } catch { } try { Vector3 val; try { val = ((Component)_targetNpc).transform.position + Vector3.up * 1f; } catch { val = ((Component)lucky).transform.position + ((Component)lucky).transform.forward * 5f; } if (!_weaponRaised) { try { lucky.SendEquippableMessage_Networked((NetworkConnection)null, "Raise"); } catch { } _weaponRaised = true; } lucky.SendEquippableMessage_Networked_Vector((NetworkConnection)null, "Shoot", val); } catch (Exception ex) { NDLog.DebugWarn("FireRealShot Shoot msg: " + ex.Message); } float num = 35f; try { CombatBehaviour combat = GetCombat(lucky); AvatarRangedWeapon val2 = (((Object)(object)combat != (Object)null) ? GameCompat.Cast((Object)(object)combat.currentWeapon) : null); if ((Object)(object)val2 != (Object)null && val2.Damage > 0f) { num = val2.Damage; } } catch { } try { if (!health.npc.NPCData.Health.Invincible) { health.TakeDamage(num, true); } } catch (Exception ex2) { NDLog.DebugWarn("FireRealShot TakeDamage: " + ex2.Message); } } catch (Exception ex3) { NDLog.DebugWarn("FireRealShot: " + ex3.Message); } } private static void StopRealCombat(NPC lucky) { try { CombatBehaviour combat = GetCombat(lucky); if ((Object)(object)combat == (Object)null) { return; } try { ((Behaviour)combat).Deactivate(); } catch { } try { ((Behaviour)combat).Disable(); } catch { } } catch { } } private static NetworkObject GetTargetNob() { try { GameObject val = null; if ((Object)(object)_targetPlayer != (Object)null) { val = ((Component)_targetPlayer).gameObject; } else if ((Object)(object)_targetNpc != (Object)null) { val = ((Component)_targetNpc).gameObject; } if ((Object)(object)val == (Object)null) { return null; } return val.GetComponent(); } catch { return null; } } private static void BeginDespawn(NPC lucky) { //IL_0014: 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_003d: Unknown result type (might be due to invalid IL or missing references) _hitConfirmed = true; StopRealCombat(lucky); _haveDoor = DoorLocator.TryGetNearestDoor(((Component)lucky).transform.position, out _despawnDoor); try { LuckyNetSync.PublishState(active: false, _method, 0); } catch { } try { LuckyWeaponVisual.Clear(lucky); } catch { } ToState(State.Despawning); NDLog.Debug("Lucky: hit done — despawning to the nearest door (" + (_haveDoor ? "found" : "none") + ")."); } private static void FinishDespawn() { TeardownAndPark(); CurrentState = State.Done; NDLog.Debug("LuckyCombatDriver: Done (despawned at door)."); } private static void Failt(Fail reason) { FailReason = reason; TeardownAndPark(); CurrentState = State.Failed; NDLog.Warn($"LuckyCombatDriver: FAILED ({reason})."); } private static void TeardownAndPark() { //IL_0036: 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) try { NPC npc = LuckyNPC.GetNpc(); if ((Object)(object)npc != (Object)null) { StopRealCombat(npc); LuckyWeaponVisual.Clear(npc); } } catch { } try { LuckyNetSync.PublishState(active: false, _method, 0); } catch { } try { LuckyNPC.DisableCombatSystems(); } catch { } try { LuckyNPC.ReturnToHidden(); } catch { } } public static bool IsTargetNeutralized() { try { if ((Object)(object)_targetPlayer != (Object)null) { PlayerHealth health = _targetPlayer.Health; if ((Object)(object)health == (Object)null) { return false; } return !health.IsAlive; } if ((Object)(object)_targetNpc == (Object)null) { return true; } NPCHealth health2 = _targetNpc.Health; if ((Object)(object)health2 == (Object)null) { return false; } return health2.IsDead || health2.IsKnockedOut; } catch { return false; } } private static bool TargetAlive() { try { return TargetExists() && !IsTargetNeutralized(); } catch { return false; } } private static bool TargetExists() { try { if ((Object)(object)_targetPlayer != (Object)null) { return (Object)(object)((Component)_targetPlayer).transform != (Object)null; } return (Object)(object)_targetNpc != (Object)null && (Object)(object)((Component)_targetNpc).transform != (Object)null; } catch { return false; } } private static Vector3 TargetPos() { //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) //IL_0059: 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_003f: 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) try { Transform val = (((Object)(object)_targetPlayer != (Object)null) ? ((Component)_targetPlayer).transform : (((Object)(object)_targetNpc != (Object)null) ? ((Component)_targetNpc).transform : null)); return ((Object)(object)val != (Object)null) ? val.position : Vector3.zero; } catch { return Vector3.zero; } } private static bool IsPathComplete(Vector3 from, Vector3 to) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0008: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 try { NavMeshPath val = new NavMeshPath(); return NavMesh.CalculatePath(from, to, -1, val) && (int)val.status == 0; } catch { return false; } } private static bool TryFindReachableSpawn(Vector3 targetPos, out Vector3 spawn) { //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_0010: 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_0019: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_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_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_0060: 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_0070: 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_0038: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //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) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Invalid comparison between Unknown and I4 //IL_00d9: 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) spawn = targetPos; NavMeshHit val3 = default(NavMeshHit); for (int i = 0; i < 8; i++) { Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized; if (((Vector2)(ref val)).sqrMagnitude < 0.01f) { val = Vector2.right; } Vector3 val2 = targetPos + new Vector3(val.x, 0f, val.y) * 32f; if (NavMesh.SamplePosition(val2 + Vector3.up * 1.5f, ref val3, 12f, -1) && !(HorizontalDist(((NavMeshHit)(ref val3)).position, targetPos) < 30f)) { NavMeshPath val4 = new NavMeshPath(); if (NavMesh.CalculatePath(((NavMeshHit)(ref val3)).position, targetPos, -1, val4) && (int)val4.status == 0) { spawn = ((NavMeshHit)(ref val3)).position; return true; } } } return false; } private static void ToState(State s) { CurrentState = s; _stateTimer = 0f; _repathCd = 0f; _shootableCd = 0f; } private static float HorizontalDist(Vector3 a, Vector3 b) { //IL_0019: 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) a.y = 0f; b.y = 0f; return Vector3.Distance(a, b); } private static bool TryReResolveTarget() { try { if ((Object)(object)_targetPlayer != (Object)null) { return false; } string text = ((!string.IsNullOrEmpty(_targetName)) ? _targetName : ((PizzoJobManager.Current != null) ? PizzoJobManager.Current.LuckyTargetName : null)); if (string.IsNullOrEmpty(text)) { return false; } NPC val = LuckyTargetPicker.FindNpcByName(text); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { string text2 = text.ToLowerInvariant().Replace(' ', '_'); try { NPC nPC = NPCManager.GetNPC(text2); if ((Object)(object)nPC != (Object)null) { val = nPC; } } catch { } } if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform != (Object)null) { _targetNpc = val; if (!_resolveLogged) { _resolveLogged = true; NDLog.Debug("LuckyCombatDriver: re-resolved mark '" + text + "' after grace — proceeding to real combat."); } return true; } } catch (Exception ex) { NDLog.DebugWarn("TryReResolveTarget: " + ex.Message); } return false; } private static void OffScreenComplete(NPC lucky) { TryReResolveTarget(); NPCHealth val = SafeTargetHealth(); if ((Object)(object)val != (Object)null) { try { val.npc.NPCData.Health.Invincible = false; } catch { } try { val.Die(); } catch (Exception ex) { NDLog.DebugWarn("OffScreenComplete Die(): " + ex.Message); } NDLog.Debug("Lucky off-screen kill: mark '" + SafeName() + "' unreachable/unloaded — Health.Die() applied."); } else { NDLog.Debug("Lucky off-screen complete: mark '" + SafeName() + "' not resolvable — completing contract (off-map hit)."); } _hitConfirmed = true; FinishDespawn(); } private static NPCHealth SafeTargetHealth() { try { if ((Object)(object)_targetPlayer == (Object)null && (Object)(object)_targetNpc != (Object)null) { NPCHealth health = _targetNpc.Health; if ((Object)(object)health != (Object)null) { return health; } } } catch { } return null; } private static bool SafeIsDead(NPCHealth hp) { try { return (Object)(object)hp != (Object)null && hp.IsDead; } catch { return false; } } private static bool SafeIsKnockedOut(NPCHealth hp) { try { return (Object)(object)hp != (Object)null && hp.IsKnockedOut; } catch { return false; } } private static void DiagnoseTargetOnce() { try { NPC targetNpc = _targetNpc; bool flag = (Object)(object)targetNpc != (Object)null; bool flag2 = false; try { flag2 = flag && (Object)(object)((Component)targetNpc).transform != (Object)null; } catch { } NPCHealth val = SafeTargetHealth(); NDLog.Debug($"[DBG] TickSpawn diag: name='{_targetName}' player={(Object)(object)_targetPlayer != (Object)null} npc={flag} transform={flag2} health={(Object)(object)val != (Object)null} IsDead={SafeIsDead(val)} IsKO={SafeIsKnockedOut(val)} exists={TargetExists()}"); } catch { } } private static string SafeName() { try { if ((Object)(object)_targetPlayer != (Object)null) { return _targetPlayer.PlayerName ?? ""; } return ((Object)(object)_targetNpc != (Object)null) ? ((Object)_targetNpc).name : ""; } catch { return ""; } } } internal static class LuckyController { public const int METHOD_MELEE = 1; public const int METHOD_FIREARM = 2; private static int _rewardForJob; private static int _method; private static bool _active; private static bool _abortedByLuckyDown; public static bool DispatchAbortedByLuckyDown => _abortedByLuckyDown; public static int CurrentMethod => _method; public static bool IsDispatching => _active; public static void Dispatch(NPC npc, Player player, int method, int reward, string targetName) { if (!((Object)(object)npc == (Object)null) || !((Object)(object)player == (Object)null)) { _method = method; _rewardForJob = reward; _abortedByLuckyDown = false; _active = true; string text = ((method == 2) ? LoreStrings.LuckyDispatchedFlatlineSms(targetName) : LoreStrings.LuckyDispatchedRaidSms(targetName)); DonMessaging.SendDon(text); NDLog.Info($"Lucky dispatched (real combat): target='{targetName}' method={method} player={(Object)(object)player != (Object)null}"); if (SessionGate.IsAuthority) { LuckyCombatDriver.Begin(npc, player, method, targetName); } } } public static bool TickHit(out int reward) { reward = 0; if (!_active) { return false; } if (!SessionGate.IsAuthority) { return false; } if (LuckyCombatDriver.Succeeded) { reward = _rewardForJob; NDLog.Info($"Lucky hit verified (real combat, method={_method})."); Reset(); return true; } if (LuckyCombatDriver.HasFailed) { if (LuckyCombatDriver.FailReason == LuckyCombatDriver.Fail.LuckyDown) { NDLog.Warn("Lucky himself is down/KO during combat — aborting job."); _abortedByLuckyDown = true; } else { NDLog.Warn($"Lucky combat failed ({LuckyCombatDriver.FailReason}) — aborting job."); } Reset(); return false; } return false; } public static void Reset() { _active = false; _rewardForJob = 0; _method = 0; try { LuckyCombatDriver.Abort(); } catch { } } public static bool ConsumeLuckyDownAbort() { bool abortedByLuckyDown = _abortedByLuckyDown; _abortedByLuckyDown = false; return abortedByLuckyDown; } public static int DepositRewardInGazebo(int reward) { if (reward <= 0) { return 0; } try { if (RealEstateManager.VillaOwned && PayoutHelper.AddOnlineBalance(reward, "Famiglia reward (Contratto)")) { return reward; } List deadDrops = DeadDrop.DeadDrops; if (deadDrops != null) { for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val = deadDrops[i]; string text = null; try { text = val?.DeadDropName; } catch { } if (!string.IsNullOrEmpty(text) && text.IndexOf("Gazebo", StringComparison.OrdinalIgnoreCase) >= 0) { if (DeadDropCashHelper.SpawnCashInDrop(val, reward)) { return reward; } if (PayoutHelper.AddCash(reward, "Lucky contratto (Gazebo full)")) { NDLog.Info($"Gazebo full — ${reward} reward credited to wallet instead."); return reward; } return 0; } } } if (PayoutHelper.AddCash(reward, "Lucky contratto (no Gazebo)")) { NDLog.Info($"Gazebo not found — ${reward} reward credited to wallet instead."); return reward; } } catch (Exception ex) { NDLog.Warn("DepositRewardInGazebo: " + ex.Message); } return 0; } } public static class LuckyTargetPicker { public sealed class Choice { public NPC Npc; public Player PlayerTarget; public string DisplayName; public string Category; public EMapRegion Region; public bool IsPlayer => (Object)(object)PlayerTarget != (Object)null; public Transform TargetTransform { get { try { return IsPlayer ? ((Component)PlayerTarget).transform : (((Object)(object)Npc != (Object)null) ? ((Component)Npc).transform : null); } catch { return null; } } } } public static readonly EMapRegion[] Regions; public static readonly string[] Categories; public static readonly char[] Letters; private static readonly Dictionary _homeRegion; private static bool _snapshotTaken; private static string SafeNpcKey(NPC n) { try { string iD = n.ID; return string.IsNullOrEmpty(iD) ? null : iD; } catch { return null; } } public static void ResetForSceneReload() { _homeRegion.Clear(); _snapshotTaken = false; } public static void EnsureHomeRegionSnapshot() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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) try { List nPCRegistry = NPCManager.NPCRegistry; if (nPCRegistry == null || nPCRegistry.Count == 0) { return; } Map val = (Singleton.InstanceExists ? Singleton.Instance : null); int num = 0; for (int i = 0; i < nPCRegistry.Count; i++) { NPC val2; try { val2 = nPCRegistry[i]; } catch { continue; } if ((Object)(object)val2 == (Object)null) { continue; } string text = SafeNpcKey(val2); if (text != null && !_homeRegion.ContainsKey(text)) { EMapRegion value; try { value = ((!((Object)(object)val != (Object)null) || !((Object)(object)((Component)val2).transform != (Object)null)) ? val2.Region : val.GetRegionFromPosition(((Component)val2).transform.position)); } catch { continue; } _homeRegion[text] = value; num++; } } if (num > 0 && !_snapshotTaken) { _snapshotTaken = true; NDLog.Debug($"LuckyTargetPicker: home-region snapshot taken (total={_homeRegion.Count})."); } } catch (Exception ex) { NDLog.DebugWarn("EnsureHomeRegionSnapshot: " + ex.Message); } } public unsafe static string RegionLabel(EMapRegion r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_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_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown EMapRegion val = r; EMapRegion val2 = val; return (int)val2 switch { 3 => "Docks", 2 => "Downtown", 0 => "Northtown", 4 => "Suburbia", 5 => "Uptown", 1 => "Westville", _ => ((object)(*(EMapRegion*)(&r))/*cast due to .constrained prefix*/).ToString(), }; } public static string CategoryLabel(string cat) { return cat switch { "all" => "Everyone", "cop" => "Cops", "civilian" => "Civilians", "dealer" => "Dealers", "shopkeeper" => "Shopkeepers", "player" => "Players", _ => cat ?? "?", }; } public static List BuildPoolByLetter(char letter, string category) { //IL_036c: 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_00f4: 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) List list = new List(); char c = char.ToUpperInvariant(letter); bool flag = string.Equals(category, "all", StringComparison.Ordinal); bool flag2 = flag || string.Equals(category, "cop", StringComparison.Ordinal); Map map = (Singleton.InstanceExists ? Singleton.Instance : null); if (flag2) { try { List officers = PoliceOfficer.Officers; if (officers != null) { for (int i = 0; i < officers.Count; i++) { NPC val; try { val = GameCompat.Cast((Object)(object)officers[i]); } catch { continue; } if (!((Object)(object)val == (Object)null) && !KillDetector.IsDead(val) && FirstNameStartsWith(val, c)) { string text = SafeName(val); if (!string.IsNullOrEmpty(text)) { list.Add(new Choice { Npc = val, DisplayName = text, Category = "cop", Region = LiveRegion(val, map) }); } } } } } catch (Exception ex) { NDLog.DebugWarn("BuildPoolByLetter(cop): " + ex.Message); } } if (!string.Equals(category, "cop", StringComparison.Ordinal)) { try { List nPCRegistry = NPCManager.NPCRegistry; if (nPCRegistry != null) { for (int j = 0; j < nPCRegistry.Count; j++) { NPC val2; try { val2 = nPCRegistry[j]; } catch { continue; } if ((Object)(object)val2 == (Object)null || KillDetector.IsDead(val2) || IsOwnModNpc(val2) || !FirstNameStartsWith(val2, c)) { continue; } string text2 = ClassifyCategory(val2); if (!string.Equals(text2, "cop", StringComparison.Ordinal) && (flag || string.Equals(text2, category, StringComparison.Ordinal))) { string text3 = SafeName(val2); if (!string.IsNullOrEmpty(text3)) { list.Add(new Choice { Npc = val2, DisplayName = text3, Category = text2, Region = LiveRegion(val2, map) }); } } } } } catch (Exception ex2) { NDLog.DebugWarn("BuildPoolByLetter: " + ex2.Message); } } if (SessionGate.AllowPlayerTargets && (flag || string.Equals(category, "player", StringComparison.Ordinal))) { try { Player local = Player.Local; List playerList = Player.PlayerList; if (playerList != null) { for (int k = 0; k < playerList.Count; k++) { Player val3; try { val3 = playerList[k]; } catch { continue; } if (!((Object)(object)val3 == (Object)null) && !GameCompat.SameInstance((object)val3, (object)local)) { string text4 = SafePlayerName(val3); if (!string.IsNullOrEmpty(text4) && char.ToUpperInvariant(text4[0]) == c) { list.Add(new Choice { PlayerTarget = val3, DisplayName = text4, Category = "player", Region = (EMapRegion)0 }); } } } } } catch (Exception ex3) { NDLog.DebugWarn("BuildPoolByLetter(player): " + ex3.Message); } } NDLog.Debug($"LuckyTargetPicker: letter={c} cat={category} -> {list.Count} target(s)"); return list; } public static string SafePlayerName(Player p) { try { return (p.PlayerName ?? "").Trim(); } catch { return ""; } } private static bool FirstNameStartsWith(NPC n, char upper) { try { string firstName = n.FirstName; if (string.IsNullOrEmpty(firstName)) { return false; } return char.ToUpperInvariant(firstName[0]) == upper; } catch { return false; } } private static bool IsOwnModNpc(NPC n) { try { string iD = n.ID; return !string.IsNullOrEmpty(iD) && iD.StartsWith("Ndrangheta_", StringComparison.Ordinal); } catch { return false; } } private static EMapRegion LiveRegion(NPC n, Map map) { //IL_003e: 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_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_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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)map != (Object)null && (Object)(object)((Component)n).transform != (Object)null) { return map.GetRegionFromPosition(((Component)n).transform.position); } return n.Region; } catch { return (EMapRegion)0; } } public static List BuildPool(EMapRegion region, string category) { //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0249: 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_00c6: 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_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_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: 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_0119: 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) List list = new List(); if (string.Equals(category, "cop", StringComparison.Ordinal)) { try { List officers = PoliceOfficer.Officers; Map val = (Singleton.InstanceExists ? Singleton.Instance : null); if (officers != null) { for (int i = 0; i < officers.Count; i++) { NPC val2; try { val2 = GameCompat.Cast((Object)(object)officers[i]); } catch { continue; } if ((Object)(object)val2 == (Object)null || KillDetector.IsDead(val2)) { continue; } EMapRegion val3; try { val3 = ((!((Object)(object)val != (Object)null) || !((Object)(object)((Component)val2).transform != (Object)null)) ? val2.Region : val.GetRegionFromPosition(((Component)val2).transform.position)); } catch { continue; } if (val3 == region) { string text = SafeName(val2); if (!string.IsNullOrEmpty(text)) { list.Add(new Choice { Npc = val2, DisplayName = text, Category = "cop", Region = val3 }); } } } } } catch (Exception ex) { NDLog.DebugWarn("LuckyTargetPicker.BuildPool(cop): " + ex.Message); } NDLog.Debug($"LuckyTargetPicker: cop pool region={RegionLabel(region)} -> {list.Count} target(s)"); return list; } try { EnsureHomeRegionSnapshot(); List nPCRegistry = NPCManager.NPCRegistry; if (nPCRegistry == null) { return list; } for (int j = 0; j < nPCRegistry.Count; j++) { NPC val4; try { val4 = nPCRegistry[j]; } catch { continue; } if ((Object)(object)val4 == (Object)null || KillDetector.IsDead(val4)) { continue; } string text2 = SafeNpcKey(val4); if (text2 == null || !_homeRegion.TryGetValue(text2, out var value)) { try { value = val4.Region; } catch { continue; } if (text2 != null) { _homeRegion[text2] = value; } } if (value != region) { continue; } string text3 = ClassifyCategory(val4); if (string.Equals(text3, category, StringComparison.Ordinal)) { string text4 = SafeName(val4); if (!string.IsNullOrEmpty(text4)) { list.Add(new Choice { Npc = val4, DisplayName = text4, Category = text3, Region = value }); } } } } catch (Exception ex2) { NDLog.DebugWarn("LuckyTargetPicker.BuildPool: " + ex2.Message); } NDLog.Debug($"LuckyTargetPicker: {category} pool region={RegionLabel(region)} -> {list.Count} target(s)"); return list; } public static string ClassifyCategory(NPC n) { if ((Object)(object)n == (Object)null) { return "civilian"; } try { PoliceOfficer val = GameCompat.Cast((Object)(object)n); if ((Object)(object)val != (Object)null) { return "cop"; } } catch { } try { Dealer val2 = GameCompat.Cast((Object)(object)n); if ((Object)(object)val2 != (Object)null) { return "dealer"; } } catch { } try { string displayName = SafeName(n); if (PizzoTargets.FindByName(displayName) != null) { return "shopkeeper"; } } catch { } return "civilian"; } public static NPC FindNpcByName(string displayName) { if (string.IsNullOrEmpty(displayName)) { return null; } try { List nPCRegistry = NPCManager.NPCRegistry; if (nPCRegistry == null) { return null; } for (int i = 0; i < nPCRegistry.Count; i++) { NPC val; try { val = nPCRegistry[i]; } catch { continue; } if ((Object)(object)val == (Object)null || !string.Equals(SafeName(val), displayName, StringComparison.OrdinalIgnoreCase)) { continue; } return val; } } catch (Exception ex) { NDLog.DebugWarn("FindNpcByName: " + ex.Message); } return null; } public static string SafeName(NPC n) { try { return (n.FirstName + " " + n.LastName).Trim(); } catch { return ""; } } static LuckyTargetPicker() { EMapRegion[] array = new EMapRegion[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Regions = (EMapRegion[])(object)array; Categories = new string[5] { "all", "civilian", "cop", "dealer", "shopkeeper" }; Letters = new char[26] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; _homeRegion = new Dictionary(); } } internal static class LuckyWeaponVisual { public const int METHOD_MELEE = 1; public const int METHOD_FIREARM = 2; private static readonly string[] MeleePaths = new string[3] { "Avatar/Equippables/Machete", "Avatar/Equippables/Knife", "Avatar/Equippables/BrokenBottle" }; private static readonly string[] FirearmPaths = new string[3] { "Avatar/Equippables/PumpShotgun", "Avatar/Equippables/M1911", "Avatar/Equippables/Revolver" }; private static string _meleePath; private static string _firearmPath; private static readonly string[][] BrawlMeleeCandidates = new string[4][] { new string[2] { "Avatar/Equippables/BaseballBat", "Avatar/Equippables/Baseballbat" }, new string[2] { "Avatar/Equippables/FryingPan", "Avatar/Equippables/Fryingpan" }, new string[1] { "Avatar/Equippables/Knife" }, new string[1] { "Avatar/Equippables/Machete" } }; private static List _brawlMeleePool; public static string ResolveWeaponPath(int method) { bool flag = method == 2; string text = (flag ? _firearmPath : _meleePath); if (!string.IsNullOrEmpty(text)) { return text; } string[] array = (flag ? FirearmPaths : MeleePaths); foreach (string text2 in array) { if (ResourceExists(text2)) { if (flag) { _firearmPath = text2; } else { _meleePath = text2; } NDLog.Debug("LuckyWeaponVisual: weapon path chosen (" + (flag ? "firearm" : "melee") + "='" + text2 + "')."); return text2; } } NDLog.Warn($"LuckyWeaponVisual: no Resources weapon path found for method={method}."); return null; } public static AvatarWeapon LoadRandomBrawlMelee(Random rng) { try { if (_brawlMeleePool == null) { _brawlMeleePool = new List(); string[][] brawlMeleeCandidates = BrawlMeleeCandidates; foreach (string[] array in brawlMeleeCandidates) { string[] array2 = array; foreach (string text in array2) { if (ResourceExists(text)) { _brawlMeleePool.Add(text); break; } } } NDLog.Debug(string.Format("Brawl melee pool: {0}/4 resolvable ({1}).", _brawlMeleePool.Count, string.Join(", ", _brawlMeleePool))); } if (_brawlMeleePool.Count == 0) { return null; } string path = _brawlMeleePool[rng.Next(_brawlMeleePool.Count)]; return LoadAvatarWeaponByPath(path); } catch (Exception ex) { NDLog.DebugWarn("LoadRandomBrawlMelee: " + ex.Message); return null; } } public static AvatarWeapon LoadAvatarWeapon(int method) { try { string text = ResolveWeaponPath(method); if (string.IsNullOrEmpty(text)) { return null; } return LoadAvatarWeaponByPath(text); } catch (Exception ex) { NDLog.DebugWarn("LoadAvatarWeapon: " + ex.Message); return null; } } public static AvatarWeapon LoadAvatarWeaponByPath(string path) { try { if (string.IsNullOrEmpty(path)) { return null; } GameObject val = LoadPrefab(path); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate(val); AvatarEquippable component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return null; } AvatarWeapon val3 = GameCompat.Cast((Object)(object)component); if ((Object)(object)val3 == (Object)null) { Object.Destroy((Object)(object)val2); return null; } AvatarRangedWeapon val4 = GameCompat.Cast((Object)(object)val3); if ((Object)(object)val4 != (Object)null) { try { val4.HitChance_MinRange = 0.95f; } catch { } try { val4.HitChance_MaxRange = 0.95f; } catch { } } return val3; } catch (Exception ex) { NDLog.Warn("LuckyWeaponVisual.LoadAvatarWeapon: " + ex.Message); return null; } } public static AvatarWeapon EquipOnAvatar(NPC npc, int method) { try { if ((Object)(object)npc == (Object)null) { return null; } Avatar avatar = npc.Avatar; if ((Object)(object)avatar == (Object)null) { return null; } string text = ResolveWeaponPath(method); if (string.IsNullOrEmpty(text)) { return null; } AvatarEquippable val = avatar.SetEquippable(text); if ((Object)(object)val == (Object)null) { NDLog.DebugWarn("SetEquippable('" + text + "') returned null."); return null; } return GameCompat.Cast((Object)(object)val); } catch (Exception ex) { NDLog.DebugWarn("LuckyWeaponVisual.EquipOnAvatar: " + ex.Message); return null; } } public static void TriggerAttack(NPC npc) { try { object obj; if (npc == null) { obj = null; } else { Avatar avatar = npc.Avatar; obj = ((avatar != null) ? avatar.CurrentEquippable : null); } AvatarEquippable val = (AvatarEquippable)obj; if ((Object)(object)val == (Object)null) { return; } AvatarWeapon val2 = GameCompat.Cast((Object)(object)val); if ((Object)(object)val2 != (Object)null) { try { val2.Attack(); return; } catch { } } try { val.SetTrigger("Attack"); } catch { } } catch (Exception ex) { NDLog.DebugWarn("LuckyWeaponVisual.TriggerAttack: " + ex.Message); } } public static void Clear(NPC npc) { try { object obj; if (npc == null) { obj = null; } else { Avatar avatar = npc.Avatar; obj = ((avatar != null) ? avatar.CurrentEquippable : null); } AvatarEquippable val = (AvatarEquippable)obj; if ((Object)(object)val == (Object)null) { return; } try { val.Unequip(); } catch (Exception ex) { NDLog.DebugWarn("Unequip: " + ex.Message); } } catch (Exception ex2) { NDLog.DebugWarn("LuckyWeaponVisual.Clear: " + ex2.Message); } } public static GameObject LoadEquippablePrefab(string path) { return LoadPrefab(path); } private static GameObject LoadPrefab(string path) { try { Object val = Resources.Load(path); if (val == (Object)null) { return null; } return GameCompat.Cast(val); } catch (Exception ex) { NDLog.DebugWarn("Resources.Load('" + path + "'): " + ex.Message); return null; } } private static bool ResourceExists(string path) { try { return Resources.Load(path) != (Object)null; } catch { return false; } } } public static class MackAvatarCloner { public struct MackSnapshot { public bool Valid; public Color32 SkinColor; public Color EyeBallTint; public float PupilDilation; public float EyebrowScale; public float EyebrowThickness; public float EyebrowRestingHeight; public float EyebrowRestingAngle; public float Gender; public string[] FaceLayerPaths; public Color[] FaceLayerColors; } private static readonly string[] MackNpcIds = new string[4] { "mac", "mac_cooper", "Mac", "Mack" }; public static MackSnapshot LastSnapshot { get; private set; } public static bool HasSnapshot => LastSnapshot.Valid; public static bool TryCaptureSnapshot() { //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_0091: 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_0120: 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_0148: Unknown result type (might be due to invalid IL or missing references) if (LastSnapshot.Valid) { return true; } try { NPC val = ResolveMackNpc(); if ((Object)(object)val == (Object)null) { return false; } Avatar avatar = val.Avatar; if ((Object)(object)avatar == (Object)null) { return false; } AvatarSettings currentSettings = avatar.CurrentSettings; if ((Object)(object)currentSettings == (Object)null) { return false; } MackSnapshot lastSnapshot = new MackSnapshot { Valid = true, SkinColor = Color32.op_Implicit(currentSettings.SkinColor), EyeBallTint = currentSettings.EyeBallTint, PupilDilation = currentSettings.PupilDilation, EyebrowScale = currentSettings.EyebrowScale, EyebrowThickness = currentSettings.EyebrowThickness, EyebrowRestingHeight = currentSettings.EyebrowRestingHeight, EyebrowRestingAngle = currentSettings.EyebrowRestingAngle, Gender = currentSettings.Gender }; CaptureFaceLayers(currentSettings, out lastSnapshot.FaceLayerPaths, out lastSnapshot.FaceLayerColors); LastSnapshot = lastSnapshot; object[] obj = new object[4] { lastSnapshot.SkinColor.r, lastSnapshot.SkinColor.g, lastSnapshot.SkinColor.b, null }; string[] faceLayerPaths = lastSnapshot.FaceLayerPaths; obj[3] = ((faceLayerPaths != null) ? faceLayerPaths.Length : 0); NDLog.Debug(string.Format("Mack snapshot captured: skin=({0},{1},{2}) faceLayers={3}", obj)); return true; } catch (Exception ex) { NDLog.DebugWarn("MackAvatarCloner.TryCaptureSnapshot: " + ex.Message); return false; } } private static NPC ResolveMackNpc() { string[] mackNpcIds = MackNpcIds; foreach (string text in mackNpcIds) { try { NPC nPC = NPCManager.GetNPC(text); if ((Object)(object)nPC != (Object)null) { return nPC; } } catch { } } try { Mac val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null) { GameObject gameObject = ((Component)val).gameObject; NPC val2 = ((gameObject != null) ? gameObject.GetComponent() : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } catch { } return null; } private static void CaptureFaceLayers(AvatarSettings settings, out string[] paths, out Color[] colors) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) paths = Array.Empty(); colors = Array.Empty(); try { List faceLayerSettings = settings.FaceLayerSettings; if (faceLayerSettings == null || faceLayerSettings.Count == 0) { return; } int count = faceLayerSettings.Count; string[] array = new string[count]; Color[] array2 = (Color[])(object)new Color[count]; for (int i = 0; i < count; i++) { LayerSetting val = faceLayerSettings[i]; if (!GameCompat.IsNullBoxed(val)) { array[i] = val.layerPath ?? string.Empty; array2[i] = val.layerTint; } } paths = array; colors = array2; } catch (Exception ex) { NDLog.DebugWarn("MackCaptureFaceLayers: " + ex.Message); } } } public static class MirrorRenderer { private static readonly Color[] Palette = (Color[])(object)new Color[4] { new Color(0.15f, 0.85f, 0.25f), new Color(0.14f, 0.45f, 0.95f), new Color(0.95f, 0.12f, 0.1f), new Color(0.1f, 0.1f, 0.12f) }; private const float GLASS_ALPHA = 0.32f; private static readonly Dictionary _live = new Dictionary(); private static readonly Dictionary _liveStyle = new Dictionary(); private static readonly HashSet _seen = new HashSet(); public static void RenderVisuals(List objs) { //IL_010b: 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_0158: Unknown result type (might be due to invalid IL or missing references) try { _seen.Clear(); if (objs != null) { for (int i = 0; i < objs.Count; i++) { VisualMirror.MirrorObj o = objs[i]; if (string.IsNullOrEmpty(o.Id)) { continue; } _seen.Add(o.Id); if (!_live.TryGetValue(o.Id, out var value) || (Object)(object)value == (Object)null) { value = Spawn(o); if ((Object)(object)value == (Object)null) { continue; } _live[o.Id] = value; _liveStyle[o.Id] = o.Style; } else if (StyleOf(o.Id) != o.Style) { ApplyStyle(value, o.Kind, o.Style); _liveStyle[o.Id] = o.Style; } try { value.transform.position = o.Pos; value.transform.rotation = Quaternion.Euler(0f, (float)o.Yaw, 0f); if (((Vector3)(ref o.Scale)).sqrMagnitude > 0.0001f) { value.transform.localScale = o.Scale; } if (value.activeSelf != o.Visible) { value.SetActive(o.Visible); } } catch { } } } if (_live.Count <= 0) { return; } List list = null; foreach (KeyValuePair item in _live) { if (!_seen.Contains(item.Key)) { (list ?? (list = new List())).Add(item.Key); } } if (list == null) { return; } for (int j = 0; j < list.Count; j++) { try { if ((Object)(object)_live[list[j]] != (Object)null) { Object.Destroy((Object)(object)_live[list[j]]); } } catch { } _live.Remove(list[j]); _liveStyle.Remove(list[j]); } } catch (Exception ex) { NDLog.DebugWarn("MirrorRenderer.RenderVisuals: " + ex.Message); } } public static void RenderTeleports(List actions) { try { TeleportMirror.ClientApply(actions); } catch (Exception ex) { NDLog.DebugWarn("MirrorRenderer.RenderTeleports: " + ex.Message); } } private static byte StyleOf(string id) { byte value; return _liveStyle.TryGetValue(id, out value) ? value : byte.MaxValue; } private static GameObject Spawn(VisualMirror.MirrorObj o) { //IL_00a0: 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_0010: Unknown result type (might be due to invalid IL or missing references) try { PrimitiveType val = (PrimitiveType)((o.Kind == 2) ? 2 : 3); GameObject val2 = GameObject.CreatePrimitive(val); ((Object)val2).name = "NdrMirror_" + o.Id; try { Collider component = val2.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; Object.Destroy((Object)(object)component); } } catch { } ApplyStyle(val2, o.Kind, o.Style); NDLog.Debug($"[MIRROR] spawned '{o.Id}' kind={o.Kind} style={o.Style} @ {o.Pos}."); return val2; } catch (Exception ex) { NDLog.DebugWarn("MirrorRenderer.Spawn: " + ex.Message); return null; } } private static void ApplyStyle(GameObject go, byte kind, byte style) { //IL_0019: 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_001e: 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_0028: Unknown result type (might be due to invalid IL or missing references) try { Color val = ((style < Palette.Length) ? Palette[style] : Color.magenta); if (kind == 0) { PropVisuals.ApplyGlass(go, val, 0.32f); } else { PropVisuals.Apply(go, val); } } catch { } } public static void ResetForSceneReload() { try { foreach (KeyValuePair item in _live) { try { if ((Object)(object)item.Value != (Object)null) { Object.Destroy((Object)(object)item.Value); } } catch { } } } catch { } _live.Clear(); _liveStyle.Clear(); _seen.Clear(); } } public static class ModConfig { public const bool DepositoBuildGrid = true; public const bool LuckyVisible = true; public const int FirstJobDelaySeconds = 8; public const int EnvelopeAmount = 1000; public const int CutAmount = 300; public const string GazeboDeadDropName = "Gazebo"; public const bool VillaEvictBoog = true; public const bool GuardFallbackActors = true; private static bool _initialized; public static int JobCooldownSeconds { get; private set; } = 240; public static bool DebugLogging { get; private set; } = false; public static bool BrawlCrewInvincible { get; private set; } = false; public static bool BrawlOfficersFightBack { get; private set; } = true; public static int BrawlRadius { get; private set; } = 60; public static bool BrawlArmed { get; private set; } = false; public static float VanSfxVolume { get; private set; } = 1f; public static float WarehouseNpcSfxVolume { get; private set; } = 1f; public static void Initialize() { if (_initialized) { return; } _initialized = true; try { MelonPreferences_Category val = MelonPreferences.CreateCategory("Ndrangheta", "Ndrangheta — General"); MelonPreferences_Entry val2 = val.CreateEntry("JobCooldownSeconds", 240, "Cooldown between jobs (real-time seconds).", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Entry val3 = val.CreateEntry("DebugLogging", false, "Verbose debug logs (default off; Info/Warn/Error always emit).", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Category val4 = MelonPreferences.CreateCategory("Ndrangheta_Brawl", "Ndrangheta — Brawl"); MelonPreferences_Entry val5 = val4.CreateEntry("BrawlCrewInvincible", false, "Crew can't be knocked out (default off — a brawl can be lost).", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Entry val6 = val4.CreateEntry("BrawlOfficersFightBack", true, "Officers fight back against the crew (vanilla cops never retaliate vs NPCs without this).", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Entry val7 = val4.CreateEntry("BrawlRadius", 60, "Search/chase radius in meters (the crew won't run across town).", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Entry val8 = val4.CreateEntry("BrawlArmed", false, "Crew uses random melee weapons (baseball bat / frying pan / knife / machete) instead of fists.", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Category val9 = MelonPreferences.CreateCategory("Ndrangheta_SFX", "Ndrangheta — SFX Volume"); MelonPreferences_Entry val10 = val9.CreateEntry("VanSfxVolume", 1f, "Van SFX volume", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Entry val11 = val9.CreateEntry("WarehouseNpcSfxVolume", 1f, "Warehouse NPC SFX volume", (string)null, false, false, (ValueValidator)null, (string)null); JobCooldownSeconds = val2.Value; DebugLogging = val3.Value; BrawlCrewInvincible = val5.Value; BrawlOfficersFightBack = val6.Value; BrawlRadius = val7.Value; BrawlArmed = val8.Value; VanSfxVolume = Mathf.Clamp01(val10.Value); WarehouseNpcSfxVolume = Mathf.Clamp01(val11.Value); NDLog.Debug($"Config: cooldown={JobCooldownSeconds}s debug={DebugLogging} " + $"brawl(inv={BrawlCrewInvincible},fightback={BrawlOfficersFightBack},r={BrawlRadius},armed={BrawlArmed}) " + $"(intern: depoGrid={true} evictBoog={true} guardFallback={true})"); } catch (Exception ex) { NDLog.Warn("ModConfig init failed (using defaults): " + ex.Message); } } } public static class PizzoDropPicker { public sealed class DropChoice { public string Name; public Vector3 Position; public string DropGuid; } public const float MinDistanceToDon = 60f; public static DropChoice PickRandom(Random rng) { //IL_013d: 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_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_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_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) //IL_00a0: 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_00b0: 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) try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null || deadDrops.Count == 0) { NDLog.DebugWarn("PizzoDropPicker: DeadDrops list empty."); return null; } Vector3 val = ResolveDonPosition(); List list = new List(); for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val2; try { val2 = deadDrops[i]; } catch { continue; } if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).transform == (Object)null) { continue; } Vector3 position = ((Component)val2).transform.position; if (val != Vector3.zero) { float num = position.x - val.x; float num2 = position.z - val.z; if (num * num + num2 * num2 < 3600f) { continue; } } string text; try { text = val2.DeadDropName; } catch { text = null; } if (string.IsNullOrEmpty(text)) { text = "an unknown stash"; } string dropGuid; try { dropGuid = val2.GUID.ToString(); } catch { dropGuid = string.Empty; } list.Add(new DropChoice { Name = text, Position = position, DropGuid = dropGuid }); } if (list.Count == 0) { NDLog.DebugWarn("PizzoDropPicker: no candidates passed distance filter."); return null; } if (rng == null) { rng = new Random(); } DropChoice dropChoice = list[rng.Next(list.Count)]; NDLog.Debug($"Pizzo pickup drop chosen: '{dropChoice.Name}' at ({dropChoice.Position.x:F1},{dropChoice.Position.y:F1},{dropChoice.Position.z:F1})"); return dropChoice; } catch (Exception ex) { NDLog.Warn("PizzoDropPicker.PickRandom: " + ex.Message); return null; } } public static bool PickTwoDistinct(Random rng, out DropChoice a, out DropChoice b) { a = null; b = null; DropChoice dropChoice = PickRandom(rng); if (dropChoice == null) { return false; } for (int i = 0; i < 8; i++) { DropChoice dropChoice2 = PickRandom(rng); if (dropChoice2 != null && !string.Equals(dropChoice2.DropGuid, dropChoice.DropGuid, StringComparison.Ordinal)) { float num = dropChoice2.Position.x - dropChoice.Position.x; float num2 = dropChoice2.Position.z - dropChoice.Position.z; if (!(num * num + num2 * num2 < 1600f)) { a = dropChoice; b = dropChoice2; return true; } } } return false; } public static bool TryResolveByGuid(string guid, out DropChoice drop) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) drop = null; if (string.IsNullOrEmpty(guid)) { return false; } try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null) { return false; } for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val; try { val = deadDrops[i]; } catch { continue; } if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } string text; try { text = val.GUID.ToString(); } catch { continue; } if (!string.Equals(text, guid, StringComparison.Ordinal)) { continue; } string text2; try { text2 = val.DeadDropName; } catch { text2 = "stash"; } drop = new DropChoice { Name = (text2 ?? "stash"), Position = ((Component)val).transform.position, DropGuid = text }; return true; } } catch { } return false; } private static Vector3 ResolveDonPosition() { //IL_003a: 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_0042: 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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) try { NPC cachedGameNpc = DonSalvatoreNPC.CachedGameNpc; if ((Object)(object)cachedGameNpc != (Object)null && (Object)(object)((Component)cachedGameNpc).transform != (Object)null) { return ((Component)cachedGameNpc).transform.position; } } catch { } return Vector3.zero; } } public static class PizzoTargets { public sealed class Target { public string DisplayName; public string NpcId; public string ShopHint; } private static readonly Target[] Pool = new Target[9] { new Target { DisplayName = "Mick Lubbin", NpcId = "mick_lubbin", ShopHint = "from the pawn shop" }, new Target { DisplayName = "Sam Thompson", NpcId = "sam_thompson", ShopHint = "from Thompson Construction" }, new Target { DisplayName = "Donna Martin", NpcId = "donna_martin", ShopHint = "from the motel office" }, new Target { DisplayName = "Mrs. Ming", NpcId = "ming", ShopHint = "from the Chinese restaurant" }, new Target { DisplayName = "Jerry Montero", NpcId = "jerry_montero", ShopHint = "from Jerry's tent" }, new Target { DisplayName = "Charles Rowland", NpcId = "charles_rowland", ShopHint = "from Western Gas Mart" }, new Target { DisplayName = "Anna Chesterfield", NpcId = "anna_chesterfield", ShopHint = "from the barbershop" }, new Target { DisplayName = "Alison Knight", NpcId = "alison_knight", ShopHint = "from Bleuball's Boutique" }, new Target { DisplayName = "Ray Hoffman", NpcId = "ray_hoffman", ShopHint = "from the real estate office" } }; public static Target PickRandom(Random rng) { if (rng == null) { rng = new Random(); } return Pool[rng.Next(Pool.Length)]; } public static IEnumerable AllTargets() { return Pool; } public static Target FindByName(string displayName) { if (string.IsNullOrEmpty(displayName)) { return null; } for (int i = 0; i < Pool.Length; i++) { if (string.Equals(Pool[i].DisplayName, displayName, StringComparison.OrdinalIgnoreCase)) { return Pool[i]; } } return null; } } public static class PoiIconHelper { public static void ApplyAsync(QuestEntry entry, Sprite icon, Sprite compassIcon = null) { if (entry == null || (Object)(object)icon == (Object)null) { return; } try { MelonCoroutines.Start(WaitAndApply(entry, icon)); } catch { } try { MelonCoroutines.Start(WaitAndApplyCompass(entry, ((Object)(object)compassIcon != (Object)null) ? compassIcon : icon)); } catch { } } public static void MovePoi(QuestEntry entry, Vector3 pos) { //IL_0011: 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) if (entry == null) { return; } try { entry.POIPosition = pos; QuestEntry val = ResolveInner(entry); if ((Object)(object)val == (Object)null) { return; } try { if (!val.AutoUpdatePoILocation) { val.AutoUpdatePoILocation = true; } } catch { } try { POI poI = val.PoI; if ((Object)(object)poI != (Object)null) { ((Component)poI).transform.position = pos; poI.UpdatePosition(); } } catch { } } catch (Exception ex) { NDLog.DebugWarn("PoiIconHelper.MovePoi: " + ex.Message); } } public static void SetPoiVisible(QuestEntry entry, bool visible) { if (entry == null) { return; } try { QuestEntry val = ResolveInner(entry); if ((Object)(object)val == (Object)null) { return; } try { POI poI = val.PoI; if ((Object)(object)poI != (Object)null && (Object)(object)((Component)poI).gameObject != (Object)null && ((Component)poI).gameObject.activeSelf != visible) { ((Component)poI).gameObject.SetActive(visible); } } catch { } try { Element compassElement = val.compassElement; RectTransform val2 = ((compassElement != null) ? compassElement.Rect : null); if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && ((Component)val2).gameObject.activeSelf != visible) { ((Component)val2).gameObject.SetActive(visible); } } catch { } } catch (Exception ex) { NDLog.DebugWarn("PoiIconHelper.SetPoiVisible: " + ex.Message); } } public static void ForceMapVisible(QuestEntry entry) { if (entry == null) { return; } try { QuestEntry val = ResolveInner(entry); if ((Object)(object)val == (Object)null) { return; } try { POI poI = val.PoI; if ((Object)(object)poI != (Object)null && (Object)(object)((Component)poI).gameObject != (Object)null && !((Component)poI).gameObject.activeSelf) { ((Component)poI).gameObject.SetActive(true); } } catch { } try { Element compassElement = val.compassElement; if (compassElement != null) { compassElement.Visible = true; } } catch { } } catch (Exception ex) { NDLog.DebugWarn("PoiIconHelper.ForceMapVisible: " + ex.Message); } } private static IEnumerator WaitAndApply(QuestEntry entry, Sprite icon) { float elapsed = 0f; while (elapsed < 6f) { if (TryApply(entry, icon)) { NDLog.Debug("PoiIconHelper PoI applied to '" + SafeTitle(entry) + "'."); yield break; } elapsed += Time.deltaTime; yield return null; } if (TryApplyViaPoiContainer(entry, icon)) { NDLog.Debug("PoiIconHelper PoI applied via IconContainer to '" + SafeTitle(entry) + "'."); } else { NDLog.DebugWarn("PoiIconHelper PoI: timed out for '" + SafeTitle(entry) + "'."); } } private static IEnumerator WaitAndApplyCompass(QuestEntry entry, Sprite icon) { float elapsed = 0f; bool appliedOnce = false; while (elapsed < 12f) { if (TryApplyCompass(entry, icon)) { if (!appliedOnce) { NDLog.Debug("PoiIconHelper Compass applied to '" + SafeTitle(entry) + "'."); } yield break; } elapsed += Time.deltaTime; yield return null; } if (!appliedOnce) { NDLog.DebugWarn("PoiIconHelper Compass: timed out for '" + SafeTitle(entry) + "'."); } } private static bool TryApplyCompass(QuestEntry entry, Sprite icon) { try { QuestEntry val = ResolveInner(entry); if ((Object)(object)val == (Object)null) { return false; } Element compassElement = val.compassElement; if (compassElement == null) { return false; } RectTransform rect = compassElement.Rect; if ((Object)(object)rect == (Object)null) { return false; } Image[] componentsInChildren = ((Component)rect).GetComponentsInChildren(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return false; } bool result = false; Image[] array = componentsInChildren; foreach (Image val2 in array) { if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)val2.sprite == (Object)(object)icon) { result = true; continue; } val2.sprite = icon; result = true; } } return result; } catch (Exception ex) { NDLog.DebugWarn("PoiIconHelper.TryApplyCompass: " + ex.Message); return false; } } private static bool TryApply(QuestEntry entry, Sprite icon) { try { QuestEntry val = ResolveInner(entry); if ((Object)(object)val == (Object)null) { return false; } RectTransform poIIcon = val.PoIIcon; if ((Object)(object)poIIcon == (Object)null) { return false; } Image component = ((Component)poIIcon).GetComponent(); if ((Object)(object)component != (Object)null) { component.sprite = icon; } Image[] componentsInChildren = ((Component)poIIcon).GetComponentsInChildren(true); Image[] array = componentsInChildren; foreach (Image val2 in array) { if (!((Object)(object)val2 == (Object)null)) { val2.sprite = icon; } } return true; } catch (Exception ex) { NDLog.DebugWarn("PoiIconHelper.TryApply: " + ex.Message); return false; } } private static bool TryApplyViaPoiContainer(QuestEntry entry, Sprite icon) { try { QuestEntry val = ResolveInner(entry); if ((Object)(object)val == (Object)null) { return false; } POI poI = val.PoI; if ((Object)(object)poI == (Object)null) { return false; } RectTransform iconContainer = poI.IconContainer; if ((Object)(object)iconContainer == (Object)null) { return false; } Image[] componentsInChildren = ((Component)iconContainer).GetComponentsInChildren(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return false; } bool result = false; Image[] array = componentsInChildren; foreach (Image val2 in array) { if (!((Object)(object)val2 == (Object)null)) { val2.sprite = icon; result = true; } } return result; } catch (Exception ex) { NDLog.DebugWarn("PoiIconHelper.TryApplyViaPoiContainer: " + ex.Message); return false; } } private static QuestEntry ResolveInner(QuestEntry entry) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Type type = ((object)entry).GetType(); string[] array = new string[5] { "S1QuestEntry", "_questEntry", "questEntry", "Inner", "_inner" }; string[] array2 = array; foreach (string name in array2) { try { PropertyInfo property = type.GetProperty(name, bindingAttr); if (property != null) { object? value = property.GetValue(entry); QuestEntry val = (QuestEntry)((value is QuestEntry) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } FieldInfo field = type.GetField(name, bindingAttr); if (field != null) { object? value2 = field.GetValue(entry); QuestEntry val2 = (QuestEntry)((value2 is QuestEntry) ? value2 : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } catch { } } try { PropertyInfo[] properties = type.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.PropertyType != typeof(QuestEntry))) { object? value3 = propertyInfo.GetValue(entry); QuestEntry val3 = (QuestEntry)((value3 is QuestEntry) ? value3 : null); if ((Object)(object)val3 != (Object)null) { return val3; } } } FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(QuestEntry))) { object? value4 = fieldInfo.GetValue(entry); QuestEntry val4 = (QuestEntry)((value4 is QuestEntry) ? value4 : null); if ((Object)(object)val4 != (Object)null) { return val4; } } } } catch { } return null; } private static string SafeTitle(QuestEntry e) { try { return e.Title ?? "(noTitle)"; } catch { return "(error)"; } } } public static class PoliceHeat { public static void ClearLocal() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 try { Player local = Player.Local; PlayerCrimeData val = (((Object)(object)local != (Object)null) ? local.CrimeData : null); if ((Object)(object)val == (Object)null || (int)val.CurrentPursuitLevel <= 0) { return; } try { val.SetPursuitLevel((EPursuitLevel)0); } catch { } try { val.ClearCrimes(); } catch { } } catch (Exception ex) { NDLog.DebugWarn("[HEAT] ClearLocal: " + ex.Message); } } } public static class PoliceTargets { public static NPC PickRandomLiving(Random rng) { try { List officers = PoliceOfficer.Officers; if (officers == null || officers.Count == 0) { return null; } List list = new List(); for (int i = 0; i < officers.Count; i++) { PoliceOfficer val; try { val = officers[i]; } catch { continue; } if (!((Object)(object)val == (Object)null)) { NPC val2; try { val2 = GameCompat.Cast((Object)(object)val); } catch { val2 = null; } if (!((Object)(object)val2 == (Object)null) && !KillDetector.IsDead(val2)) { list.Add(val2); } } } if (list.Count == 0) { return null; } if (rng == null) { rng = new Random(); } return list[rng.Next(list.Count)]; } catch (Exception ex) { NDLog.DebugWarn("PoliceTargets.PickRandomLiving: " + ex.Message); return null; } } } public static class ProductRegistry { public const string ProductId = "granddaddypurple"; public const string DisplayName = "Calabrian Cream"; public const int BasePrice = 44; public const int CalabrianQuality = 4; private static ProductDefinition _resolved; private static bool _ready; public static ProductDefinition CalabrianCream => _resolved; public static bool IsRegistered => _ready; public static bool TryRegister() { if (_ready) { return true; } try { ItemDefinition item = Registry.GetItem("granddaddypurple"); if ((Object)(object)item == (Object)null) { return false; } ProductDefinition val = GameCompat.Cast((Object)(object)item); if ((Object)(object)val == (Object)null) { return false; } _resolved = val; _ready = true; NDLog.Debug("Calabrian Cream (vanilla reskin 'granddaddypurple') resolved."); return true; } catch (Exception ex) { NDLog.DebugWarn("ProductRegistry.TryRegister: " + ex.Message); return false; } } public static bool SpawnInStash(int count) { if (count <= 0 || !_ready || (Object)(object)_resolved == (Object)null) { return false; } try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null) { return false; } string value = "Gazebo"; DeadDrop val = null; for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val2; try { val2 = deadDrops[i]; } catch { continue; } if (!((Object)(object)val2 == (Object)null)) { string text; try { text = val2.DeadDropName; } catch { text = null; } if (!string.IsNullOrEmpty(text) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { val = val2; break; } } } if ((Object)(object)val == (Object)null) { return false; } int num = RewardSpawner.SpawnItemInDrop(val, "granddaddypurple", count, (EQuality)4); NDLog.Info(string.Format("Spawned {0}/{1} Calabrian Cream bricks ({2}, quality={3}) into Gazebo stash.", num, count, "granddaddypurple", 4)); return num > 0; } catch (Exception ex) { NDLog.Warn("SpawnInStash: " + ex.Message); return false; } } } public static class QuestIconHelper { public static void ApplyAsync(Quest q, Sprite sidebarSprite) { if (q == null || (Object)(object)sidebarSprite == (Object)null) { return; } try { MelonCoroutines.Start(WaitAndApply(q, sidebarSprite)); } catch { } } private static IEnumerator WaitAndApply(Quest q, Sprite sidebarSprite) { float elapsed = 0f; while (elapsed < 6f) { if (TrySwap(q, sidebarSprite)) { NDLog.Debug("QuestIconHelper: sidebar sprite swapped for '" + ((object)q).GetType().Name + "'."); yield break; } elapsed += Time.deltaTime; yield return null; } NDLog.DebugWarn("QuestIconHelper: sidebar swap timed out for '" + ((object)q).GetType().Name + "'."); } private static bool TrySwap(Quest q, Sprite sidebarSprite) { try { Quest val = ResolveS1Quest(q); if ((Object)(object)val == (Object)null) { return false; } RectTransform val2 = null; try { val2 = val.IconPrefab; } catch { return false; } if ((Object)(object)val2 == (Object)null) { return false; } bool result = false; try { Image component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null) { component.sprite = sidebarSprite; result = true; } } catch { } try { Image[] componentsInChildren = ((Component)val2).GetComponentsInChildren(true); if (componentsInChildren != null) { Image[] array = componentsInChildren; foreach (Image val3 in array) { if (!((Object)(object)val3 == (Object)null)) { try { val3.sprite = sidebarSprite; result = true; } catch { } } } } } catch { } return result; } catch (Exception ex) { NDLog.DebugWarn("QuestIconHelper.TrySwap: " + ex.Message); return false; } } public static void SwapSidebarSprite(Quest q, Sprite sidebarSprite) { if (q != null && !((Object)(object)sidebarSprite == (Object)null)) { TrySwap(q, sidebarSprite); } } private static Quest ResolveS1Quest(Quest q) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Type type = ((object)q).GetType(); while (type != null && type != typeof(object)) { try { FieldInfo field = type.GetField("S1Quest", bindingAttr); if (field != null) { object? value = field.GetValue(q); Quest val = (Quest)((value is Quest) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } PropertyInfo property = type.GetProperty("S1Quest", bindingAttr); if (property != null) { object? value2 = property.GetValue(q); Quest val2 = (Quest)((value2 is Quest) ? value2 : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } catch { } type = type.BaseType; } try { type = ((object)q).GetType(); while (type != null && type != typeof(object)) { PropertyInfo[] properties = type.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.PropertyType != typeof(Quest))) { object? value3 = propertyInfo.GetValue(q); Quest val3 = (Quest)((value3 is Quest) ? value3 : null); if ((Object)(object)val3 != (Object)null) { return val3; } } } FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(Quest))) { object? value4 = fieldInfo.GetValue(q); Quest val4 = (Quest)((value4 is Quest) ? value4 : null); if ((Object)(object)val4 != (Object)null) { return val4; } } } type = type.BaseType; } } catch { } return null; } } public enum Rank { Picciotto, Soldato, Capodecina, Sottocapo } public sealed class RankInfo { public Rank Rank; public int CompletedThreshold; public int EnvelopeAmount; public int CutAmount; public string DisplayName; public string ItalianGreeting; public int TrasportoEnvelope; public int TrasportoCut; public int TrasportoReward; } public static class RankTable { public static readonly RankInfo[] All = new RankInfo[4] { new RankInfo { Rank = Rank.Picciotto, CompletedThreshold = 0, EnvelopeAmount = 1000, CutAmount = 300, DisplayName = "Picciotto", ItalianGreeting = "Ehi, picciotto", TrasportoEnvelope = 0, TrasportoCut = 0, TrasportoReward = 0 }, new RankInfo { Rank = Rank.Soldato, CompletedThreshold = 2, EnvelopeAmount = 1800, CutAmount = 500, DisplayName = "Soldato", ItalianGreeting = "Soldato", TrasportoEnvelope = 2500, TrasportoCut = 700, TrasportoReward = 1500 }, new RankInfo { Rank = Rank.Capodecina, CompletedThreshold = 4, EnvelopeAmount = 3000, CutAmount = 700, DisplayName = "Capodecina", ItalianGreeting = "Capodecina", TrasportoEnvelope = 4000, TrasportoCut = 1000, TrasportoReward = 2500 }, new RankInfo { Rank = Rank.Sottocapo, CompletedThreshold = 6, EnvelopeAmount = 5000, CutAmount = 1000, DisplayName = "Sottocapo", ItalianGreeting = "Sottocapo", TrasportoEnvelope = 5000, TrasportoCut = 1000, TrasportoReward = 4000 } }; public static RankInfo For(Rank rank) { int num = (int)rank; if (num < 0) { num = 0; } if (num >= All.Length) { num = All.Length - 1; } return All[num]; } public static Rank DeriveFromCompleted(int completed) { Rank result = Rank.Picciotto; for (int i = 0; i < All.Length; i++) { if (completed >= All[i].CompletedThreshold) { result = All[i].Rank; } } return result; } } public static class RankManager { public static Rank CurrentRank { get; private set; } public static RankInfo CurrentInfo => RankTable.For(CurrentRank); public static int CurrentEnvelopeAmount => CurrentInfo.EnvelopeAmount; public static int CurrentCutAmount => CurrentInfo.CutAmount; public static string CurrentDisplayName => CurrentInfo.DisplayName; public static string CurrentGreeting => TerritoryHandover.HandoverActive ? "Boss" : CurrentInfo.ItalianGreeting; public static void ResetForSceneReload() { CurrentRank = Rank.Picciotto; } public static void LoadRank(Rank rank) { CurrentRank = rank; } public static void ReconcileFromCompleted(int completedCount) { Rank rank = RankTable.DeriveFromCompleted(completedCount); if (rank > CurrentRank) { NDLog.Debug($"Rank reconciled from save: {CurrentRank} -> {rank} (completed={completedCount})"); CurrentRank = rank; } } public static void CheckPromotion(int completedCount) { Rank rank = RankTable.DeriveFromCompleted(completedCount); if (rank > CurrentRank) { Rank currentRank = CurrentRank; CurrentRank = rank; NDLog.Info($"PROMOTION: {currentRank} -> {CurrentRank} (completed={completedCount})"); string text = BuildPromotionMessage(currentRank, CurrentRank, RankTable.For(CurrentRank)); DonMessaging.SendDon(text); if (CurrentRank == Rank.Capodecina && ProductRegistry.IsRegistered && ProductRegistry.SpawnInStash(3)) { DonMessaging.SendDon("Three bricks of Calabrian Cream in the stash — our private strain, grown in Aspromonte soil since my grandfather's day. Only made men ever touch it. You wear it now. Sell what you can't smoke, but the strain stays family. Always."); } } } private static string BuildPromotionMessage(Rank prev, Rank now, RankInfo info) { return now switch { Rank.Soldato => "Better. You moved enough volume that the famiglia's noticed. You're soldato now — still on probation, but I see the steel. " + $"Trials get heavier: ${info.EnvelopeAmount} envelopes, " + $"${info.CutAmount} cut. Don't get cute. Stay sharp.", Rank.Capodecina => "Capodecina. The famiglia sees the work — you run a decina now. Bigger trials, bigger envelopes: " + $"${info.EnvelopeAmount} envelopes, ${info.CutAmount} cut. " + "Keep your head down, the real test still waits.", Rank.Sottocapo => info.DisplayName + ". Underboss now — the 'Ndrina trusts you with more than knives. Tribute starts flowing daily to your " + $"stash. ${info.EnvelopeAmount} envelopes, ${info.CutAmount} for me. " + "Soon I'll have something bigger — something only blood-bound men get asked to do.", _ => "Promoted to " + info.DisplayName + ".", }; } } internal static class RapimentoLure { private const float SPEED_MULT = 1.8f; private const float REPATH = 0.5f; private static NPC _npc; private static float _savedSpeed = 1f; private static float _savedScale = 1f; private static float _repathCd; private static float _diagCd; internal static NPC ActiveTarget => _npc; internal static void Begin(NPC npc) { Stop(); _npc = npc; if ((Object)(object)npc == (Object)null) { return; } try { if ((Object)(object)npc.Movement != (Object)null) { try { _savedSpeed = npc.Movement.MoveSpeedMultiplier; } catch { _savedSpeed = 1f; } try { _savedScale = npc.Movement.MoveSpeedMultiplier; } catch { _savedScale = 1f; } if (_savedSpeed <= 0f) { _savedSpeed = 1f; } if (_savedScale <= 0f) { _savedScale = 1f; } try { ((Behaviour)npc.Movement).enabled = true; } catch { } try { npc.Movement.SetAgentEnabled(true); } catch { } try { npc.Movement.ResumeMovement(); } catch { } try { npc.Movement.MoveSpeedMultiplier = _savedSpeed * 1.8f; } catch { } try { npc.Movement.MoveSpeedMultiplier = _savedScale * 1.8f; } catch { } } DisableSchedule(npc); try { if ((Object)(object)npc.Behaviour != (Object)null) { ((Behaviour)npc.Behaviour).enabled = false; } } catch { } DisableFleeCower(npc); Pacify(npc); } catch (Exception ex) { NDLog.DebugWarn("RapimentoLure.Begin: " + ex.Message); } _repathCd = 0f; _diagCd = 0f; } internal static void Tick(float dt, Vector3 anchor) { //IL_00e0: 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_0189: 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) //IL_0097: 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_009a: 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_00b5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_npc == (Object)null) { return; } try { NPCHealth health = _npc.Health; if ((Object)(object)health != (Object)null && (health.IsDead || health.IsKnockedOut)) { _npc = null; return; } } catch { _npc = null; return; } _repathCd -= dt; if (_repathCd > 0f) { return; } _repathCd = 0.5f; Pacify(_npc); Vector3 val = anchor; try { NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(anchor, ref val2, 5f, -1)) { val = ((NavMeshHit)(ref val2)).position; } } catch { } try { if ((Object)(object)_npc.Movement != (Object)null) { _npc.Movement.SetDestination(val); } } catch { } _diagCd -= 0.5f; if (!(_diagCd <= 0f)) { return; } _diagCd = 2f; try { NavMeshAgent component = ((Component)_npc).gameObject.GetComponent(); float num = Vector3.Distance(((Component)_npc).transform.position, val); object obj4; if (!((Object)(object)component != (Object)null)) { obj4 = "no-agent"; } else { object[] obj5 = new object[5] { component.isOnNavMesh, component.hasPath, null, null, null }; Vector3 velocity = component.velocity; obj5[2] = ((Vector3)(ref velocity)).magnitude; obj5[3] = ((Behaviour)component).enabled; obj5[4] = component.isStopped; obj4 = string.Format("onMesh={0} hasPath={1} vel={2:0.0} en={3} stop={4}", obj5); } string arg = (string)obj4; NDLog.Debug($"[RAPIMENTO][lure] dist={num:0.0}m {arg}"); } catch { } } internal static void Stop() { NPC npc = _npc; _npc = null; if ((Object)(object)npc == (Object)null) { return; } try { if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.MoveSpeedMultiplier = _savedSpeed; } catch { } try { npc.Movement.MoveSpeedMultiplier = _savedScale; } catch { } try { npc.Movement.Stop(); return; } catch { return; } } } catch { } } internal static void RestoreNpc(NPC npc) { if ((Object)(object)npc == (Object)null) { return; } try { if ((Object)(object)npc.Movement != (Object)null) { try { ((Behaviour)npc.Movement).enabled = true; } catch { } try { npc.Movement.SetAgentEnabled(true); } catch { } try { npc.Movement.ResumeMovement(); } catch { } try { npc.Movement.MoveSpeedMultiplier = 1f; } catch { } try { npc.Movement.MoveSpeedMultiplier = 1f; } catch { } } try { if ((Object)(object)npc.Behaviour != (Object)null) { ((Behaviour)npc.Behaviour).enabled = true; } } catch { } EnableSchedule(npc); try { NPCResponses responses = npc.Responses; NPCResponses_Civilian val = (NPCResponses_Civilian)(object)((responses is NPCResponses_Civilian) ? responses : null); if ((Object)(object)val != (Object)null) { ((NPCResponses)val).npc.NPCData.Behaviour.CanCallPolice = true; val.OverrideThreatResponses = false; } } catch { } } catch (Exception ex) { NDLog.DebugWarn("RapimentoLure.RestoreNpc: " + ex.Message); } } internal static void Pacify(NPC npc) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)npc == (Object)null) { return; } try { NPCResponses responses = npc.Responses; NPCResponses_Civilian val = (NPCResponses_Civilian)(object)((responses is NPCResponses_Civilian) ? responses : null); if ((Object)(object)val != (Object)null) { ((NPCResponses)val).npc.NPCData.Behaviour.CanCallPolice = false; val.OverrideThreatResponses = true; val.ThreatResponseOverride = (EAttackResponse)0; } try { npc.NPCData.Behaviour.DefaultAggression = 0f; } catch { } NPCBehaviour behaviour = npc.Behaviour; if (!((Object)(object)behaviour != (Object)null)) { return; } try { CallPoliceBehaviour callPoliceBehaviour = behaviour.CallPoliceBehaviour; if ((Object)(object)callPoliceBehaviour != (Object)null && ((Behaviour)callPoliceBehaviour).Enabled) { ((Behaviour)callPoliceBehaviour).Disable_Server(); } } catch { } try { FleeBehaviour fleeBehaviour = behaviour.FleeBehaviour; if ((Object)(object)fleeBehaviour != (Object)null && ((Behaviour)fleeBehaviour).Enabled) { ((Behaviour)fleeBehaviour).Disable_Server(); } } catch { } try { CoweringBehaviour coweringBehaviour = behaviour.CoweringBehaviour; if ((Object)(object)coweringBehaviour != (Object)null && ((Behaviour)coweringBehaviour).Enabled) { ((Behaviour)coweringBehaviour).Disable_Server(); } } catch { } } catch (Exception ex) { NDLog.DebugWarn("RapimentoLure.Pacify: " + ex.Message); } } private static void DisableSchedule(NPC npc) { try { NPCScheduleManager componentInChildren = ((Component)npc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } } private static void EnableSchedule(NPC npc) { try { NPCScheduleManager componentInChildren = ((Component)npc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = true; } } catch { } } private static void DisableFleeCower(NPC npc) { try { NPCBehaviour behaviour = npc.Behaviour; if (!((Object)(object)behaviour == (Object)null)) { TryKill((Behaviour)(object)behaviour.FleeBehaviour); TryKill((Behaviour)(object)behaviour.CoweringBehaviour); } } catch { } } private static void TryKill(Behaviour b) { if ((Object)(object)b == (Object)null) { return; } try { b.Disable(); } catch { } try { ((Behaviour)b).enabled = false; } catch { } } } internal static class RapimentoManager { internal enum Variant { Rapimento, Tortura, Esecuzione, Autobomba } private enum State { Idle, VanReady, Recruiting, Luring, AwaitDrop } private const string VAN_CODE = "Veeper"; private const string VAN_CODE_FALLBACK = "hotbox"; private const float TRUNK_OFFSET = 2.6f; private const float TRUNK_MARGIN = 0.6f; private const float DROP_REACH = 4.5f; private const float REPATH_BACKUP = 0.6f; private const int REWARD = 12000; private static readonly Vector3 WAREHOUSE_DROP = new Vector3(-19.75f, -4.95f, 173.8f); private static readonly Color TRUNK_COLOR = new Color(0.15f, 0.85f, 0.25f); private static readonly Color DROP_COLOR = new Color(0.14f, 0.45f, 0.95f); private static State _state = State.Idle; private static Variant _variant = Variant.Rapimento; private static string _opLabel = "Kidnapping"; private static LandVehicle _van; private static string _vanGuid; private static LandVehicle _vanVanilla; private static Vector3 _parkPos; private static float _parkYaw; private static NPC _target; private static bool _targetFemale; private static string _targetName; private static bool _targetHidden; private static bool _rollPlayed; private static float _rollDriveTimer; private static bool _carrying; private static Transform _carryBody; private static Player _anchor; private static string _anchorWho; private static bool _clientRecruitOn; private static bool _clientDropPrevActive; private static bool _clientDropDiagOn; private static string _clientColoredVan; private static GameObject _trunkBox; private static GameObject _dropZone; private static Vector3 _dropPos; private static float _stateTimer; private static bool _payPending; private static bool _sackInserted; private static float _sackCheckCd; private static float _markerUpdateCd; private static readonly Random _rng = new Random(); private const float MARKER_UPDATE_INTERVAL = 0.5f; private const float RELEASE_DELAY = 60f; private const float RELEASE_DAMAGE = 25f; private static string _pendingOrphanVanGuid; private static float _clientKoScanNext; private static string _clientKoSentFor; private static float _heatScanCd; private const float ESCORT_ESCALATE_SECONDS = 7f; private static int _clientReleaseSeq; private static int _clientReleaseTries; private const int RELEASE_FIND_MAX_TRIES = 90; private static readonly (string Name, Vector3 Pos)[] PICKUP_LOTS = new(string, Vector3)[7] { ("Fast food parking (Northtown)", new Vector3(-41.7f, 0.1f, 60.8f)), ("West parking (Westville)", new Vector3(-131.4f, -4f, 51.9f)), ("Dealership parking (Downtown)", new Vector3(36.9f, 0f, -10f)), ("Medical center parking (Uptown)", new Vector3(119.7f, 0.1f, 56.6f)), ("Corporate plaza parking (Uptown)", new Vector3(36.5f, 0.1f, 74f)), ("Pizzeria parking (Northtown)", new Vector3(-28.9f, -4f, 133.8f)), ("Parking lot (Westville)", new Vector3(-159.6f, -4f, 82.3f)) }; private static readonly Vector3 VAN_HALF = new Vector3(1f, 0.85f, 2.4f); private static Player Anchor { get { try { return ((Object)(object)_anchor != (Object)null && (Object)(object)((Component)_anchor).transform != (Object)null) ? _anchor : Player.Local; } catch { return Player.Local; } } } public static bool IsRecruiting => _state == State.Recruiting; public static bool OpDropActive => _state == State.AwaitDrop; public static Vector3 OpDropPos => _dropPos; public static int OpDropReachInt => Mathf.RoundToInt(4.5f); public static int CurrentVariant => (int)_variant; internal static string ActiveVanGuid => (_state != State.Idle && !string.IsNullOrEmpty(_vanGuid)) ? _vanGuid : null; public static int ReleasedVictimSeq { get; private set; } public static int ReleasedVictimObjId { get; private set; } internal static void SetPendingOrphanVan(string guid) { _pendingOrphanVanGuid = (string.IsNullOrEmpty(guid) ? null : guid); } internal static bool IsActiveVan(LandVehicle v) { try { if ((Object)(object)v == (Object)null) { return false; } string text = ActiveVanGuid; if (string.IsNullOrEmpty(text)) { try { text = QuestNetSync.RemoteKidnapVanGuid; } catch { } } if (string.IsNullOrEmpty(text)) { return false; } string text2 = null; try { text2 = v.GUID.ToString(); } catch { } return text2 != null && text2 == text; } catch { return false; } } public static void ResetForSceneReload() { try { AbortQuiet(); } catch { } _clientDropPrevActive = false; _clientReleaseSeq = 0; _clientReleaseTries = 0; _clientKoSentFor = null; _clientKoScanNext = 0f; try { if (_clientRecruitOn) { RapimentoRecruit.SetEnabled(on: false); _clientRecruitOn = false; } } catch { } } public static void StartRapimentoFromChat() { _anchor = null; _anchorWho = null; BeginOperation(Variant.Rapimento); } internal static void HostStartForClient(string who, string npcId) { if (!SessionGate.IsAuthority) { return; } try { Player val = ResolvePlayerByCode(who); if (string.IsNullOrEmpty(npcId)) { _anchor = val; _anchorWho = (((Object)(object)val != (Object)null) ? who : null); if ((Object)(object)val == (Object)null) { NDLog.DebugWarn("[RAPIMENTO] client '" + who + "' not resolvable — using host anchor."); } BeginOperation(Variant.Rapimento); } else if (_state == State.Recruiting) { if ((Object)(object)val != (Object)null) { _anchor = val; _anchorWho = who; } NPC nPC = NPCManager.GetNPC(npcId); if ((Object)(object)nPC != (Object)null) { OnRecruited(nPC); } else { NDLog.DebugWarn("[RAPIMENTO] recruit relay: NPC '" + npcId + "' not found on host."); } } } catch (Exception ex) { NDLog.Warn("HostStartForClient: " + ex.Message); } } internal static void HostStartCarryForClient(string who, string npcId) { if (!SessionGate.IsAuthority) { return; } try { if (_state != State.Recruiting) { return; } Player val = ResolvePlayerByCode(who); if ((Object)(object)val != (Object)null) { _anchor = val; _anchorWho = who; } NPC val2 = ((!string.IsNullOrEmpty(npcId)) ? NPCManager.GetNPC(npcId) : null); if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)null) { NDLog.DebugWarn("[RAPIMENTO] carry relay: NPC '" + npcId + "' not found on host."); return; } Transform val3 = null; try { Draggable componentInChildren = ((Component)val2).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { val3 = (((Object)(object)componentInChildren.Rigidbody != (Object)null) ? ((Component)componentInChildren.Rigidbody).transform : ((Component)componentInChildren).transform); } } catch { } OnPickedUp(val2, val3); NDLog.Debug("[RAPIMENTO] carry relay: host entered carry mode for client '" + who + "' npc '" + npcId + "' (body=" + (((Object)(object)val3 != (Object)null) ? "resolved" : "null→fallback") + ")."); } catch (Exception ex) { NDLog.Warn("HostStartCarryForClient: " + ex.Message); } } internal static Player ResolvePlayerByCode(string code) { try { if (string.IsNullOrEmpty(code)) { return null; } List playerList = Player.PlayerList; if (playerList == null) { return null; } for (int i = 0; i < playerList.Count; i++) { Player val = playerList[i]; if (!((Object)(object)val == (Object)null)) { string text = null; try { text = val.PlayerCode; } catch { } if (text == code) { return val; } } } } catch { } return null; } internal static void StartTorturaFromChat() { BeginOperation(Variant.Tortura); } internal static void StartTortura(string who = "") { if (!SessionGate.IsAuthority) { return; } try { if (string.IsNullOrEmpty(who)) { _anchor = null; _anchorWho = null; } else { _anchorWho = (((Object)(object)(_anchor = ResolvePlayerByCode(who)) != (Object)null) ? who : null); } BeginOperation(Variant.Tortura); } catch (Exception ex) { NDLog.Warn("StartTortura: " + ex.Message); } } internal static void StartEsecuzioneFromChat() { BeginOperation(Variant.Esecuzione); } internal static void StartEsecuzione(string who = "") { if (!SessionGate.IsAuthority) { return; } try { if (string.IsNullOrEmpty(who)) { _anchor = null; _anchorWho = null; } else { _anchorWho = (((Object)(object)(_anchor = ResolvePlayerByCode(who)) != (Object)null) ? who : null); } BeginOperation(Variant.Esecuzione); } catch (Exception ex) { NDLog.Warn("StartEsecuzione: " + ex.Message); } } private static void BeginOperation(Variant v) { //IL_00fb: 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_0114: 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_0181: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority || !TerritoryHandover.HandoverActive) { return; } if (TortureManager.IsActive) { DonMessaging.SendDon("We're in the middle of something, boss — finish it first."); return; } if (_state != State.Idle) { DonMessaging.SendDon("One job at a time, boss — we're already out on a pickup."); return; } _target = null; _carrying = false; _carryBody = null; _targetName = "the mark"; _targetHidden = false; _variant = v; TortureManager.OpScene opScene = TortureManager.SceneFor(v); _opLabel = ((opScene != null) ? opScene.OpLabel : "Kidnapping"); _payPending = false; _sackInserted = false; _rollPlayed = false; _rollDriveTimer = 0f; Player anchor = Anchor; if ((Object)(object)anchor == (Object)null || (Object)(object)((Component)anchor).transform == (Object)null) { _anchor = null; _anchorWho = null; return; } _parkPos = PickVanPickupSpot(((Component)anchor).transform.position, out _parkYaw); if (!SpawnVan("Veeper", _parkPos, _parkYaw)) { DonMessaging.SendDon("Couldn't get a van out, boss. Give me a moment and try again."); return; } RapimentoMarkerQuest.EnsureCreated(_opLabel + ": grab the van at the parking lot", _parkPos); _markerUpdateCd = 0.5f; DonMessaging.SendDon((opScene != null) ? "We've got someone who needs taking care of, boss. There's a van at the lot on your map — go pick it up." : "There's a van parked for you at the lot on your map, boss. Go pick it up."); NDLog.Info($"[RAPIMENTO] started ({v}) — van at {_parkPos}, awaiting pickup."); _state = State.VanReady; _stateTimer = 0f; } catch (Exception ex) { NDLog.Warn("Rapimento.BeginOperation: " + ex.Message); AbortQuiet(); } } private static void TickVanReady(float dt) { if (!VanAlive()) { DonMessaging.SendDon("Lost the van, boss. Job's off."); Abort(); } else if (VanOccupied()) { RapimentoRecruit.OnRecruited = OnRecruited; RapimentoRecruit.SetEnabled(on: true); RapimentoMarkerQuest.SetText(_opLabel + ": drive up to someone, stop, and talk them into the van"); DonMessaging.SendDon("You've got wheels now, boss. Drive around, pull up to someone, hop out and talk 'em into the back."); NDLog.Debug("[RAPIMENTO] van picked up → recruiting ON."); _state = State.Recruiting; _stateTimer = 0f; } } private static void OnRecruited(NPC npc) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) try { if (_state != State.Recruiting || (Object)(object)npc == (Object)null || (Object)(object)((Component)npc).gameObject == (Object)null) { return; } try { NPCHealth health = npc.Health; if ((Object)(object)health != (Object)null && (health.IsDead || health.IsKnockedOut)) { return; } } catch { } if (!VanAlive()) { DonMessaging.SendDon("Lost the van, boss. Job's off."); Abort(); return; } RapimentoRecruit.SetEnabled(on: false); _target = npc; try { _targetName = ((Object)((Component)npc).gameObject).name; } catch { _targetName = "the mark"; } _targetHidden = false; _carrying = false; _carryBody = null; RapimentoLure.Begin(_target); KidnapLoopStart(); _trunkBox = RapimentoZones.MakeTrunkBox(TRUNK_COLOR); PositionTrunkBox(); RapimentoMarkerQuest.SetText(_opLabel + ": lead the mark to the van"); DonMessaging.SendDon("Good pick, boss. Get out and walk 'em into the back of the van."); NDLog.Debug("[RAPIMENTO] recruited '" + _targetName + "', van GUID=" + _vanGuid + "."); _state = State.Luring; _stateTimer = 0f; } catch (Exception ex) { NDLog.Warn("Rapimento.OnRecruited: " + ex.Message); AbortQuiet(); } } private static void TryPickupKO() { try { DragManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null || !instance.IsDragging) { return; } Draggable currentDraggable = instance.CurrentDraggable; if ((Object)(object)currentDraggable == (Object)null) { return; } NPC componentInParent = ((Component)currentDraggable).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || (Object)(object)((Component)componentInParent).gameObject == (Object)null) { return; } bool flag = false; try { NPCHealth health = componentInParent.Health; flag = (Object)(object)health != (Object)null && health.IsKnockedOut && !health.IsDead; } catch { } if (flag) { Transform val = null; try { val = (((Object)(object)currentDraggable.Rigidbody != (Object)null) ? ((Component)currentDraggable.Rigidbody).transform : ((Component)currentDraggable).transform); } catch { val = ((Component)currentDraggable).transform; } OnPickedUp(componentInParent, val); } } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO] TryPickupKO: " + ex.Message); } } private static void OnPickedUp(NPC npc, Transform body) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) try { if (_state != State.Recruiting || (Object)(object)npc == (Object)null || (Object)(object)((Component)npc).gameObject == (Object)null) { return; } if (!VanAlive()) { DonMessaging.SendDon("Lost the van, boss. Job's off."); Abort(); return; } RapimentoRecruit.SetEnabled(on: false); _target = npc; try { _targetName = ((Object)((Component)npc).gameObject).name; } catch { _targetName = "the mark"; } _targetHidden = false; _carrying = true; _carryBody = body; KidnapLoopStart(); _trunkBox = RapimentoZones.MakeTrunkBox(TRUNK_COLOR); PositionTrunkBox(); RapimentoMarkerQuest.SetText(_opLabel + ": haul the body into the van"); DonMessaging.SendDon("Out cold — good. Drag the body into the back of the van, boss."); NDLog.Debug("[RAPIMENTO] picked up KO'd '" + _targetName + "' (carry mode), van GUID=" + _vanGuid + "."); _state = State.Luring; _stateTimer = 0f; } catch (Exception ex) { NDLog.Warn("Rapimento.OnPickedUp: " + ex.Message); AbortQuiet(); } } public static void Tick(float dt) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) if (!SessionGate.IsAuthority) { TickClient(dt); } else { if (_state == State.Idle) { return; } if (_state == State.Recruiting || _state == State.Luring) { TickEscortHeat(dt); } if (PlayerArrested()) { FailBusted(); return; } _stateTimer += dt; if (_state == State.VanReady || _state == State.Recruiting || _state == State.Luring) { _markerUpdateCd -= dt; if (_markerUpdateCd <= 0f) { _markerUpdateCd = 0.5f; bool flag = VanOccupied(); try { RapimentoMarkerQuest.SetPoiVisible(!flag); } catch { } if (!flag) { try { RapimentoMarkerQuest.MoveTo(VanPos()); } catch { } } } } switch (_state) { case State.VanReady: TickVanReady(dt); break; case State.Recruiting: RapimentoRecruit.Tick(dt); TryPickupKO(); break; case State.Luring: TickLuring(dt); break; case State.AwaitDrop: TickAwaitDrop(dt); break; } SyncBossMarker(); } } private static void TickClient(float dt) { try { bool flag = TerritoryHandover.IsBossForLocalPeer && QuestNetSync.RemoteRapRecruiting; if (flag && !_clientRecruitOn) { RapimentoRecruit.OnRecruited = OnClientRecruited; RapimentoRecruit.SetEnabled(on: true); _clientRecruitOn = true; } else if (!flag && _clientRecruitOn) { RapimentoRecruit.SetEnabled(on: false); _clientRecruitOn = false; } if (_clientRecruitOn) { RapimentoRecruit.Tick(dt); } if (flag) { TryRelayClientKoPickup(); } bool flag2 = QuestNetSync.RemoteOpDropActive && TerritoryHandover.IsBossForLocalPeer; if (flag2 != _clientDropDiagOn) { _clientDropDiagOn = flag2; NDLog.Debug(string.Format("[RAPIMENTO] client drop phase {0} (rawActive={1}, boss={2}, variant={3}).", flag2 ? "ON" : "off", QuestNetSync.RemoteOpDropActive, TerritoryHandover.IsBossForLocalPeer, QuestNetSync.RemoteOpVariant)); } if (_clientDropPrevActive && !flag2) { try { TeleportMirror.ExitLocalVehicle(); } catch { } NDLog.Debug("[RAPIMENTO] client exited its van on delivery → host can despawn it now."); } _clientDropPrevActive = flag2; } catch { } } public static void ClientApplyVanColor() { //IL_00ee: 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) try { if (SessionGate.IsAuthority) { return; } string remoteKidnapVanGuid = QuestNetSync.RemoteKidnapVanGuid; if (string.IsNullOrEmpty(remoteKidnapVanGuid)) { _clientColoredVan = null; } else { if (remoteKidnapVanGuid == _clientColoredVan) { return; } TortureManager.OpScene opScene = TortureManager.SceneFor((Variant)QuestNetSync.RemoteOpVariant); if (opScene == null) { _clientColoredVan = remoteKidnapVanGuid; return; } VehicleManager instance = NetworkSingleton.Instance; List list = (((Object)(object)instance != (Object)null) ? instance.AllVehicles : null); if (list == null) { return; } for (int i = 0; i < list.Count; i++) { LandVehicle val = list[i]; if ((Object)(object)val == (Object)null) { continue; } string text = null; try { text = val.GUID.ToString(); } catch { } if (!(text != remoteKidnapVanGuid)) { try { val.ApplyColor((EVehicleColor)opScene.VanColor); _clientColoredVan = remoteKidnapVanGuid; NDLog.Debug($"[RAPIMENTO] client colored pickup van -> {opScene.VanColor}."); break; } catch (Exception ex) { NDLog.DebugWarn("client van color: " + ex.Message); break; } } } } } catch { } } private static void OnClientRecruited(NPC npc) { try { if (!((Object)(object)npc == (Object)null) && !((Object)(object)((Component)npc).gameObject == (Object)null)) { string text = null; try { text = npc.ID; } catch { } if (!string.IsNullOrEmpty(text)) { RapimentoRecruit.SetEnabled(on: false); _clientRecruitOn = false; ClientActionNet.SendAction("raprecruit", text); NDLog.Debug("[RAPIMENTO] client picked target '" + text + "' -> relayed to host."); } } } catch (Exception ex) { NDLog.DebugWarn("OnClientRecruited: " + ex.Message); } } private static void TryRelayClientKoPickup() { try { if (Time.time < _clientKoScanNext) { return; } _clientKoScanNext = Time.time + 0.25f; DragManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null || !instance.IsDragging) { _clientKoSentFor = null; return; } Draggable currentDraggable = instance.CurrentDraggable; if ((Object)(object)currentDraggable == (Object)null) { return; } NPC componentInParent = ((Component)currentDraggable).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || (Object)(object)((Component)componentInParent).gameObject == (Object)null) { return; } bool flag = false; try { NPCHealth health = componentInParent.Health; flag = (Object)(object)health != (Object)null && health.IsKnockedOut && !health.IsDead; } catch { } if (flag) { string text = null; try { text = componentInParent.ID; } catch { } if (!string.IsNullOrEmpty(text) && !(text == _clientKoSentFor) && ClientActionNet.SendAction("rapko", text)) { _clientKoSentFor = text; NDLog.Debug("[RAPIMENTO] client dragging KO'd '" + text + "' -> relayed to host (rapko)."); } } } catch (Exception ex) { NDLog.DebugWarn("TryRelayClientKoPickup: " + ex.Message); } } private static void SyncBossMarker() { //IL_003e: 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) //IL_0024: 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_0056: Unknown result type (might be due to invalid IL or missing references) try { if (_state == State.Idle) { BossMarkerSync.Clear(); return; } Vector3 worldPos; string label; if (_state == State.AwaitDrop) { worldPos = _dropPos; label = _opLabel + ": deliver the captive to the marked drop"; } else { worldPos = VanPos(); label = _opLabel + ": get to the van"; } BossMarkerSync.Set(label, worldPos, 3); } catch { } } private static void TickLuring(float dt) { //IL_0147: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00e8: 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_00b2: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_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) if (!(_carrying ? TargetCarryable() : TargetAlive())) { DonMessaging.SendDon("The mark's gone, boss — scrap this one."); Abort(); return; } if (!VanAlive()) { DonMessaging.SendDon("Lost the van, boss. Job's off."); Abort(); return; } PositionTrunkBox(); Vector3 val = TrunkCenter(); Vector3 halfExtents = RapimentoZones.TrunkBoxScale * 0.5f; if (_carrying) { Vector3 point = (((Object)(object)_carryBody != (Object)null) ? _carryBody.position : (((Object)(object)_target != (Object)null && (Object)(object)((Component)_target).transform != (Object)null) ? ((Component)_target).transform.position : (val + Vector3.up * 1000f))); if (RapimentoZones.PointInOrientedBox(point, val, BoxYaw(), halfExtents, 0.6f)) { CaptureTarget(); } return; } Vector3 anchor = val; try { Player anchor2 = Anchor; if ((Object)(object)anchor2 != (Object)null && (Object)(object)((Component)anchor2).transform != (Object)null) { anchor = ((Component)anchor2).transform.position; } } catch { } RapimentoLure.Tick(dt, anchor); if (RapimentoZones.NpcInOrientedBox(_target, val, BoxYaw(), halfExtents, 0.6f)) { CaptureTarget(); } } private static bool TargetCarryable() { try { if ((Object)(object)_target == (Object)null || (Object)(object)((Component)_target).gameObject == (Object)null) { return false; } NPCHealth health = _target.Health; return (Object)(object)health == (Object)null || !health.IsDead; } catch { return false; } } private static void TickEscortHeat(float dt) { //IL_0099: 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_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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Invalid comparison between Unknown and I4 //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Invalid comparison between Unknown and I4 //IL_00ac: 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_007a: 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) _heatScanCd -= dt; if (_heatScanCd > 0f) { return; } _heatScanCd = 0.25f; try { Player anchor = Anchor; PlayerCrimeData val = (((Object)(object)anchor != (Object)null) ? anchor.CrimeData : null); if ((Object)(object)anchor == (Object)null || (Object)(object)val == (Object)null) { return; } Vector3 pt; try { pt = (((Object)(object)anchor.Avatar != (Object)null) ? anchor.Avatar.CenterPoint : ((Component)anchor).transform.position); } catch { try { pt = ((Component)anchor).transform.position; } catch { return; } } if (!OfficerSeesPoint(pt)) { return; } try { val.RecordLastKnownPosition(true); } catch { } EPursuitLevel currentPursuitLevel = val.CurrentPursuitLevel; if ((int)currentPursuitLevel == 0) { try { val.SetPursuitLevel((EPursuitLevel)1); return; } catch { return; } } if ((int)currentPursuitLevel != 1) { return; } try { if (val.CurrentPursuitLevelDuration >= 7f) { val.Escalate(); } } catch { } } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO] EscortHeat: " + ex.Message); } } private static bool OfficerSeesPoint(Vector3 pt) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) try { List officers = PoliceOfficer.Officers; if (officers == null) { return false; } for (int i = 0; i < officers.Count; i++) { PoliceOfficer val; try { val = officers[i]; } catch { continue; } if ((Object)(object)val == (Object)null) { continue; } try { if (val.IgnorePlayers || !((NPC)val).IsConscious) { continue; } goto IL_006e; } catch { goto IL_006e; } IL_006e: VisionCone val2 = null; try { NPCAwareness awareness = ((NPC)val).Awareness; val2 = (((Object)(object)awareness != (Object)null) ? awareness.VisionCone : null); } catch { } if ((Object)(object)val2 == (Object)null) { continue; } try { if (val2.IsPointWithinSight(pt, false, (LandVehicle)null)) { return true; } } catch { } } } catch { } return false; } private static void KidnapSfx(string name, float delay = 0f, float vol = 1f) { bool flag = string.IsNullOrEmpty(_anchorWho); Sfx.PlayScoped(name, delay, vol, flag, !flag); } private static void KidnapLoopStart() { bool flag = string.IsNullOrEmpty(_anchorWho); Sfx.StartLoopScoped("heartbeat", 1f, flag, !flag); } private static void CaptureTarget() { //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_025f: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0289: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) try { RapimentoLure.Stop(); if (_carrying) { try { DragManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null && instance.IsDragging) { instance.StopDragging(Vector3.zero); } } catch { } _carrying = false; _carryBody = null; } _targetFemale = ReadFemale(_target); try { if ((Object)(object)_target != (Object)null) { _target.SetVisible(false, true); } } catch { } try { if ((Object)(object)_target != (Object)null && (Object)(object)((Component)_target).gameObject != (Object)null) { ((Component)_target).gameObject.SetActive(false); _targetHidden = true; } } catch { } KidnapSfx("kidnapping-sack"); KidnapSfx("car-door", 1f); KidnapSfx(_targetFemale ? "fem kidnap start" : "cough", 3f); _rollPlayed = false; _rollDriveTimer = 0f; DestroyTrunkBox(); StorageEntity val = TrunkStorage(); _sackInserted = (Object)(object)val != (Object)null && KidnapSackItem.Insert(val); _sackCheckCd = 2f; if (!_sackInserted) { NDLog.Warn("[RAPIMENTO] could not place kidnap sack in the trunk (no storage/slot)."); } TortureManager.OpScene opScene = TortureManager.SceneFor(_variant); _dropPos = opScene?.DropZonePos ?? WarehouseAnchor(); DestroyDropZone(); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(3.5f, 3f, 3.5f); _dropZone = RapimentoZones.MakeDropoffZone(_dropPos, val2, DROP_COLOR); try { VisualMirror.Set("rap.drop", 0, new Vector3(_dropPos.x, _dropPos.y + val2.y * 0.5f, _dropPos.z), 0f, val2, 1); } catch { } bool flag = opScene == null || opScene.DropZonePos == WarehouseAnchor(); RapimentoMarkerQuest.SetText(flag ? (_opLabel + ": drive the mark to the warehouse (Northtown)") : (_opLabel + ": drive the mark to the marked drop")); RapimentoMarkerQuest.SetPoiVisible(visible: true); RapimentoMarkerQuest.MoveTo(_dropPos); DonMessaging.SendDon(flag ? "They're in the van, boss. Take 'em up to the warehouse in Northtown — drive into the marked zone and walk away." : "They're in the van, boss. Drive 'em to the spot marked on your map and walk into the zone."); NDLog.Debug($"[RAPIMENTO] captured '{_targetName}', drop @ {_dropPos}, sack={_sackInserted}."); _state = State.AwaitDrop; _stateTimer = 0f; } catch (Exception ex) { NDLog.Warn("Rapimento.Capture: " + ex.Message); Abort(); } } private static void TickAwaitDrop(float dt) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) if (!VanAlive()) { DonMessaging.SendDon("Van's gone, boss — and the package with it."); Abort(); return; } if (!_rollPlayed) { if (VanOccupied()) { _rollDriveTimer += dt; if (_rollDriveTimer >= 5f) { KidnapSfx(_targetFemale ? "fem kidnap rolling" : "kidnap-rolling"); _rollPlayed = true; NDLog.Debug("[RAPIMENTO] kidnap-rolling played (5s into the drive)."); } } else { _rollDriveTimer = 0f; } } if (_sackInserted) { _sackCheckCd -= dt; if (_sackCheckCd <= 0f) { _sackCheckCd = 0.5f; StorageEntity val = TrunkStorage(); if ((Object)(object)val != (Object)null) { KidnapSackItem.EnsureUnlocked(val); } if ((Object)(object)val != (Object)null && !KidnapSackItem.IsPresent(val)) { FailSackRemoved(); return; } } } if (RapimentoZones.VanInZone(_vanVanilla, _dropPos, 4.5f)) { Finish(); } } private static void Finish() { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_0089: 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_0094: 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) if (_variant == Variant.Tortura || _variant == Variant.Esecuzione) { FinishIntoOperation(); return; } try { if (!string.IsNullOrEmpty(_anchorWho)) { PizzoJobManager.EmitCoopPayoutExternal(12000, "h", "Kidnapping"); _payPending = false; } else { if (!PayoutHelper.AddCash(12000, "Kidnapping")) { _payPending = true; return; } _payPending = false; } Vector3 val = BesideVan(); Vector3 pos = NavSnap(_dropPos, 15f); try { StorageEntity val2 = TrunkStorage(); if ((Object)(object)val2 != (Object)null) { KidnapSackItem.Remove(val2); } } catch { } _sackInserted = false; try { if ((Object)(object)_vanVanilla != (Object)null && _vanVanilla.IsOccupied) { _vanVanilla.ExitVehicle(); } } catch { } DestroyTrunkBox(); DespawnVan(); Sfx.StopLoop(); DestroyDropZone(); MobTeleport.Fade(val, true); NPC target = _target; _target = null; _targetHidden = false; if ((Object)(object)target != (Object)null) { KidnapSfx(_targetFemale ? "fem torture" : "chainsaw-torture", 2f); try { MelonCoroutines.Start(ReleaseAfterDelay(target, 60f, pos)); } catch { } } RapimentoMarkerQuest.CompleteAndClear(fanfare: true); try { BossMarkerSync.Clear(); } catch { } Sfx.PlayOneShot("quest-effect", 0.8f); DonMessaging.SendDon("Clean drop, boss. Package handled — and your cut's in."); NDLog.Info("[RAPIMENTO] complete."); _state = State.Idle; _stateTimer = 0f; try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } catch (Exception ex) { NDLog.Warn("Rapimento.Finish: " + ex.Message); AbortQuiet(); } } private static void FinishIntoOperation() { //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_0133: Unknown result type (might be due to invalid IL or missing references) try { Variant variant = _variant; string anchorWho = _anchorWho; Vector3 returnPos = BesideVan(); bool hostRode = false; try { Player local = Player.Local; hostRode = (Object)(object)local != (Object)null && (Object)(object)local.CurrentVehicle != (Object)null; } catch { } try { StorageEntity val = TrunkStorage(); if ((Object)(object)val != (Object)null) { KidnapSackItem.Remove(val); } } catch { } _sackInserted = false; try { if ((Object)(object)_vanVanilla != (Object)null && _vanVanilla.IsOccupied) { _vanVanilla.ExitVehicle(); } } catch { } DestroyTrunkBox(); DespawnVan(); Sfx.StopLoop(); DestroyDropZone(); try { RapimentoMarkerQuest.SetText((variant == Variant.Esecuzione) ? "Execution: finish it like a boss" : "Interrogation: beat the mark until they're out cold"); RapimentoMarkerQuest.SetPoiVisible(visible: false); } catch { } try { BossMarkerSync.Clear(); } catch { } NPC target = _target; _target = null; _targetHidden = false; _payPending = false; _markerUpdateCd = 0f; _state = State.Idle; _stateTimer = 0f; if ((Object)(object)target != (Object)null) { TortureManager.Begin(target, returnPos, variant, anchorWho, hostRode); } else { NDLog.Warn("[RAPIMENTO] operation handoff with no captive — nothing to do."); } NDLog.Debug($"[RAPIMENTO] handed off to operation ({variant})."); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } catch (Exception ex) { NDLog.Warn("Rapimento.FinishIntoOperation: " + ex.Message); AbortQuiet(); } } private static IEnumerator ReleaseAfterDelay(NPC npc, float delay, Vector3 pos) { //IL_0015: 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) float t = 0f; while (t < delay) { if ((Object)(object)npc == (Object)null || (Object)(object)((Component)npc).gameObject == (Object)null) { yield break; } t += 0.5f; yield return (object)new WaitForSeconds(0.5f); } ReleaseTargetScared(npc, pos); } private static void ReleaseTargetScared(NPC npc, Vector3 pos) { //IL_00b1: 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) if ((Object)(object)npc == (Object)null) { return; } try { if ((Object)(object)((Component)npc).gameObject != (Object)null && !((Component)npc).gameObject.activeSelf) { ((Component)npc).gameObject.SetActive(true); } try { npc.SetVisible(true, true); } catch { } try { if ((Object)(object)npc.Health != (Object)null && (npc.Health.IsKnockedOut || !npc.IsConscious)) { npc.Health.Revive(); } } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO] revive: " + ex.Message); } WarpNpc(npc, NavSnap(pos, 12f)); RapimentoLure.RestoreNpc(npc); try { npc.Avatar.EmotionManager.AddEmotionOverride("Scared", "RapimentoFreed", 60f, 10); } catch (Exception ex2) { NDLog.DebugWarn("[RAPIMENTO] scared-emote: " + ex2.Message); } try { if ((Object)(object)npc.Health != (Object)null) { npc.Health.TakeDamage(25f, false); } } catch (Exception ex3) { NDLog.DebugWarn("[RAPIMENTO] release-damage: " + ex3.Message); } ApplyVictimDrugEffects(npc); try { NetworkObject val = (((Object)(object)((Component)npc).gameObject != (Object)null) ? ((Component)npc).gameObject.GetComponent() : null); if ((Object)(object)val != (Object)null) { ReleasedVictimObjId = val.ObjectId; ReleasedVictimSeq++; } } catch { } NDLog.Debug("[RAPIMENTO] victim released (scared + bloodied + drugged)."); } catch (Exception ex4) { NDLog.DebugWarn("Rapimento.ReleaseTargetScared: " + ex4.Message); } } public static void ClientApplyRelease(int seq, int objId) { try { if (SessionGate.IsAuthority || objId == 0 || seq == _clientReleaseSeq) { return; } NPC val = FindNpcByObjId(objId); if ((Object)(object)val == (Object)null) { if (++_clientReleaseTries > 90) { NDLog.DebugWarn($"[RAPIMENTO] client release: npc objId={objId} unresolved after {90} tries — giving up."); _clientReleaseSeq = seq; _clientReleaseTries = 0; } return; } _clientReleaseSeq = seq; _clientReleaseTries = 0; try { val.Avatar.EmotionManager.AddEmotionOverride("Scared", "RapimentoFreed", 60f, 10); } catch { } ApplyVictimDrugEffects(val); NDLog.Debug($"[RAPIMENTO] client applied release effects to npc objId={objId}."); } catch (Exception ex) { NDLog.DebugWarn("ClientApplyRelease: " + ex.Message); } } private static NPC FindNpcByObjId(int objId) { try { NPC[] array = Object.FindObjectsOfType(true); if (array != null) { foreach (NPC val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { NetworkObject component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.ObjectId == objId) { return val; } } } } } catch { } return null; } private static void ApplyVictimDrugEffects(NPC npc) { try { Avatar val = ((npc != null) ? npc.Avatar : null); if (!((Object)(object)val == (Object)null)) { try { val.Effects.TriggerSick(true); } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO] toxic-sick: " + ex.Message); } try { val.EmotionManager.AddEmotionOverride("Concerned", "toxic", 30f, 1); } catch { } try { val.Effects.EnableLaxative(true); } catch (Exception ex2) { NDLog.DebugWarn("[RAPIMENTO] laxative: " + ex2.Message); } try { val.Eyes.SetPupilDilation(0.1f, false); } catch (Exception ex3) { NDLog.DebugWarn("[RAPIMENTO] schizo-pupils: " + ex3.Message); } try { val.EmotionManager.AddEmotionOverride("Scared", "Schizophrenic", 0f, 3); } catch { } NDLog.Debug("[RAPIMENTO] victim drug effects applied (Toxic + Laxative + Schizophrenic)."); } } catch (Exception ex4) { NDLog.DebugWarn("Rapimento.ApplyVictimDrugEffects: " + ex4.Message); } } private static void Abort() { AbortQuiet(); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } internal static void AbortQuiet() { //IL_008f: 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) try { RapimentoRecruit.SetEnabled(on: false); } catch { } try { RapimentoLure.Stop(); } catch { } if (_carrying) { try { DragManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null && instance.IsDragging) { instance.StopDragging(Vector3.zero); } } catch { } } _carrying = false; _carryBody = null; NPC target = _target; _target = null; if ((Object)(object)target != (Object)null) { if (_targetHidden) { ReleaseTargetScared(target, BesideVan()); } else { try { RapimentoLure.RestoreNpc(target); } catch { } } } _targetHidden = false; _sackInserted = false; DestroyTrunkBox(); DestroyDropZone(); DespawnVan(); Sfx.StopLoop(); try { RapimentoMarkerQuest.CompleteAndClear(); } catch { } try { BossMarkerSync.Clear(); } catch { } _payPending = false; _markerUpdateCd = 0f; _anchor = null; _anchorWho = null; _clientRecruitOn = false; _state = State.Idle; _stateTimer = 0f; } internal static void SweepStaleMarker() { if (!string.IsNullOrEmpty(_pendingOrphanVanGuid)) { string pendingOrphanVanGuid = _pendingOrphanVanGuid; _pendingOrphanVanGuid = null; try { if (SessionGate.IsAuthority) { LandVehicle val = ResolveVanillaByGuid(pendingOrphanVanGuid); if ((Object)(object)val != (Object)null) { try { if (val.IsOccupied) { val.ExitVehicle(); } } catch { } try { VehicleManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null && instance.PlayerOwnedVehicles != null) { instance.PlayerOwnedVehicles.Remove(val); } } catch { } try { val.DestroyVehicle(); } catch { } NDLog.Debug("[RAPIMENTO] orphan van (GUID=" + pendingOrphanVanGuid + ") despawned after reload — quest failed."); try { DonMessaging.SendDon("That pickup fell apart while you were away, boss — had to dump the van. Start fresh when you're ready."); } catch { } } else { NDLog.Debug("[RAPIMENTO] orphan van (GUID=" + pendingOrphanVanGuid + ") not in the scene — nothing to clean up."); } } } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO] orphan-van cleanup: " + ex.Message); } } if (_state == State.Idle && RapimentoMarkerQuest.Instance != null) { NDLog.Debug("[RAPIMENTO] cleaned up stale marker quest after reload."); RapimentoMarkerQuest.CompleteAndClear(); } } private static bool SpawnVan(string code, Vector3 pos, float yaw) { //IL_0153: 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_00a9: 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) try { VehicleManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { return false; } string text = code; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { NDLog.Warn("[RAPIMENTO] vehicle code '" + text + "' not in the prefab list — falling back to 'hotbox'."); text = "hotbox"; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { NDLog.Warn("[RAPIMENTO] the fallback code is missing too — no van."); return false; } } LandVehicle val = VehicleRegistry.CreateVehicle(text); if (val == null) { NDLog.Warn("[RAPIMENTO] S1API CreateVehicle returned null."); return false; } val.Spawn(pos, Quaternion.Euler(0f, yaw, 0f)); TortureManager.OpScene opScene = TortureManager.SceneFor(_variant); if (opScene != null) { try { val.ApplyColor(opScene.VanColor); } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO] op van color: " + ex.Message); } } try { val.IsPlayerOwned = true; } catch (Exception ex2) { NDLog.DebugWarn("[RAPIMENTO] IsPlayerOwned: " + ex2.Message); } _van = val; try { _vanGuid = val.GUID; } catch { _vanGuid = null; } _vanVanilla = ResolveVanVanilla(); NDLog.Debug($"[RAPIMENTO] van '{text}' spawned @ {pos} (GUID={_vanGuid})."); return true; } catch (Exception ex3) { NDLog.Warn("Rapimento.SpawnVan: " + ex3.Message); return false; } } private static void DespawnVan() { if (_van != null) { KidnapSfx("gateshut"); } if (_van != null && !string.IsNullOrEmpty(_vanGuid) && SessionGate.IsAuthority) { try { MelonCoroutines.Start(DelayedVanDespawn(_van, _vanGuid)); } catch { try { _van.DestroyVehichle(); } catch { } } } _van = null; _vanVanilla = null; _vanGuid = null; } private static IEnumerator DelayedVanDespawn(LandVehicle wrapper, string guid) { for (int i = 0; i < 100; i++) { LandVehicle veh = ResolveVanillaByGuid(guid); if ((Object)(object)veh == (Object)null) { yield break; } bool occ = false; try { occ = veh.IsOccupied; } catch { } if (occ) { try { veh.ExitVehicle(); } catch { } } else { try { if (SessionGate.IsAuthority) { wrapper.DestroyVehichle(); } } catch { } } yield return (object)new WaitForSeconds(0.1f); } try { LandVehicle veh2 = ResolveVanillaByGuid(guid); if ((Object)(object)veh2 != (Object)null) { veh2.DestroyVehicle(); } } catch { } } private static LandVehicle ResolveVanillaByGuid(string guid) { try { if (string.IsNullOrEmpty(guid)) { return null; } List list = NetworkSingleton.Instance?.AllVehicles; if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { LandVehicle val = list[i]; if (!((Object)(object)val == (Object)null)) { string text = null; try { text = val.GUID.ToString(); } catch { } if (text != null && text == guid) { return val; } } } } catch { } return null; } private static LandVehicle ResolveVanVanilla() { try { if (string.IsNullOrEmpty(_vanGuid)) { return null; } List list = NetworkSingleton.Instance?.AllVehicles; if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { LandVehicle val = list[i]; if (!((Object)(object)val == (Object)null)) { string text = null; try { text = val.GUID.ToString(); } catch { } if (text != null && text == _vanGuid) { return val; } } } } catch { } return null; } private static bool VanAlive() { try { if ((Object)(object)_vanVanilla == (Object)null || (Object)(object)((Component)_vanVanilla).gameObject == (Object)null) { _vanVanilla = ResolveVanVanilla(); } return (Object)(object)_vanVanilla != (Object)null && (Object)(object)((Component)_vanVanilla).gameObject != (Object)null; } catch { return false; } } private static Vector3 VanPos() { //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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) try { if (VanAlive()) { return ((Component)_vanVanilla).transform.position; } } catch { } return _parkPos; } private static Vector3 TrunkCenter() { //IL_004c: 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_0056: 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_005c: 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_0067: Unknown result type (might be due to invalid IL or missing references) //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_0018: 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_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) //IL_0032: 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) try { if (VanAlive()) { Transform transform = ((Component)_vanVanilla).transform; return transform.position - transform.forward * 2.6f; } } catch { } Vector3 val = Quaternion.Euler(0f, _parkYaw, 0f) * Vector3.forward; return _parkPos - val * 2.6f; } private static float BoxYaw() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) try { if (VanAlive()) { return ((Component)_vanVanilla).transform.eulerAngles.y; } } catch { } return _parkYaw; } private static void PositionTrunkBox() { //IL_0018: 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_0020: 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_0032: 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_0069: 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_00b3: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_trunkBox == (Object)null) { return; } Vector3 val = TrunkCenter(); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(val.x, val.y + 0.55f, val.z); float num = BoxYaw(); _trunkBox.transform.position = val2; _trunkBox.transform.rotation = Quaternion.Euler(0f, num, 0f); bool flag = _targetHidden || !VanOccupied(); if (_trunkBox.activeSelf != flag) { _trunkBox.SetActive(flag); } try { VisualMirror.Set("rap.trunk", 0, val2, num, RapimentoZones.TrunkBoxScale, 0, flag); } catch { } } catch { } } private static bool VanOccupied() { try { return VanAlive() && _vanVanilla.IsOccupied; } catch { return false; } } private static bool ReadFemale(NPC npc) { try { Avatar val = (((Object)(object)npc != (Object)null) ? npc.Avatar : null); if ((Object)(object)val == (Object)null) { return false; } AvatarSettings currentSettings = val.CurrentSettings; return (Object)(object)currentSettings != (Object)null && currentSettings.Gender >= 0.5f; } catch { return false; } } private static Vector3 BesideVan() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_001e: 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) //IL_0037: 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_0085: 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) try { if (VanAlive()) { Transform transform = ((Component)_vanVanilla).transform; return NavSnap(transform.position + transform.right * 1.8f, 4f); } } catch { } try { Player anchor = Anchor; if ((Object)(object)((anchor != null) ? ((Component)anchor).transform : null) != (Object)null) { return ((Component)anchor).transform.position; } } catch { } return _dropPos; } private static bool PlayerArrested() { try { Player anchor = Anchor; return (Object)(object)anchor != (Object)null && anchor.IsArrested; } catch { return false; } } private static void FailBusted() { try { DonMessaging.SendDon("Cops grabbed you, boss — job's blown. The mark's loose."); } catch { } AbortQuiet(); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static void FailSackRemoved() { try { DonMessaging.SendDon("You dumped the sack, boss — the mark slipped out. Job's off."); } catch { } NDLog.Debug("[RAPIMENTO] kidnap sack removed → victim released, quest failed."); Abort(); } private static StorageEntity TrunkStorage() { try { return VanAlive() ? _vanVanilla.Storage : null; } catch { return null; } } private static bool TargetAlive() { try { if ((Object)(object)_target == (Object)null) { return false; } NPCHealth health = _target.Health; return (Object)(object)health == (Object)null || (!health.IsDead && !health.IsKnockedOut); } catch { return false; } } private static Vector3 PickVanPickupSpot(Vector3 ppos, out float yaw) { //IL_0115: 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_011b: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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_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_0031: 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_00b9: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) try { List<(float, Vector3, string)> list = new List<(float, Vector3, string)>(); for (int i = 0; i < PICKUP_LOTS.Length; i++) { list.Add((Vector3.Distance(PICKUP_LOTS[i].Pos, ppos), PICKUP_LOTS[i].Pos, PICKUP_LOTS[i].Name)); } list.Sort(((float d, Vector3 p, string n) a, (float d, Vector3 p, string n) b) => a.d.CompareTo(b.d)); int maxValue = Math.Min(3, list.Count); (float, Vector3, string) tuple = list[_rng.Next(maxValue)]; Vector3 val = NavSnap(tuple.Item2, 20f); yaw = FaceYaw(val, ppos); NDLog.Debug($"[RAPIMENTO] van pickup spot = '{tuple.Item3}' @ {val} ({tuple.Item1:0}m from the player)."); return val; } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO] PickVanPickupSpot: " + ex.Message); } Vector3 val2 = PickParkSpot(ppos); yaw = FaceYaw(val2, ppos); return val2; } private static Vector3 PickParkSpot(Vector3 ppos) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_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_0078: 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_0112: 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_009b: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00b9: Unknown result type (might be due to invalid IL or missing references) float[] array = new float[5] { 6f, 9f, 13f, 18f, 25f }; NavMeshHit val2 = default(NavMeshHit); for (int i = 0; i < array.Length; i++) { for (int j = 0; j < 8; j++) { double num = (double)j / 8.0 * Math.PI * 2.0 + _rng.NextDouble(); Vector3 val = ppos + new Vector3((float)Math.Cos(num), 0f, (float)Math.Sin(num)) * array[i]; if (NavMesh.SamplePosition(val, ref val2, 6f, -1)) { Vector3 position = ((NavMeshHit)(ref val2)).position; if (IsSpotClear(position, VAN_HALF, FaceYaw(position, ppos))) { return position; } } } } NDLog.DebugWarn("[RAPIMENTO] no obstacle-free van spot — falling back to NavMesh point."); NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(ppos, ref val3, 10f, -1)) { return ((NavMeshHit)(ref val3)).position; } return ppos; } private static bool IsSpotClear(Vector3 groundPos, Vector3 half, float yaw) { //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_0008: 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_0019: 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_001f: 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_002c: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = groundPos + Vector3.up * (half.y + 0.2f); Collider[] array = Physics.OverlapBox(val, half, Quaternion.Euler(0f, yaw, 0f), -5, (QueryTriggerInteraction)1); if (array == null) { return true; } foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).gameObject == (Object)null) && !val2.isTrigger && !((Object)(object)((Component)val2).GetComponentInParent() != (Object)null)) { string text = ((Object)((Component)val2).gameObject).name ?? ""; if (text.IndexOf("Terrain", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Ground", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Road", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Floor", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Pavement", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Sidewalk", StringComparison.OrdinalIgnoreCase) < 0) { return false; } } } return true; } catch { return true; } } private static Vector3 WarehouseAnchor() { //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_0009: Unknown result type (might be due to invalid IL or missing references) return WAREHOUSE_DROP; } private static Vector3 NavSnap(Vector3 pos, float radius) { //IL_0002: 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_0023: 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_0026: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(pos, ref val, radius, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return pos; } private static float FaceYaw(Vector3 from, Vector3 to) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_002f: 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_0035: 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) Vector3 val = to - from; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { return 0f; } Quaternion val2 = Quaternion.LookRotation(val); return ((Quaternion)(ref val2)).eulerAngles.y; } private static void WarpNpc(NPC npc, Vector3 pos) { //IL_0066: 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_0047: Unknown result type (might be due to invalid IL or missing references) try { NavMeshAgent component = ((Component)npc).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { component.Warp(pos); return; } if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.Warp(pos); return; } catch { } } } catch { } try { ((Component)npc).transform.position = pos; } catch { } } private static void DestroyTrunkBox() { try { if ((Object)(object)_trunkBox != (Object)null) { Object.Destroy((Object)(object)_trunkBox); } } catch { } _trunkBox = null; try { VisualMirror.Remove("rap.trunk"); } catch { } } private static void DestroyDropZone() { try { if ((Object)(object)_dropZone != (Object)null) { Object.Destroy((Object)(object)_dropZone); } } catch { } _dropZone = null; try { VisualMirror.Remove("rap.drop"); } catch { } } private static void PlayVehicleSound(string which) { NDLog.Debug("[RAPIMENTO] (sound hook '" + which + "' — V1 silent)."); } } internal static class RapimentoRecruit { internal const string ChoiceText = "You are in trouble so get in the van and don't make this difficult or i will kill you!"; private const float RAY_DIST = 4f; private const float POLL = 0.4f; private static bool _enabled; private static float _pollCd; private static int _lastLookId; private static readonly List _injected = new List(); public static Action OnRecruited; public static void SetEnabled(bool on) { _enabled = on; _pollCd = 0f; _lastLookId = 0; if (!on) { CleanupInjected(); } } public static void Tick(float dt) { if (!_enabled) { return; } _pollCd -= dt; if (_pollCd > 0f) { return; } _pollCd = 0.4f; try { Inject(); } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO][recruit] " + ex.Message); } } private static void Inject() { //IL_0020: 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_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown Transform val = CameraT(); RaycastHit val2 = default(RaycastHit); if ((Object)(object)val == (Object)null || !Physics.Raycast(val.position, val.forward, ref val2, 4f, -5, (QueryTriggerInteraction)1) || (Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) { return; } NPC val3 = ((Component)((RaycastHit)(ref val2)).collider).GetComponent() ?? ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent(); if ((Object)(object)val3 == (Object)null || (Object)(object)((Component)val3).gameObject == (Object)null) { return; } try { NPCHealth health = val3.Health; if ((Object)(object)health != (Object)null && (health.IsDead || health.IsKnockedOut)) { return; } } catch { } int instanceID = ((Object)((Component)val3).gameObject).GetInstanceID(); if (instanceID == _lastLookId) { return; } _lastLookId = instanceID; DialogueController val4 = ((Component)val3).gameObject.GetComponent() ?? ((Component)val3).gameObject.GetComponentInChildren(true); if ((Object)(object)val4 == (Object)null) { return; } List choices = val4.Choices; if (choices == null) { return; } for (int i = 0; i < choices.Count; i++) { DialogueChoice val5 = choices[i]; if (val5 != null && val5.ChoiceText == "You are in trouble so get in the van and don't make this difficult or i will kill you!") { return; } } DialogueChoice val6 = new DialogueChoice(); val6.ChoiceText = "You are in trouble so get in the van and don't make this difficult or i will kill you!"; val6.Enabled = true; val6.ShowWorldspaceDialogue = true; val6.Priority = 100; NPC captured = val3; val6.onChoosen.AddListener(GameCompat.ToUnityAction((Action)delegate { try { OnRecruited?.Invoke(captured); } catch (Exception ex) { NDLog.DebugWarn("[RAPIMENTO][recruit] onChoosen: " + ex.Message); } })); choices.Add(val6); TrackController(val4); NDLog.Debug($"[RAPIMENTO][recruit] choice injected (NPC {instanceID})."); } private static void TrackController(DialogueController ctrl) { for (int i = 0; i < _injected.Count; i++) { if (GameCompat.SameInstance((object)_injected[i], (object)ctrl)) { return; } } _injected.Add(ctrl); } private static void CleanupInjected() { for (int i = 0; i < _injected.Count; i++) { DialogueController val = _injected[i]; try { if ((Object)(object)val == (Object)null) { continue; } List choices = val.Choices; if (choices == null) { continue; } for (int num = choices.Count - 1; num >= 0; num--) { DialogueChoice val2 = choices[num]; if (val2 != null && val2.ChoiceText == "You are in trouble so get in the van and don't make this difficult or i will kill you!") { choices.RemoveAt(num); } } } catch { } } _injected.Clear(); } private static Transform CameraT() { try { PlayerCamera instance = PlayerSingleton.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)((Component)instance).transform != (Object)null) { return ((Component)instance).transform; } } catch { } try { Camera main = Camera.main; if ((Object)(object)main != (Object)null) { return ((Component)main).transform; } } catch { } return null; } } internal static class RapimentoZones { internal static readonly Vector3 TrunkBoxScale = new Vector3(1.6f, 1.1f, 3f); internal static GameObject MakeTrunkBox(Color color) { //IL_001d: 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) GameObject val = null; try { val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Ndrangheta_RapimentoTrunk"; val.transform.localScale = TrunkBoxScale; StripCollider(val); PropVisuals.ApplyGlass(val, color, 0.32f); } catch (Exception ex) { NDLog.DebugWarn("RapimentoZones.MakeTrunkBox: " + ex.Message); } return val; } internal static GameObject MakeDropoffZone(Vector3 center, Vector3 size, Color color) { //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_0029: 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_003c: 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_005c: Unknown result type (might be due to invalid IL or missing references) GameObject val = null; try { val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Ndrangheta_RapimentoDrop"; val.transform.position = new Vector3(center.x, center.y + size.y * 0.5f, center.z); val.transform.localScale = size; StripCollider(val); PropVisuals.ApplyGlass(val, color, 0.32f); } catch (Exception ex) { NDLog.DebugWarn("RapimentoZones.MakeDropoffZone: " + ex.Message); } return val; } internal static bool NpcInBox(NPC npc, Vector3 center, float radius) { //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) //IL_003a: 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_0048: 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_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) try { if ((Object)(object)npc == (Object)null || (Object)(object)((Component)npc).transform == (Object)null) { return false; } Vector3 position = ((Component)npc).transform.position; position.y = 0f; Vector3 val = center; val.y = 0f; Vector3 val2 = position - val; return ((Vector3)(ref val2)).sqrMagnitude <= radius * radius; } catch { return false; } } internal static bool NpcInOrientedBox(NPC npc, Vector3 center, float yawDeg, Vector3 halfExtents, float margin) { //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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)npc == (Object)null || (Object)(object)((Component)npc).transform == (Object)null) { return false; } return PointInOrientedBox(((Component)npc).transform.position, center, yawDeg, halfExtents, margin); } catch { return false; } } internal static bool PointInOrientedBox(Vector3 point, Vector3 center, float yawDeg, Vector3 halfExtents, float margin) { //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_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_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_0020: 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_0036: 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) try { Vector3 val = Quaternion.Euler(0f, 0f - yawDeg, 0f) * (point - center); return Mathf.Abs(val.x) <= halfExtents.x + margin && Mathf.Abs(val.z) <= halfExtents.z + margin; } catch { return false; } } internal static bool VanInZone(LandVehicle van, Vector3 center, float radius) { //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) //IL_003a: 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_0048: 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_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) try { if ((Object)(object)van == (Object)null || (Object)(object)((Component)van).transform == (Object)null) { return false; } Vector3 position = ((Component)van).transform.position; position.y = 0f; Vector3 val = center; val.y = 0f; Vector3 val2 = position - val; return ((Vector3)(ref val2)).sqrMagnitude <= radius * radius; } catch { return false; } } private static void StripCollider(GameObject go) { try { Collider component = go.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; Object.Destroy((Object)(object)component); } } catch { } } } internal static class RealEstateManager { private enum Role { Door, Patrol, Escort } private enum Move { Stationary, ToPost, Patrolling, Following, Fighting } private sealed class Guard { public NPC G; public int Slot; public Role Role; public Role HomeRole; public Move Move; public Vector3 Post; public float PostYaw; public int RouteIdx; public Vector3[] RouteWps; public int WpIdx; public int Dir = 1; public float HoldUntil; public float RepathCd; public float RecallDeadline; public float CalmAt; } public const int VILLA_PRICE = 25000; public const int LAGER_PRICE = 7500; private const float SELL_REFUND_PCT = 0.8f; private const float SCAN_INTERVAL = 1.5f; private const float REPATH_INTERVAL = 2f; private const float POST_REACH = 1.6f; private const float WP_REACH = 2.2f; private const float DEFEND_RADIUS = 30f; private const float ESCORT_RADIUS = 25f; private const float ESCORT_FOLLOW = 2.6f; private const float RECALL_TIMEOUT = 90f; private const float PATROL_HOLD_SECONDS = 20f; private static readonly Vector3 GATE = new Vector3(145.61f, 5.02f, 104.22f); private static readonly Vector3[] DoorPostPos = (Vector3[])(object)new Vector3[4] { new Vector3(145.61f, 5.02f, 104.22f), new Vector3(140.73f, 5.03f, 99f), new Vector3(146.47f, 4.83f, 128.28f), new Vector3(99.14f, 5.22f, 119.66f) }; private static readonly float[] DoorPostYaw = new float[4] { 202.5f, 225f, 90f, 225f }; private static readonly Vector3[][] PatrolRoutes = new Vector3[3][] { (Vector3[])(object)new Vector3[3] { new Vector3(132.66f, 5.13f, 113.39f), new Vector3(111.88f, 5.13f, 103.01f), new Vector3(111.24f, 5.11f, 119.17f) }, (Vector3[])(object)new Vector3[3] { new Vector3(144.09f, 5.13f, 112.99f), new Vector3(145.19f, 5.1f, 125.42f), new Vector3(132.56f, 5.14f, 125.11f) }, (Vector3[])(object)new Vector3[3] { new Vector3(152.65f, 4.67f, 95.88f), new Vector3(152.32f, 3.66f, 87.79f), new Vector3(140.48f, 1.09f, 82.24f) } }; internal static readonly Vector3[] SpotCandidates = (Vector3[])(object)new Vector3[3] { new Vector3(-101.89f, -3.71f, 48.14f), new Vector3(-0.37f, 0.1f, 56.64f), new Vector3(6.87f, 0.1f, -6.58f) }; internal static readonly string[] SpotNames = new string[3] { "Deposito West (docks)", "Deposito Centro (downtown)", "Deposito Centro Due (downtown)" }; private static int _clientEstateCode = -1; private static readonly int[] _furnishA = new int[4] { FurnishCatalog.DefaultSurfaces, FurnishCatalog.DefaultSurfaces, FurnishCatalog.DefaultSurfaces, FurnishCatalog.DefaultSurfaces }; private static readonly int[] _furnishB = new int[4] { 1, 1, 1, 0 }; private static readonly List _guards = new List(); private static readonly List _engagedOfficers = new List(); private static float _scanCd; private static float _deployRetryAt; private static bool _fighting; private static bool _knockDisabled; private static CartelGoon[] _goonScanCache; private static float _goonScanCacheAt = -999f; private static Sprite _doorIcon; private static Sprite _villaIcon; private static Sprite _depositoIcon; private static Vector3[][] _clientRouteWps; private static bool _clientGuardsActive; private static readonly int[] _clientWp = new int[PatrolRoutes.Length]; private static readonly int[] _clientDir = new int[PatrolRoutes.Length]; private static readonly float[] _clientHold = new float[PatrolRoutes.Length]; private static readonly bool[] _clientSeeded = new bool[PatrolRoutes.Length]; private static bool _evictLogged; private static float _carSweepNextAt; public static int VillaRefund => Mathf.RoundToInt(20000f); public static int LagerRefund => Mathf.RoundToInt(6000f); public static bool VillaOwned { get; private set; } public static bool VillaCarSpawned { get; private set; } public static int LagerMask { get; private set; } public static int SyncCode => (VillaOwned ? 8 : 0) | (LagerMask & 7); public static bool VillaOwnedView => (SessionGate.IsAuthority || _clientEstateCode < 0) ? VillaOwned : ((_clientEstateCode & 8) != 0); public static bool Owned => VillaOwned; public static int SpotIndex => 0; public static float FacingYaw => 0f; public static bool HasEscort => FindGuard(Role.Escort) != null; public static int GuardPatrolSyncCode { get { if (!SessionGate.IsAuthority) { return 0; } int num = 0; try { for (int i = 0; i < PatrolRoutes.Length; i++) { int num2 = DoorPostPos.Length + i; Guard guard = null; for (int j = 0; j < _guards.Count; j++) { if (_guards[j].Slot == num2) { guard = _guards[j]; break; } } if (guard != null) { int num3 = Mathf.Clamp(guard.WpIdx, 0, 3); bool flag = guard.HoldUntil > Time.time; bool flag2 = guard.Move == Move.Fighting || guard.Move == Move.Following || GuardNPC.IsDownOrKO(guard.Slot); int num4 = (num3 & 3) | (flag ? 4 : 0) | ((guard.Dir < 0) ? 8 : 0) | (flag2 ? 16 : 0); num |= (num4 & 0x1F) << i * 5; } } } catch { } return num; } } internal static bool IsLagerOpen(int idx) { return true; } internal static void MarkVillaCarSpawned() { VillaCarSpawned = true; } public static bool LagerOwned(int idx) { return idx >= 0 && idx < 3 && (LagerMask & (1 << idx)) != 0; } public static bool LagerOwnedView(int idx) { return (SessionGate.IsAuthority || _clientEstateCode < 0) ? LagerOwned(idx) : (idx >= 0 && idx < 3 && (_clientEstateCode & (1 << idx)) != 0); } public static bool AnyLagerOwnedView() { for (int i = 0; i < 3; i++) { if (LagerOwnedView(i)) { return true; } } return false; } private static int DefaultObjFor(int idx) { return (idx != 3) ? 1 : 0; } public static int GetFurnishA(int idx) { return (idx >= 0 && idx < 4) ? _furnishA[idx] : FurnishCatalog.DefaultSurfaces; } public static int GetFurnishB(int idx) { return (idx >= 0 && idx < 4) ? _furnishB[idx] : 0; } public static int GetMat(int idx, int surface) { return FurnishCatalog.Mat(GetFurnishA(idx), surface); } public static int GetCol(int idx, int surface) { return FurnishCatalog.Col(GetFurnishA(idx), surface); } public static bool GetObj(int idx, int objIdx) { return objIdx >= 0 && objIdx < 32 && (GetFurnishB(idx) & (1 << objIdx)) != 0; } public static void SetMat(int idx, int surface, int matIdx) { if (idx >= 0 && idx < 4) { _furnishA[idx] = FurnishCatalog.SetMat(_furnishA[idx], surface, FurnishCatalog.ClampMat(matIdx)); _furnishA[idx] = FurnishCatalog.SetTouched(_furnishA[idx], surface); ApplyFurnishTo(idx); PushSave(); } } public static void SetCol(int idx, int surface, int colIdx) { if (idx >= 0 && idx < 4) { _furnishA[idx] = FurnishCatalog.SetCol(_furnishA[idx], surface, FurnishCatalog.ClampCol(colIdx)); _furnishA[idx] = FurnishCatalog.SetTouched(_furnishA[idx], surface); ApplyFurnishTo(idx); PushSave(); } } public static void ToggleObj(int idx, int objIdx) { if (idx >= 0 && idx < 4 && objIdx >= 0 && objIdx < FurnishCatalog.Objects.Length) { _furnishB[idx] ^= 1 << objIdx; ApplyFurnishTo(idx); PushSave(); } } private static void ApplyFurnishTo(int idx) { if (idx == 3) { VillaRoom.ApplyFurnish(); } else { LagerRoom.ApplyFurnish(idx); } } private static void PushSave() { try { NdranghetaSaveData.Instance?.PushNow(); } catch { } } public static void LoadFurnish(int a0, int a1, int a2, int a3, int b0, int b1, int b2, int b3) { int[] array = new int[4] { a0, a1, a2, a3 }; int[] array2 = new int[4] { b0, b1, b2, b3 }; for (int i = 0; i < 4; i++) { if (array[i] == 0) { _furnishA[i] = FurnishCatalog.DefaultSurfaces; _furnishB[i] = ((array2[i] == 0) ? DefaultObjFor(i) : array2[i]); } else { _furnishA[i] = array[i]; _furnishB[i] = array2[i]; } } } public static void ResetForSceneReload() { RetireAllGuards(); GuardNPC.ResetCaches(); StandDownOfficers(); VillaOwned = false; VillaCarSpawned = false; LagerMask = 0; _clientEstateCode = -1; _clientRouteWps = null; _clientGuardsActive = false; ResetClientPatrolState(); _doorIcon = null; _villaIcon = null; _depositoIcon = null; try { DoorPoiMarker.RemoveAll(); } catch { } for (int i = 0; i < 4; i++) { _furnishA[i] = FurnishCatalog.DefaultSurfaces; _furnishB[i] = DefaultObjFor(i); } _deployRetryAt = 0f; _fighting = false; _knockDisabled = false; _goonScanCache = null; _carSweepNextAt = 0f; _evictLogged = false; VillaLocator.ResetForSceneReload(); VillaProbe.ResetForSceneReload(); LagerRoom.ResetForSceneReload(); VillaRoom.ResetForSceneReload(); CircoloQuest.ClearInstanceForReload(); DepositoMarkerQuest.ClearInstanceForReload(); } public static void LoadState(bool villaOwned, int lagerMask, string villaBuildingName, bool legacyOwned, int legacySpotIndex) { VillaOwned = villaOwned; VillaCarSpawned = villaOwned; LagerMask = lagerMask & 7; if (legacyOwned && !villaOwned && lagerMask == 0) { LagerMask = 1 << Mathf.Clamp(legacySpotIndex, 0, 2); NDLog.Debug($"[CIRCOLO] Legacy spot purchase migrated -> Lager #{Mathf.Clamp(legacySpotIndex, 0, 2)}."); } VillaLocator.LoadSavedBuildingName(villaBuildingName); if (VillaOwned) { _deployRetryAt = Time.time + 8f; } NDLog.Debug($"[CIRCOLO] state loaded: villa={VillaOwned} lagerMask={LagerMask}."); } internal static void SweepStaleMarker() { try { CleanupLegacyMarkerQuests(); RefreshDoorPois(); } catch { } } internal static bool IsEstateGuard(CartelGoon g) { return false; } public static string VillaStatusText() { if (VillaOwned) { return "OWNED"; } Vector3 pos; float yaw; return VillaLocator.TryGetEntrance(out pos, out yaw) ? $"${25000:N0}" : "scouting…"; } public static bool BuyVillaFromApp(out string message) { //IL_0148: Unknown result type (might be due to invalid IL or missing references) message = ""; try { if (!SessionGate.IsAuthority) { message = "In co-op the host signs the famiglia's papers — ask them to buy or sell."; NDLog.Debug("[CIRCOLO] BuyVilla blocked: not authority."); return false; } if (!TerritoryHandover.HandoverActive) { message = "Not yet, boss — finish the Don's business first."; NDLog.Debug("[CIRCOLO] BuyVilla blocked: handover inactive."); return false; } if (VillaOwned) { message = "The Villa is already ours."; return false; } if (!VillaLocator.TryGetEntrance(out var _, out var _)) { message = "Still casing the Villa — try again."; NDLog.Debug("[CIRCOLO] BuyVilla blocked: villa not resolved (TryGetEntrance=false)."); return false; } if (!PayoutHelper.DeductCash(25000, "Villa (Real Estate)")) { message = $"Need ${25000:N0} cash, boss."; NDLog.Debug($"[CIRCOLO] BuyVilla blocked: not enough cash (need ${25000})."); return false; } VillaOwned = true; DeployGuards(); try { VillaRoom.SpawnVillaCarOnce(); } catch { } PushSave(); VillaLocator.DisableKnockOnVilla(); _knockDisabled = true; RefreshDoorPois(); DonMessaging.SendDon("The papers are signed, boss. We had a word with the owner — the Villa is famiglia ground now. The men are taking the gate."); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } message = "The Villa is ours."; NDLog.Info($"[CIRCOLO] Villa bought ('{VillaLocator.BuildingName}') — gate anchor {GATE}."); return true; } catch (Exception ex) { NDLog.Warn("[CIRCOLO] BuyVilla: " + ex.Message); message = "Something went wrong."; return false; } } public static bool BuyLagerFromApp(int idx, out string message) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) message = ""; try { if (!SessionGate.IsAuthority) { message = "In co-op the host signs the famiglia's papers — ask them to buy or sell."; return false; } if (!TerritoryHandover.HandoverActive) { message = "Not yet, boss — finish the Don's business first."; return false; } if (idx < 0 || idx >= SpotCandidates.Length) { return false; } if (LagerOwned(idx)) { message = "That deposito is already ours."; return false; } if (!PayoutHelper.DeductCash(7500, $"Deposito #{idx} (Real Estate)")) { message = $"Need ${7500:N0} cash, boss."; return false; } LagerMask |= 1 << idx; LagerRoom.EnsureLager(idx, SpotCandidates[idx]); RefreshDoorPois(); DonMessaging.SendDon(SpotNames[idx] + " is ours, boss. We dug out a room under it — crack the crate at the spot and step down into the deposito."); message = "Deposito acquired."; NDLog.Info($"[CIRCOLO] Lager #{idx} bought."); return true; } catch (Exception ex) { NDLog.Warn("[CIRCOLO] BuyLager: " + ex.Message); message = "Something went wrong."; return false; } } public static bool SellVillaFromApp(out string message) { message = ""; try { if (!SessionGate.IsAuthority) { message = "In co-op the host signs the famiglia's papers — ask them to buy or sell."; NDLog.Debug("[CIRCOLO] SellVilla blocked: not authority."); return false; } if (!VillaOwned) { message = "We don't own the Villa."; NDLog.Debug("[CIRCOLO] SellVilla blocked: villa not owned."); return false; } if (!PayoutHelper.AddCash(VillaRefund, "Villa (sold)")) { message = "Couldn't close the sale right now, boss — try again in a moment."; NDLog.Debug("[CIRCOLO] SellVilla blocked: AddCash failed (MoneyManager?)."); return false; } VillaOwned = false; VillaCarSpawned = false; TeardownVilla(); RefreshDoorPois(); DonMessaging.SendDon($"Done, boss — the Villa's off our books. We pulled the men and pocketed ${VillaRefund:N0}."); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } message = $"Villa sold — +${VillaRefund:N0}."; NDLog.Info($"[CIRCOLO] Villa sold (refund ${VillaRefund})."); return true; } catch (Exception ex) { NDLog.Warn("[CIRCOLO] SellVilla: " + ex.Message); message = "Something went wrong."; return false; } } public static bool SellLagerFromApp(int idx, out string message) { message = ""; try { if (!SessionGate.IsAuthority) { message = "In co-op the host signs the famiglia's papers — ask them to buy or sell."; return false; } if (idx < 0 || idx >= SpotCandidates.Length) { return false; } if (!LagerOwned(idx)) { message = "We don't own that deposito."; return false; } if (!PayoutHelper.AddCash(LagerRefund, $"Deposito #{idx} (sold)")) { message = "Couldn't close the sale right now, boss — try again in a moment."; return false; } LagerMask &= ~(1 << idx); LagerRoom.RemoveLager(idx); RefreshDoorPois(); DonMessaging.SendDon($"{SpotNames[idx]} is gone, boss — we filled in the room and took ${LagerRefund:N0} for it."); message = $"Deposito sold — +${LagerRefund:N0}."; NDLog.Info($"[CIRCOLO] Lager #{idx} sold (refund ${LagerRefund})."); return true; } catch (Exception ex) { NDLog.Warn("[CIRCOLO] SellLager: " + ex.Message); message = "Something went wrong."; return false; } } private static void TeardownVilla() { RetireAllGuards(); StandDownOfficers(); try { VillaRoom.Teardown(); } catch { } try { CircoloQuest.CompleteAndClear(); } catch { } try { VillaLocator.EnableKnockOnVilla(); } catch { } RestoreOwner(); _knockDisabled = false; _fighting = false; _deployRetryAt = 0f; } public static void ToggleEscortFromChat() { try { if (!SessionGate.IsAuthority || !VillaOwned) { return; } Guard guard = FindGuard(Role.Escort); if (guard != null) { RecallEscort(guard); return; } Guard guard2 = FindGuard(Role.Patrol); if (guard2 == null) { int num = _guards.Count - 1; while (num >= 0 && guard2 == null) { if (_guards[num].Role == Role.Door) { guard2 = _guards[num]; } num--; } } if (guard2 == null) { DonMessaging.SendDon("Nobody's free right now, boss — the gate comes first."); return; } guard2.HomeRole = guard2.Role; guard2.Role = Role.Escort; guard2.Move = Move.Following; guard2.RepathCd = 0f; MakeMobile(guard2); DonMessaging.SendDon("Right behind you, boss."); } catch (Exception ex) { NDLog.Warn("[CIRCOLO] Escort: " + ex.Message); } } public static void StatusFromChat() { try { if (!VillaOwned) { DonMessaging.SendDon("No Villa yet, boss. Open the Famiglia app — Real Estate is waiting."); return; } int num = 0; int num2 = 0; bool flag = false; for (int i = 0; i < _guards.Count; i++) { switch (_guards[i].Role) { case Role.Door: num++; break; case Role.Patrol: num2++; break; case Role.Escort: flag = true; break; } } int num3 = 0; for (int j = 0; j < 3; j++) { if (LagerOwned(j)) { num3++; } } string text = $"The Villa stands, boss. {num} of us on the gate, {num2} walking the grounds" + (flag ? ", one at your side" : "") + ((num3 > 0) ? string.Format(". {0} deposito{1} stocked.", num3, (num3 == 1) ? "" : "s") : "."); if (_guards.Count == 0) { text = "The Villa stands, boss — but we're stretched thin, the gate is empty. We'll man it as soon as hands are free."; } DonMessaging.SendDon(text); } catch { } } public static void ClientMirror(int estateCode) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) try { _clientEstateCode = estateCode; bool flag = (estateCode & 8) != 0; int num = estateCode & 7; if (flag) { if (!_knockDisabled) { VillaLocator.DisableKnockOnVilla(); _knockDisabled = true; } VillaRoom.EnsureVilla(); VillaRoom.KeepInteriorActive(); TickVehicleSweep(); } else { if (_knockDisabled) { VillaLocator.EnableKnockOnVilla(); _knockDisabled = false; } VillaRoom.Teardown(); } for (int i = 0; i < 3; i++) { if ((num & (1 << i)) != 0) { LagerRoom.EnsureLager(i, SpotCandidates[i]); } else { LagerRoom.RemoveLager(i); } } ClientMirrorGuards(flag); CleanupLegacyMarkerQuests(); RefreshDoorPois(); } catch (Exception ex) { NDLog.DebugWarn("[CIRCOLO] ClientMirror: " + ex.Message); } } private static void ResetClientPatrolState() { for (int i = 0; i < PatrolRoutes.Length; i++) { _clientWp[i] = 0; _clientDir[i] = 1; _clientHold[i] = 0f; _clientSeeded[i] = false; } } private static void EnsureClientRoutes() { if (_clientRouteWps != null) { return; } try { Vector3[][] array = new Vector3[PatrolRoutes.Length][]; for (int i = 0; i < PatrolRoutes.Length; i++) { array[i] = SnapRoute(PatrolRoutes[i]); } _clientRouteWps = array; } catch { _clientRouteWps = null; } } public static void ClientGuardTick(bool villaOwned, int patrolCode) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) try { if (SessionGate.IsAuthority) { return; } if (!villaOwned) { if (!_clientGuardsActive) { return; } for (int i = 0; i < PatrolRoutes.Length; i++) { int num = DoorPostPos.Length + i; if (num < 7) { GuardNPC.ClientHoldHidden(num); } } _clientGuardsActive = false; ResetClientPatrolState(); return; } _clientGuardsActive = true; for (int j = 0; j < DoorPostPos.Length && j < 7; j++) { GuardNPC.ClientWalkTo(j, DoorPostPos[j], DoorPostYaw[j], faceWhenArrived: true); } for (int k = 0; k < PatrolRoutes.Length; k++) { int num2 = DoorPostPos.Length + k; if (num2 < 7) { GuardNPC.ClientHoldHidden(num2); } } } catch { } } private static void ClientMirrorGuards(bool villa) { try { if (villa) { for (int i = 7; i < 9; i++) { GuardNPC.ClientHoldHidden(i); } } else { for (int j = 0; j < 9; j++) { GuardNPC.ClientHoldHidden(j); } } } catch (Exception ex) { NDLog.DebugWarn("[CIRCOLO] ClientMirrorGuards: " + ex.Message); } } private static void DeployGuards() { try { int num = DoorPostPos.Length + PatrolRoutes.Length; int num2 = 0; int num3 = 0; for (int i = 0; i < num; i++) { if (!SlotTaken(i)) { if (PlaceGuard(i)) { num2++; } else { num3++; } } } if (num3 > 0) { _deployRetryAt = Time.time + 6f; } if (num2 > 0 || num3 > 0) { NDLog.Debug($"[CIRCOLO] guards deployed: {_guards.Count}/{num} (placed={num2}, pending={num3})."); } } catch (Exception ex) { NDLog.Warn("[CIRCOLO] DeployGuards: " + ex.Message); } } private static bool SlotTaken(int slot) { for (int i = 0; i < _guards.Count; i++) { if (_guards[i].Slot == slot) { return true; } } return false; } private static bool PlaceGuard(int slot) { //IL_00ed: 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_00fe: 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_0114: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) try { NPC val = GuardNPC.Resolve(slot); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return false; } Guard guard = new Guard { G = val, Slot = slot, Role = ((slot >= DoorPostPos.Length) ? Role.Patrol : Role.Door) }; guard.HomeRole = guard.Role; float yaw; if (guard.Role == Role.Door) { guard.Post = FindNavPointNear(DoorPostPos[slot]); guard.PostYaw = DoorPostYaw[slot]; yaw = guard.PostYaw; guard.Move = Move.Stationary; } else { guard.RouteIdx = (slot - DoorPostPos.Length) % PatrolRoutes.Length; guard.RouteWps = SnapRoute(PatrolRoutes[guard.RouteIdx]); guard.WpIdx = 0; guard.Dir = 1; guard.Post = guard.RouteWps[0]; Vector3 val2 = guard.RouteWps[1] - guard.RouteWps[0]; val2.y = 0f; float num; if (!(((Vector3)(ref val2)).sqrMagnitude > 0.01f)) { num = 0f; } else { Quaternion val3 = Quaternion.LookRotation(val2); num = ((Quaternion)(ref val3)).eulerAngles.y; } yaw = num; guard.Move = Move.Patrolling; } if (!GuardNPC.Deploy(slot, guard.Post, yaw)) { return false; } guard.CalmAt = Time.time + 5f; _guards.Add(guard); return true; } catch (Exception ex) { NDLog.DebugWarn($"[CIRCOLO] PlaceGuard slot {slot}: {ex.Message}"); return false; } } private static void MakeMobile(Guard guard) { try { NPC g = guard.G; if ((Object)(object)g == (Object)null) { return; } try { NPCScheduleManager componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } NPCMovement movement = g.Movement; if (!((Object)(object)movement != (Object)null)) { return; } try { movement.ResumeMovement(); } catch { } try { movement.SetAgentEnabled(true); } catch { } try { ((Behaviour)movement).enabled = true; } catch { } } catch { } } private static void MakeStationary(Guard guard) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) try { NPC g = guard.G; if ((Object)(object)g == (Object)null) { return; } try { NPCScheduleManager componentInChildren = ((Component)g).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } NPCMovement movement = g.Movement; if ((Object)(object)movement != (Object)null) { try { movement.Stop(); } catch { } try { movement.PauseMovement(); } catch { } } try { if ((Object)(object)((Component)g).transform != (Object)null) { ((Component)g).transform.rotation = Quaternion.Euler(0f, guard.PostYaw, 0f); } } catch { } } catch { } } private static void RefreshDoorPois() { //IL_007c: 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) try { if ((Object)(object)_doorIcon == (Object)null) { _doorIcon = AssetLoader.LoadSprite("Ndrangheta.assets.don_icon.png"); } if ((Object)(object)_villaIcon == (Object)null) { _villaIcon = AssetLoader.LoadSprite("Ndrangheta.assets.villa_icon.png") ?? _doorIcon; } if ((Object)(object)_depositoIcon == (Object)null) { _depositoIcon = AssetLoader.LoadSprite("Ndrangheta.assets.safehouse.png") ?? _doorIcon; } if (VillaOwnedView) { DoorPoiMarker.Set("villa", GATE, "Il Circolo", _villaIcon); } else { DoorPoiMarker.Remove("villa"); } for (int i = 0; i < 3; i++) { if (LagerOwnedView(i)) { DoorPoiMarker.Set("deposito" + i, SpotCandidates[i], SpotNames[i], _depositoIcon); } else { DoorPoiMarker.Remove("deposito" + i); } } } catch (Exception ex) { NDLog.DebugWarn("[CIRCOLO] RefreshDoorPois: " + ex.Message); } } private static void CleanupLegacyMarkerQuests() { try { if (CircoloQuest.Instance != null) { CircoloQuest.CompleteAndClear(); } } catch { } try { if (DepositoMarkerQuest.Instance != null) { DepositoMarkerQuest.CompleteAndClear(); } } catch { } } public static void Tick(float dt) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_024b: 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_0423: Unknown result type (might be due to invalid IL or missing references) if (!SessionGate.IsAuthority) { return; } for (int i = 0; i < 3; i++) { if (LagerOwned(i)) { LagerRoom.EnsureLager(i, SpotCandidates[i]); } } if (!VillaOwned) { return; } if (!_knockDisabled) { VillaLocator.DisableKnockOnVilla(); _knockDisabled = true; } TickEvictOwner(); VillaRoom.EnsureVilla(); VillaRoom.EnsureVehicle(); VillaRoom.KeepInteriorActive(); TickVehicleSweep(); if (GangBattleManager.IsActive || GangWarManager.IsActive) { return; } if (_guards.Count < DoorPostPos.Length + PatrolRoutes.Length) { if (_deployRetryAt <= 0f) { _deployRetryAt = Time.time + 3f; } if (Time.time >= _deployRetryAt) { _deployRetryAt = Time.time + 10f; DeployGuards(); } if (_guards.Count == 0) { return; } } _scanCd -= dt; bool flag = _scanCd <= 0f; if (flag) { _scanCd = 1.5f; } for (int j = 0; j < _guards.Count; j++) { Guard guard = _guards[j]; if ((Object)(object)guard.G == (Object)null || (Object)(object)((Component)guard.G).gameObject == (Object)null) { NPC val = GuardNPC.Resolve(guard.Slot); if ((Object)(object)val != (Object)null) { guard.G = val; } } } for (int k = 0; k < _guards.Count; k++) { if (!GuardNPC.IsDownOrKO(_guards[k].Slot)) { TickGuard(_guards[k], dt); } } if (!flag) { return; } List list = CollectThreats(GATE, 30f); if (list.Count > 0) { _fighting = true; int num = 0; for (int l = 0; l < _guards.Count; l++) { Guard guard2 = _guards[l]; if (guard2.Role != Role.Escort) { guard2.Move = Move.Fighting; MakeMobile(guard2); Engage(guard2, list[num++ % list.Count]); } } } else if (_fighting) { _fighting = false; StandDownOfficers(); for (int m = 0; m < _guards.Count; m++) { Guard guard3 = _guards[m]; if (guard3.Role != Role.Escort) { guard3.Move = Move.ToPost; guard3.RepathCd = 0f; MakeMobile(guard3); } } } Guard guard4 = FindGuard(Role.Escort); if (guard4 != null && guard4.Move != Move.Fighting) { Player local = Player.Local; if ((Object)(object)local != (Object)null && (Object)(object)((Component)local).transform != (Object)null) { List list2 = CollectThreats(((Component)local).transform.position, 25f); if (list2.Count > 0) { guard4.Move = Move.Fighting; Engage(guard4, list2[0]); } } } else if (guard4 != null && guard4.Move == Move.Fighting) { Player local2 = Player.Local; if ((Object)(object)local2 == (Object)null || (Object)(object)((Component)local2).transform == (Object)null || CollectThreats(((Component)local2).transform.position, 25f).Count == 0) { guard4.Move = Move.Following; guard4.RepathCd = 0f; } } } private static void TickGuard(Guard guard, float dt) { //IL_008d: 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_00b2: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) try { NPC g = guard.G; if ((Object)(object)g == (Object)null) { return; } guard.RepathCd -= dt; if (Time.time >= guard.CalmAt) { guard.CalmAt = Time.time + 5f; GuardNPC.KeepCalm(guard.Slot); } switch (guard.Move) { case Move.Stationary: GuardNPC.HostHoldPost(guard.Slot, guard.Post, guard.PostYaw); break; case Move.ToPost: { Vector3 target2 = ((guard.Role == Role.Door) ? guard.Post : PatrolWp(guard, guard.WpIdx)); if (GuardNPC.HostWalkTo(guard.Slot, target2, (guard.Role == Role.Door) ? 1.6f : 2.2f, guard.PostYaw, guard.Role == Role.Door)) { guard.RecallDeadline = 0f; guard.Move = ((guard.Role != Role.Door) ? Move.Patrolling : Move.Stationary); } break; } case Move.Patrolling: { Vector3[] array = guard.RouteWps ?? PatrolRoutes[guard.RouteIdx]; if (guard.HoldUntil > Time.time) { try { if ((Object)(object)((Component)g).transform != (Object)null) { GuardNPC.HostHoldPost(guard.Slot, ((Component)g).transform.position, ((Component)g).transform.eulerAngles.y); } break; } catch { break; } } Vector3 target = array[Mathf.Clamp(guard.WpIdx, 0, array.Length - 1)]; if (GuardNPC.HostWalkTo(guard.Slot, target, 2.2f, 0f, faceWhenArrived: false)) { if (guard.Dir > 0 && guard.WpIdx >= array.Length - 1) { guard.HoldUntil = Time.time + 20f; guard.Dir = -1; guard.WpIdx = array.Length - 2; } else if (guard.Dir < 0 && guard.WpIdx <= 0) { guard.HoldUntil = Time.time + 20f; guard.Dir = 1; guard.WpIdx = 1; } else { guard.WpIdx += guard.Dir; } } break; } case Move.Following: { Player local = Player.Local; if ((Object)(object)local == (Object)null || (Object)(object)((Component)local).transform == (Object)null || !(guard.RepathCd <= 0f)) { break; } guard.RepathCd = 2f; try { if ((Object)(object)((Component)g).transform != (Object)null && Vector3.Distance(((Component)g).transform.position, ((Component)local).transform.position) > 2.6f) { g.Movement.SetDestination(((Component)local).transform.position); } break; } catch { break; } } case Move.Fighting: break; } } catch { } } internal static void TickVehicleSweep() { //IL_00ae: 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_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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (Time.time < _carSweepNextAt) { return; } _carSweepNextAt = Time.time + 10f; try { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(124.5f, 0f, 113.5f); LandVehicle[] array = Object.FindObjectsOfType(false); if (array == null) { return; } for (int i = 0; i < array.Length; i++) { try { LandVehicle val2 = array[i]; if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).transform == (Object)null || VillaRoom.IsHotbox(val2) || RapimentoManager.IsActiveVan(val2)) { continue; } Vector3 position = ((Component)val2).transform.position; if (!(Vector3.Distance(position, val) > 28f) || !(Vector3.Distance(position, GATE) > 22f)) { bool flag = false; try { flag = val2.IsPlayerOwned; } catch { } if (!flag) { ((Component)val2).gameObject.SetActive(false); NDLog.Debug("[VILLA] Foreign vehicle on the estate hidden."); } } } catch { } } } catch { } } private static void TickEvictOwner() { //IL_0104: 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) try { if (!VillaLocator.TryGetOwner(out var npc) || (Object)(object)npc == (Object)null) { return; } Transform transform = ((Component)npc).transform; if ((Object)(object)transform == (Object)null) { return; } bool flag = transform.position.y < -1500f; bool flag2 = true; if (flag) { return; } try { NPCScheduleManager componentInChildren = ((Component)npc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } try { NPCMovement movement = npc.Movement; if ((Object)(object)movement != (Object)null) { try { movement.Stop(); } catch { } try { movement.PauseMovement(); } catch { } try { movement.SetAgentEnabled(false); } catch { } } } catch { } transform.position = new Vector3(0f, -2000f, 0f); if (!_evictLogged) { _evictLogged = true; NDLog.Debug("[VILLA] Former owner evacuated (VillaEvictBoog=true — customer mechanic on him is dormant)."); } } catch { } } private static void RestoreOwner() { //IL_008e: 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_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_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_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_007f: 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) try { if (!VillaLocator.TryGetOwner(out var npc) || (Object)(object)npc == (Object)null) { return; } Transform transform = ((Component)npc).transform; if ((Object)(object)transform == (Object)null || transform.position.y > -1500f) { return; } Vector3 val = GATE; try { NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(val + Vector3.forward * 2f, ref val2, 8f, -1)) { val = ((NavMeshHit)(ref val2)).position; } } catch { } transform.position = val; try { NPCMovement movement = npc.Movement; if ((Object)(object)movement != (Object)null) { try { movement.ResumeMovement(); } catch { } try { movement.SetAgentEnabled(true); } catch { } } } catch { } try { NPCScheduleManager componentInChildren = ((Component)npc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = true; try { componentInChildren.EnableSchedule(); } catch { } } } catch { } _evictLogged = false; NDLog.Debug("[VILLA] Former owner restored."); } catch { } } private static void RecallEscort(Guard escort) { escort.Role = escort.HomeRole; escort.Move = Move.ToPost; escort.RepathCd = 0f; escort.RecallDeadline = Time.time + 90f; MakeMobile(escort); DonMessaging.SendDon("Heading back to the Villa, boss."); } private static List CollectThreats(Vector3 center, float radius) { //IL_00a5: 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_01d4: 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) List list = new List(); try { List officers = PoliceOfficer.Officers; if (officers != null) { for (int i = 0; i < officers.Count; i++) { try { PoliceOfficer val = officers[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } NPCHealth health = ((NPC)val).Health; if (!((Object)(object)health == (Object)null) && !health.IsDead && !health.IsKnockedOut) { bool flag = true; try { flag = ((NPC)val).IsCurrentlyTargetable; } catch { } if (flag && !(Vector3.Distance(((Component)val).transform.position, center) > radius)) { list.Add((NPC)(object)val); } } } catch { } } } } catch { } try { bool flag2 = AnyGoonQuestActive(); CartelGoon[] array; if (_goonScanCache != null && Time.time - _goonScanCacheAt < 4.5f) { array = _goonScanCache; } else { array = (_goonScanCache = Object.FindObjectsOfType(true)); _goonScanCacheAt = Time.time; } if (array != null && !flag2) { for (int j = 0; j < array.Length; j++) { try { CartelGoon val2 = array[j]; if (!((Object)(object)val2 == (Object)null) && val2.IsGoonSpawned && !LuckyBrawlManager.IsFriendlyGoon(val2)) { NPCHealth health2 = ((NPC)val2).Health; if (!((Object)(object)health2 == (Object)null) && !health2.IsDead && !health2.IsKnockedOut && !((Object)(object)((Component)val2).transform == (Object)null) && !(Vector3.Distance(((Component)val2).transform.position, center) > radius)) { list.Add((NPC)(object)val2); } } } catch { } } } } catch { } return list; } private static bool AnyGoonQuestActive() { try { if (LuckyBrawlManager.IsRunning) { return true; } } catch { } try { if ((Object)(object)LaBombaManager.ActiveCourier != (Object)null) { return true; } } catch { } try { if (LuckyCombatDriver.IsRunning) { return true; } } catch { } return false; } private static void Engage(Guard guard, NPC target) { try { if ((Object)(object)guard?.G == (Object)null || (Object)(object)target == (Object)null) { return; } bool flag = false; try { ICombatTargetable val = GameCompat.CastTargetable((object)target); flag = val != null && !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (!flag) { return; } GuardNPC.Engage(guard.Slot, target); PoliceOfficer val2 = GameCompat.Cast((Object)(object)target); if ((Object)(object)val2 != (Object)null) { if (ModConfig.BrawlOfficersFightBack) { EngageOfficerCounter(val2, guard.G); } return; } CartelGoon val3 = GameCompat.Cast((Object)(object)target); ICombatTargetable val4 = GameCompat.CastTargetable((object)guard.G); if (!((Object)(object)val3 != (Object)null) || val4 == null) { return; } try { val3.AttackEntity(val4, false); } catch { } } catch (Exception ex) { NDLog.DebugWarn("[CIRCOLO] Engage: " + ex.Message); } } private static void EngageOfficerCounter(PoliceOfficer officer, NPC guard) { try { object obj; if (guard == null) { obj = null; } else { GameObject gameObject = ((Component)guard).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent() : null); } NetworkObject val = (NetworkObject)obj; CombatBehaviour val2 = ((officer == null) ? null : ((NPC)officer).Behaviour?.CombatBehaviour); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } try { val2.SetDefaultWeapon(LuckyWeaponVisual.LoadAvatarWeaponByPath("Avatar/Equippables/M1911")); val2.GiveUpRange = 200f; try { val2.DefaultSearchTime = 9999f; } catch { } try { val2.SetWeapon("Avatar/Equippables/M1911"); } catch { } } catch { } val2.SetTargetAndEnable_Server(val); bool flag = false; for (int i = 0; i < _engagedOfficers.Count; i++) { if (flag) { break; } flag = (Object)(object)_engagedOfficers[i] != (Object)null && GameCompat.SameInstance((object)_engagedOfficers[i], (object)officer); } if (!flag) { _engagedOfficers.Add(officer); } } catch { } } private static void StandDownOfficers() { for (int i = 0; i < _engagedOfficers.Count; i++) { try { PoliceOfficer obj = _engagedOfficers[i]; CombatBehaviour val = ((obj == null) ? null : ((NPC)obj).Behaviour?.CombatBehaviour); if ((Object)(object)val != (Object)null) { try { ((Behaviour)val).Deactivate(); } catch { } try { ((Behaviour)val).Disable(); } catch { } } } catch { } } _engagedOfficers.Clear(); } private static void RetireAllGuards() { for (int i = 0; i < 7; i++) { try { GuardNPC.Retire(i); } catch { } } _guards.Clear(); } private static Guard FindGuard(Role role) { for (int i = 0; i < _guards.Count; i++) { if (_guards[i].Role == role) { return _guards[i]; } } return null; } private static bool Reached(NPC g, Vector3 target, float reach) { //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_002e: 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_003c: 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) try { if ((Object)(object)((Component)g).transform == (Object)null) { return false; } Vector3 position = ((Component)g).transform.position; position.y = 0f; Vector3 val = target; val.y = 0f; return Vector3.Distance(position, val) <= reach; } catch { return false; } } private static Vector3 FindNavPointNear(Vector3 p) { //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_000d: 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_003a: 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_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_003e: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(p + Vector3.up * 1.5f, ref val, 12f, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return p; } private static Vector3[] SnapRoute(Vector3[] raw) { //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_001c: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[raw.Length]; for (int i = 0; i < raw.Length; i++) { array[i] = FindNavPointNear(raw[i]); } return array; } private static Vector3 PatrolWp(Guard guard, int idx) { //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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = guard.RouteWps ?? PatrolRoutes[guard.RouteIdx]; return array[Mathf.Clamp(idx, 0, array.Length - 1)]; } } internal static class RecruitmentState { public static bool ConversationReady { get; set; } public static bool WelcomeSmsSent { get; set; } public static bool HasMetDon { get; set; } public static bool Recruited { get; set; } public static void ResetForSceneReload() { ConversationReady = false; WelcomeSmsSent = false; HasMetDon = false; Recruited = false; } } public static class RewardSpawner { public const int MaxBricksPerDrop = 5; private static float _spawnWarnMuteUntil = -999f; private const string BrickPackagingId = "brick"; private const int BrickStackLimit = 20; private static readonly string[] BrickRegistryIdCandidates = new string[2] { "brick", "bricks" }; private static PackagingDefinition _brickPackaging; internal static PackagingDefinition ResolveBrickPackaging(ProductDefinition productDef = null) { if ((Object)(object)_brickPackaging != (Object)null) { return _brickPackaging; } string[] brickRegistryIdCandidates = BrickRegistryIdCandidates; foreach (string text in brickRegistryIdCandidates) { try { ItemDefinition item = Registry.GetItem(text); if (!((Object)(object)item == (Object)null)) { PackagingDefinition val = GameCompat.Cast((Object)(object)item); if ((Object)(object)val != (Object)null) { _brickPackaging = val; NDLog.Debug("ResolveBrickPackaging: found via S1Registry.GetItem(\"" + text + "\")."); return _brickPackaging; } } } catch { } } if ((Object)(object)productDef != (Object)null) { try { PackagingDefinition[] validPackaging = productDef.ValidPackaging; if (validPackaging != null && validPackaging.Length != 0) { PackagingDefinition val2 = null; int num = -1; foreach (PackagingDefinition val3 in validPackaging) { if (!((Object)(object)val3 == (Object)null)) { int num2 = 0; try { num2 = val3.Quantity; } catch { } if (num2 > num) { val2 = val3; num = num2; } } } if ((Object)(object)val2 != (Object)null && num >= 5) { _brickPackaging = val2; NDLog.Debug($"ResolveBrickPackaging: found via ValidPackaging scan (id='{TryGetId(val2)}', qty={num})."); return _brickPackaging; } } } catch { } } return null; } private static string TryGetId(PackagingDefinition p) { try { return ((BaseItemDefinition)p).ID ?? "?"; } catch { return "?"; } } public static int SpawnItemInDrop(DeadDrop drop, string itemId, int qty) { return SpawnItemInDrop(drop, itemId, qty, heavenly: false); } public static int SpawnItemInDrop(DeadDrop drop, string itemId, int qty, bool heavenly) { return SpawnItemInDrop(drop, itemId, qty, heavenly ? new EQuality?((EQuality)4) : ((EQuality?)null)); } public static int SpawnItemInDrop(DeadDrop drop, string itemId, int qty, EQuality? quality) { if ((Object)(object)drop == (Object)null || string.IsNullOrEmpty(itemId) || qty <= 0) { return 0; } if (qty > 5) { NDLog.Debug($"SpawnItemInDrop: qty {qty} capped to {5} (DeadDrop slot limit)."); qty = 5; } StorageEntity val = null; try { val = (StorageEntity)(object)drop.Storage; } catch { } if ((Object)(object)val == (Object)null) { if (Time.time >= _spawnWarnMuteUntil) { _spawnWarnMuteUntil = Time.time + 30f; NDLog.Warn("SpawnItemInDrop: storage is null for '" + SafeDropName(drop) + "'."); } else { NDLog.DebugWarn("SpawnItemInDrop: storage is null for '" + SafeDropName(drop) + "'."); } return 0; } return SpawnItemInStorage(val, itemId, qty, quality, SafeDropName(drop)); } public static int SpawnItemInStorage(StorageEntity storage, string itemId, int qty, EQuality? quality, string label = null) { //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Expected I4, but got Unknown //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)storage == (Object)null || string.IsNullOrEmpty(itemId) || qty <= 0) { return 0; } string text = label ?? "storage"; try { ItemDefinition item = Registry.GetItem(itemId); if ((Object)(object)item == (Object)null) { if (Time.time >= _spawnWarnMuteUntil) { _spawnWarnMuteUntil = Time.time + 30f; NDLog.Warn("SpawnItemInStorage: item '" + itemId + "' not in Registry — cannot spawn."); } else { NDLog.DebugWarn("SpawnItemInStorage: item '" + itemId + "' not in Registry — cannot spawn."); } return 0; } ProductDefinition val = GameCompat.Cast((Object)(object)item); bool flag = (Object)(object)val != (Object)null; PackagingDefinition val2 = (flag ? ResolveBrickPackaging(val) : null); if (flag && (Object)(object)val2 == (Object)null) { if (Time.time >= _spawnWarnMuteUntil) { _spawnWarnMuteUntil = Time.time + 30f; NDLog.Warn("SpawnItemInDrop: S1ProductDefinition '" + itemId + "' cannot be spawned as a brick ('brick' not in Registry) — spawn skip, no raw fallback."); } else { NDLog.DebugWarn("SpawnItemInDrop: S1ProductDefinition '" + itemId + "' cannot be spawned as a brick ('brick' not in Registry) — spawn skip, no raw fallback."); } return 0; } int num = 0; int num2 = qty; while (num2 > 0) { ItemSlot val3 = FindEmptySlot(storage); if (val3 == null) { if (Time.time >= _spawnWarnMuteUntil) { _spawnWarnMuteUntil = Time.time + 30f; NDLog.Warn($"SpawnItemInStorage: '{itemId}' {num2}/{qty} left, no empty slot in '{text}' (storage full)."); } else { NDLog.DebugWarn($"SpawnItemInStorage: '{itemId}' {num2}/{qty} left, no empty slot in '{text}' (storage full)."); } break; } int num3 = ((!flag) ? 1 : ((num2 < 20) ? num2 : 20)); ItemInstance val4 = null; try { val4 = item.GetDefaultInstance(num3); } catch (Exception ex) { NDLog.DebugWarn($"GetDefaultInstance({itemId}, {num3}): {ex.Message}"); } if (val4 == null) { break; } if (flag) { bool flag2 = false; try { ProductItemInstance val5 = GameCompat.CastObj((object)val4); if (val5 != null) { val5.SetPackaging(val2); flag2 = true; if (quality.HasValue) { try { ((QualityItemInstance)val5).SetQuality(quality.Value); } catch (Exception ex2) { NDLog.DebugWarn($"SetQuality({(int)quality.Value}) {itemId}: {ex2.Message}"); } } } } catch (Exception ex3) { NDLog.DebugWarn("SetPackaging pre-store(" + itemId + "): " + ex3.Message); } if (!flag2) { if (Time.time >= _spawnWarnMuteUntil) { _spawnWarnMuteUntil = Time.time + 30f; NDLog.Warn("SpawnItemInStorage: '" + itemId + "' brick wrap failed — spawn skip, no raw insert."); } else { NDLog.DebugWarn("SpawnItemInStorage: '" + itemId + "' brick wrap failed — spawn skip, no raw insert."); } break; } } try { val3.SetStoredItem(val4, false); } catch (Exception ex4) { NDLog.DebugWarn("SetStoredItem(" + itemId + "): " + ex4.Message); break; } if (flag) { try { ItemInstance itemInstance = val3.ItemInstance; ProductItemInstance val6 = ((itemInstance != null) ? GameCompat.CastObj((object)itemInstance) : null); if (val6 != null && (Object)(object)val6.AppliedPackaging == (Object)null) { val6.SetPackaging(val2); if (quality.HasValue) { try { ((QualityItemInstance)val6).SetQuality(quality.Value); } catch { } } NDLog.Warn("SpawnItemInStorage: '" + itemId + "' packaging lost during store — re-applied post-store (client may see raw)."); } } catch { } } num += num3; num2 -= num3; } if (num > 0) { NDLog.Debug($"Spawned {num}x '{itemId}'" + (flag ? " (brick, pre-store SetPackaging)" : " (raw)") + " in '" + text + "'."); } return num; } catch (Exception ex5) { NDLog.Warn("SpawnItemInStorage failed: " + ex5.Message); return 0; } } public static int GetTotalQuantityInDrop(DeadDrop drop, string itemId) { if ((Object)(object)drop == (Object)null || string.IsNullOrEmpty(itemId)) { return 0; } try { WorldStorageEntity storage = drop.Storage; List list = ((storage != null) ? ((StorageEntity)storage).ItemSlots : null); if (list == null) { return 0; } bool flag = false; try { ItemDefinition item = Registry.GetItem(itemId); if ((Object)(object)item != (Object)null && (Object)(object)GameCompat.Cast((Object)(object)item) != (Object)null) { flag = true; } } catch { } int num = 0; int num2 = 0; int num3 = 0; for (int i = 0; i < list.Count; i++) { ItemSlot val; try { val = list[i]; } catch { continue; } ItemInstance val2 = ((val != null) ? val.ItemInstance : null); if (val2 == null) { continue; } string a = null; try { a = ((BaseItemInstance)val2).ID; } catch { } if (!string.Equals(a, itemId, StringComparison.OrdinalIgnoreCase)) { string a2 = null; try { a2 = ((BaseItemDefinition)(val2.Definition?)).ID; } catch { } if (!string.Equals(a2, itemId, StringComparison.OrdinalIgnoreCase)) { continue; } } num2++; if (flag) { if (!IsBrickInstance(val2)) { num3++; continue; } int num4 = 0; try { num4 = ((BaseItemInstance)val2).Quantity; } catch { } num += ((num4 <= 0) ? 1 : num4); } else { int num5 = 0; try { num5 = ((BaseItemInstance)val2).Quantity; } catch { } if (num5 > 0) { num += num5; } } } if (flag && num2 > 0 && num3 == num2 && num == 0) { NDLog.DebugWarn($"GetTotalQuantityInDrop({itemId}): {num2} ID matches but 0 brick matches — packaging loss? Logging first instance:"); try { for (int j = 0; j < list.Count; j++) { ItemSlot obj7 = list[j]; ItemInstance val3 = ((obj7 != null) ? obj7.ItemInstance : null); if (val3 == null) { continue; } string text = null; try { text = ((BaseItemInstance)val3).ID; } catch { } if (!string.Equals(text, itemId, StringComparison.OrdinalIgnoreCase)) { continue; } ProductItemInstance val4 = GameCompat.CastObj((object)val3); string text2 = ""; string text3 = ""; int num6 = -1; if (val4 != null) { try { text3 = val4.PackagingID ?? ""; } catch { } try { PackagingDefinition appliedPackaging = val4.AppliedPackaging; text2 = (((Object)(object)appliedPackaging != (Object)null) ? (((BaseItemDefinition)appliedPackaging).ID ?? "") : ""); num6 = (((Object)(object)appliedPackaging != (Object)null) ? appliedPackaging.Quantity : (-1)); } catch { } } NDLog.DebugWarn($" slot[{j}]: it.ID='{text}' PackagingID='{text3}' AppliedPackaging.ID='{text2}' Qty={num6}"); break; } } catch { } } return num; } catch (Exception ex) { NDLog.DebugWarn("GetTotalQuantityInDrop(" + itemId + "): " + ex.Message); return 0; } } public static int RemoveItemFromDrop(DeadDrop drop, string itemId, int maxQty = -1) { if ((Object)(object)drop == (Object)null || string.IsNullOrEmpty(itemId)) { return 0; } try { WorldStorageEntity storage = drop.Storage; List list = ((storage != null) ? ((StorageEntity)storage).ItemSlots : null); if (list == null) { return 0; } bool flag = false; try { ItemDefinition item = Registry.GetItem(itemId); if ((Object)(object)item != (Object)null && (Object)(object)GameCompat.Cast((Object)(object)item) != (Object)null) { flag = true; } } catch { } int num = 0; for (int num2 = list.Count - 1; num2 >= 0 && (maxQty < 0 || num < maxQty); num2--) { ItemSlot val; try { val = list[num2]; } catch { continue; } ItemInstance val2 = ((val != null) ? val.ItemInstance : null); if (val2 == null) { continue; } string a = null; try { a = ((BaseItemInstance)val2).ID; } catch { } if (!string.Equals(a, itemId, StringComparison.OrdinalIgnoreCase)) { continue; } int num4; if (flag) { if (!IsBrickInstance(val2)) { continue; } int num3 = 0; try { num3 = ((BaseItemInstance)val2).Quantity; } catch { } num4 = ((num3 <= 0) ? 1 : num3); } else { int num5 = 0; try { num5 = ((BaseItemInstance)val2).Quantity; } catch { } num4 = ((num5 <= 0) ? 1 : num5); } try { val.ClearStoredInstance(false); } catch { } num += num4; } if (num > 0) { NDLog.Debug($"Removed {num}x '{itemId}' from '{SafeDropName(drop)}'."); } return num; } catch (Exception ex) { NDLog.DebugWarn("RemoveItemFromDrop(" + itemId + "): " + ex.Message); return 0; } } private static bool IsBrickInstance(ItemInstance it) { try { ProductItemInstance val = GameCompat.CastObj((object)it); if (val == null) { return false; } PackagingDefinition appliedPackaging = val.AppliedPackaging; if ((Object)(object)appliedPackaging == (Object)null) { return false; } if ((Object)(object)_brickPackaging != (Object)null && appliedPackaging == _brickPackaging) { return true; } string text = null; try { text = ((BaseItemDefinition)appliedPackaging).ID; } catch { } if (!string.IsNullOrEmpty(text)) { string[] brickRegistryIdCandidates = BrickRegistryIdCandidates; foreach (string b in brickRegistryIdCandidates) { if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase)) { return true; } } if ((Object)(object)_brickPackaging != (Object)null) { string text2 = null; try { text2 = ((BaseItemDefinition)_brickPackaging).ID; } catch { } if (!string.IsNullOrEmpty(text2) && string.Equals(text, text2, StringComparison.OrdinalIgnoreCase)) { return true; } } } int num = 0; try { num = appliedPackaging.Quantity; } catch { } if (num >= 20) { return true; } return false; } catch { return false; } } private static ItemSlot FindEmptySlot(StorageEntity storage) { try { List list = ((storage != null) ? storage.ItemSlots : null); if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { ItemSlot val; try { val = list[i]; } catch { continue; } if (val != null) { ItemInstance itemInstance; try { itemInstance = val.ItemInstance; } catch { continue; } if (itemInstance == null) { return val; } } } } catch { } return null; } private static string SafeDropName(DeadDrop drop) { try { return drop.DeadDropName ?? "drop"; } catch { return "drop"; } } } [HarmonyPatch(typeof(ProductManagerLoader), "Load")] internal static class Patch_ProductManagerLoader_Load_EarlyRegister { private static bool _loggedEarlyRegister; [HarmonyPrefix] private static void Prefix(string mainPath) { try { bool isRegistered = ProductRegistry.IsRegistered; ProductRegistry.TryRegister(); bool isRegistered2 = ProductRegistry.IsRegistered; if (!_loggedEarlyRegister) { _loggedEarlyRegister = true; NDLog.Debug("early Calabrian-Cream register before ProductManagerLoader.Load " + $"(registered: {isRegistered} -> {isRegistered2}; path='{mainPath}')"); } } catch (Exception ex) { NDLog.DebugWarn("early register failed (fail-open): " + ex.Message); } } } [HarmonyPatch(typeof(SaveManager), "Save", new Type[] { typeof(string) })] internal static class SavePreCapturePatch { [HarmonyPrefix] private static void Prefix() { try { NdranghetaSaveData.Instance?.PushNow(refreshGrids: true); } catch (Exception ex) { NDLog.DebugWarn("[SAVE] pre-capture: " + ex.Message); } } } internal static class Sfx { public const string Heartbeat = "heartbeat"; public const string KidnappingSack = "kidnapping-sack"; public const string QuestEffect = "quest-effect"; public const string KillYou = "kill-you"; public const string CarDoor = "car-door"; public const string Cough = "cough"; public const string KidnapRolling = "kidnap-rolling"; public const string GateShut = "gateshut"; public const string ChainsawTorture = "chainsaw-torture"; public const string FemTorture = "fem torture"; public const string FemKidnapStart = "fem kidnap start"; public const string FemKidnapRolling = "fem kidnap rolling"; private static GameObject _root; private static AudioSource _oneShot; private static AudioSource _loop; private static string _loopName; private static readonly Dictionary _clips = new Dictionary(); private static readonly HashSet _warnedMissing = new HashSet(); private static string _mirrorLoopName = ""; private static int _appliedSeq = -1; public static int MirrorSeq { get; private set; } public static string MirrorName { get; private set; } = ""; public static float MirrorVol { get; private set; } = 1f; public static string LoopName => _mirrorLoopName; private static float GroupVolume(string name) { switch (name) { case "heartbeat": case "kidnapping-sack": case "car-door": case "cough": case "kidnap-rolling": case "gateshut": case "fem kidnap start": case "fem kidnap rolling": return ModConfig.VanSfxVolume; case "chainsaw-torture": case "fem torture": return ModConfig.WarehouseNpcSfxVolume; default: return 1f; } } private static bool EnsureSources() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown try { if ((Object)(object)_root != (Object)null && (Object)(object)_oneShot != (Object)null && (Object)(object)_loop != (Object)null) { return true; } _root = new GameObject("Ndrangheta_Sfx"); Object.DontDestroyOnLoad((Object)(object)_root); _oneShot = _root.AddComponent(); _oneShot.playOnAwake = false; _oneShot.spatialBlend = 0f; _loop = _root.AddComponent(); _loop.playOnAwake = false; _loop.spatialBlend = 0f; _loop.loop = true; return true; } catch (Exception ex) { NDLog.Warn("[SFX] EnsureSources: " + ex.Message); return false; } } private static void PlayLocal(string name, float volume) { try { if (EnsureSources()) { AudioClip val = Get(name); if ((Object)(object)val != (Object)null) { _oneShot.PlayOneShot(val, volume * GroupVolume(name)); } } } catch (Exception ex) { NDLog.DebugWarn("[SFX] PlayLocal " + name + ": " + ex.Message); } } private static void StampMirror(string name, float volume) { MirrorSeq++; MirrorName = name ?? ""; MirrorVol = volume; } public static void PlayOneShot(string name, float volume = 1f) { PlayLocal(name, volume); StampMirror(name, volume); } public static void PlayScoped(string name, float delaySeconds, float volume, bool playLocal, bool mirror) { try { if (delaySeconds <= 0f) { if (playLocal) { PlayLocal(name, volume); } if (mirror) { StampMirror(name, volume); } } else { MelonCoroutines.Start(DelayedScoped(name, delaySeconds, volume, playLocal, mirror)); } } catch (Exception ex) { NDLog.DebugWarn("[SFX] PlayScoped " + name + ": " + ex.Message); } } private static IEnumerator DelayedScoped(string name, float delaySeconds, float volume, bool playLocal, bool mirror) { yield return (object)new WaitForSeconds(delaySeconds); if (playLocal) { PlayLocal(name, volume); } if (mirror) { StampMirror(name, volume); } } public static void ApplyMirror(int seq, string name, float volume, string loop) { try { if (string.IsNullOrEmpty(loop)) { if ((Object)(object)_loop != (Object)null && _loop.isPlaying) { StopLoop(); } } else { StartLoop(loop); } if (_appliedSeq < 0) { _appliedSeq = seq; } else if (seq != _appliedSeq) { _appliedSeq = seq; if (!string.IsNullOrEmpty(name)) { PlayOneShot(name, volume); } } } catch (Exception ex) { NDLog.DebugWarn("[SFX] ApplyMirror: " + ex.Message); } } public static void PlayOneShotDelayed(string name, float delaySeconds, float volume = 1f) { try { if (delaySeconds <= 0f) { PlayOneShot(name, volume); } else { MelonCoroutines.Start(DelayedOneShot(name, delaySeconds, volume)); } } catch (Exception ex) { NDLog.DebugWarn("[SFX] PlayOneShotDelayed " + name + ": " + ex.Message); } } private static IEnumerator DelayedOneShot(string name, float delaySeconds, float volume) { yield return (object)new WaitForSeconds(delaySeconds); PlayOneShot(name, volume); } public static void StartLoop(string name, float volume = 1f) { StartLoopScoped(name, volume, playLocal: true, mirror: true); } public static void StartLoopScoped(string name, float volume, bool playLocal, bool mirror) { try { if (playLocal && EnsureSources() && (!_loop.isPlaying || !(_loopName == name))) { AudioClip val = Get(name); if ((Object)(object)val != (Object)null) { _loop.clip = val; _loop.volume = volume * GroupVolume(name); _loopName = name; _loop.Play(); } } _mirrorLoopName = (mirror ? (name ?? "") : ""); } catch (Exception ex) { NDLog.DebugWarn("[SFX] StartLoopScoped " + name + ": " + ex.Message); } } public static void StopLoop() { try { if ((Object)(object)_loop != (Object)null && _loop.isPlaying) { _loop.Stop(); } } catch { } _loopName = null; _mirrorLoopName = ""; } public static void ResetForSceneReload() { StopLoop(); _appliedSeq = -1; } private static AudioClip Get(string name) { try { if (_clips.TryGetValue(name, out var value) && (Object)(object)value != (Object)null) { return value; } Assembly assembly = typeof(Sfx).Assembly; byte[] d; using (Stream stream = assembly.GetManifestResourceStream("Ndrangheta.assets.sfx." + name + ".wav")) { if (stream == null) { if (_warnedMissing.Add(name)) { NDLog.Warn("[SFX] embedded resource not found: " + name + ".wav"); } return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); d = memoryStream.ToArray(); } AudioClip val = ParseWav(d, name); if ((Object)(object)val != (Object)null) { _clips[name] = val; } return val; } catch (Exception ex) { NDLog.Warn("[SFX] Get " + name + ": " + ex.Message); return null; } } private static AudioClip ParseWav(byte[] d, string name) { try { if (d == null || d.Length < 44) { return null; } int num = BitConverter.ToInt16(d, 22); int num2 = BitConverter.ToInt32(d, 24); int num3 = BitConverter.ToInt16(d, 34); if (num < 1) { num = 1; } int i = 12; int num4 = -1; int num5 = 0; int num6; for (; i + 8 <= d.Length; i += 8 + num6 + (num6 & 1)) { string text = Encoding.ASCII.GetString(d, i, 4); num6 = BitConverter.ToInt32(d, i + 4); if (text == "data") { num4 = i + 8; num5 = num6; break; } } if (num4 < 0) { return null; } if (num4 + num5 > d.Length) { num5 = d.Length - num4; } int num7 = num3 / 8; if (num7 < 1) { return null; } int num8 = num5 / num7; float[] array = new float[num8]; switch (num3) { case 16: { for (int k = 0; k < num8; k++) { array[k] = (float)BitConverter.ToInt16(d, num4 + k * 2) / 32768f; } break; } case 8: { for (int j = 0; j < num8; j++) { array[j] = (float)(d[num4 + j] - 128) / 128f; } break; } case 32: { for (int l = 0; l < num8; l++) { array[l] = (float)BitConverter.ToInt32(d, num4 + l * 4) / 2.1474836E+09f; } break; } default: if (_warnedMissing.Add(name)) { NDLog.Warn($"[SFX] {name}: unsupported bits={num3}"); } return null; } AudioClip val = AudioClip.Create(name, num8 / num, num, num2, false); val.SetData(array, 0); try { ((Object)val).hideFlags = (HideFlags)32; } catch { } NDLog.Debug($"[SFX] loaded '{name}' ({num}ch {num2}Hz {num3}bit, {num8 / num} samples)."); return val; } catch (Exception ex) { NDLog.Warn("[SFX] ParseWav " + name + ": " + ex.Message); return null; } } } public static class SuburbiaPositions { private static readonly Vector3 GazeboOffset = new Vector3(-1.8f, 0f, -1.2f); private static readonly Vector3 PavilionAnchor = new Vector3(94.2f, 4.3f, -129f); public const float SpawnYaw = -15f; public static Vector3 ResolveSpawnPosition(out string source) { //IL_0029: 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_0038: 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_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_003b: Unknown result type (might be due to invalid IL or missing references) if (TryResolveGazebo(out var pos)) { source = "Gazebo DeadDrop (Gazebo)"; return pos + GazeboOffset; } source = "Pavilion anchor (fallback)"; return PavilionAnchor + GazeboOffset; } public static bool TryResolveGazebo(out Vector3 pos) { //IL_0002: 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_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) pos = Vector3.zero; try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null || deadDrops.Count == 0) { return false; } string value = "Gazebo"; if (string.IsNullOrEmpty(value)) { return false; } for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val; try { val = deadDrops[i]; } catch { continue; } if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null)) { string text; try { text = val.DeadDropName; } catch { text = null; } if (!string.IsNullOrEmpty(text) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { pos = ((Component)val).transform.position; NDLog.Debug($"Gazebo DeadDrop resolved: '{text}' at ({pos.x:F1},{pos.y:F1},{pos.z:F1})"); return true; } } } } catch (Exception ex) { NDLog.DebugWarn("TryResolveGazebo: " + ex.Message); } return false; } } public static class TeleportMirror { public struct TpAction { public int Seq; public Vector3 Pos; public int Yaw; public byte Mode; public string Peer; } public const byte MODE_ALIGN_FEET = 0; public const byte MODE_SNAP_NAVMESH = 1; private static readonly Dictionary _byPeer = new Dictionary(); private static int _seq; private static readonly Dictionary _hostApplied = new Dictionary(); private static readonly Dictionary _clientApplied = new Dictionary(); private static bool _clientBaselined; public static void Request(Vector3 pos, float yaw, byte mode, string peer = "") { //IL_005a: 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_00a2: Unknown result type (might be due to invalid IL or missing references) try { if (SessionGate.IsAuthority) { _seq++; int num = (float.IsNaN(yaw) ? 9999 : Mathf.RoundToInt(yaw)); _byPeer[peer ?? ""] = new TpAction { Seq = _seq, Pos = pos, Yaw = num, Mode = mode, Peer = (peer ?? "") }; NDLog.Debug($"[TPMIRROR] request seq={_seq} pos={pos} yaw={num} mode={mode} peer='{peer}'."); } } catch (Exception ex) { NDLog.DebugWarn("TeleportMirror.Request: " + ex.Message); } } public static string Encode() { //IL_0076: 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_00b0: Unknown result type (might be due to invalid IL or missing references) try { if (_byPeer.Count == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(); bool flag = true; foreach (KeyValuePair item in _byPeer) { TpAction value = item.Value; if (!flag) { stringBuilder.Append('~'); } flag = false; stringBuilder.Append(value.Seq).Append(',').Append(F1(value.Pos.x)) .Append(',') .Append(F1(value.Pos.y)) .Append(',') .Append(F1(value.Pos.z)) .Append(',') .Append(value.Yaw) .Append(',') .Append(value.Mode) .Append(',') .Append(SafePeer(value.Peer)); } return stringBuilder.ToString(); } catch { return ""; } } public static List Decode(string s) { //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) List list = new List(); if (string.IsNullOrEmpty(s)) { return list; } try { string[] array = s.Split(new char[1] { '~' }); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { string[] array2 = text.Split(new char[1] { ',' }); if (array2.Length >= 6) { int.TryParse(array2[0], out var result); float num = PF(array2[1]); float num2 = PF(array2[2]); float num3 = PF(array2[3]); int.TryParse(array2[4], out var result2); int.TryParse(array2[5], out var result3); string peer = ((array2.Length > 6) ? array2[6] : ""); list.Add(new TpAction { Seq = result, Pos = new Vector3(num, num2, num3), Yaw = result2, Mode = (byte)result3, Peer = peer }); } } } } catch { } return list; } public static void TickLocalApply() { try { if (!SessionGate.IsAuthority || _byPeer.Count == 0) { return; } foreach (KeyValuePair item in _byPeer) { TpAction value = item.Value; _hostApplied.TryGetValue(value.Peer, out var value2); if (value.Seq > value2) { _hostApplied[value.Peer] = value.Seq; if (PeerMatchesLocal(value.Peer)) { Apply(value); } } } } catch (Exception ex) { NDLog.DebugWarn("TeleportMirror.TickLocalApply: " + ex.Message); } } public static void ClientApply(List actions) { try { if (SessionGate.IsAuthority || actions == null) { return; } if (!_clientBaselined) { for (int i = 0; i < actions.Count; i++) { _clientApplied[actions[i].Peer] = actions[i].Seq; } _clientBaselined = true; return; } for (int j = 0; j < actions.Count; j++) { TpAction a = actions[j]; _clientApplied.TryGetValue(a.Peer, out var value); if (a.Seq > value) { _clientApplied[a.Peer] = a.Seq; if (PeerMatchesLocal(a.Peer)) { Apply(a); } } } } catch (Exception ex) { NDLog.DebugWarn("TeleportMirror.ClientApply: " + ex.Message); } } private static bool PeerMatchesLocal(string peer) { try { bool isAuthority = SessionGate.IsAuthority; if (peer == "h") { return isAuthority; } if (peer == "c") { return !isAuthority && TerritoryHandover.IsBossForLocalPeer; } return TerritoryHandover.IsBossForLocalPeer; } catch { return false; } } private static void Apply(TpAction a) { //IL_003a: 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) try { float num = ((a.Yaw >= 9999) ? float.NaN : ((float)a.Yaw)); NDLog.Debug($"[TPMIRROR] APPLY seq={a.Seq} pos={a.Pos} mode={a.Mode} peer='{a.Peer}' (local boss={TerritoryHandover.IsBossForLocalPeer}, auth={SessionGate.IsAuthority})."); ExitLocalVehicle(); MobTeleport.Fade(a.Pos, a.Mode == 1, num); } catch (Exception ex) { NDLog.DebugWarn("TeleportMirror.Apply: " + ex.Message); } } public static void ExitLocalVehicle() { try { Player local = Player.Local; if ((Object)(object)local == (Object)null) { return; } NetworkObject currentVehicle = local.CurrentVehicle; if (!((Object)(object)currentVehicle == (Object)null)) { LandVehicle component = ((Component)currentVehicle).GetComponent(); if ((Object)(object)component != (Object)null) { component.ExitVehicle(); NDLog.Debug("[TPMIRROR] exited local vehicle."); } } } catch (Exception ex) { NDLog.DebugWarn("TeleportMirror.ExitLocalVehicle: " + ex.Message); } } public static void Reset() { _byPeer.Clear(); _hostApplied.Clear(); _clientApplied.Clear(); _clientBaselined = false; _seq = 0; } public static void ResetForSceneReload() { _byPeer.Clear(); _hostApplied.Clear(); _clientApplied.Clear(); _clientBaselined = false; } private static string F1(float v) { return v.ToString("F1", CultureInfo.InvariantCulture); } private static float PF(string s) { float result; return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out result) ? result : 0f; } private static string SafePeer(string p) { return string.IsNullOrEmpty(p) ? "" : p.Replace("~", "").Replace(",", "").Replace("|", ""); } } internal static class TerritoryHandover { public const int CONTRATTI_FOR_HANDOVER = 5; public static bool HandoverActive { get; private set; } public static bool IsBossForLocalPeer { get { try { if (SessionGate.IsAuthority) { return HandoverActive; } return QuestNetSync.RemoteHandover; } catch { return HandoverActive; } } } public static void ResetForSceneReload() { } public static void LoadState(bool active) { HandoverActive = active; NDLog.Debug($"TerritoryHandover loaded: active={active}"); } public static void OnContrattoCompleted(int contrattiCount) { if (HandoverActive || contrattiCount < 5) { return; } try { HandoverActive = true; DonMessaging.SendDon("Cinque contratti, fratello. The 'Ndrina sees you. From here on you don't take orders from the streets — you give them. Hyland Point is your playground. My made-man (call him Lucky) takes care of the wet work when you point. Open the chat: famiglia run for the regular cut, or pick a target yourself and Lucky will make it happen. Capito?"); NDLog.Info($"Handover triggered after {contrattiCount} contratti."); LuckyChatController.OpenMainMenu(); } catch (Exception ex) { NDLog.Warn("OnContrattoCompleted/Handover SMS failed: " + ex.Message); } } public static void ForceReset() { HandoverActive = false; } } internal static class TortureManager { internal sealed class OpScene { public RapimentoManager.Variant Variant; public string OpLabel; public Vector3 DropZonePos; public Vector3 ReturnPos; public float ReturnYaw = float.NaN; public Vector3 VictimPos; public Vector3 PlayerPos; public bool HasSceneVan; public Vector3 SceneVanPos; public VehicleColor VanColor; public bool ExplicitGuards; public Vector3 Guard1Pos; public float Guard1Yaw; public Vector3 Guard2Pos; public float Guard2Yaw; public string[] WeaponItemIds; public string[] WeaponPrefabs; public string PickupPrompt; public string Popup; public string Hud; public bool ArmsUp; public bool KillToWin; public float TimeLimit; public int Reward; public int OfficerBonus; public int BenzieDealerBonus; public int BenzieGoonBonus; public string BeginSfx; public string SmsBegin; public string SmsDownEvent; public string SmsSuccess; } internal enum BonusKind { None, Officer, BenzieDealer, BenzieGoon } private static readonly Vector3 WAREHOUSE_DROP = new Vector3(-19.75f, -4.95f, 173.8f); internal static readonly OpScene Torture = new OpScene { Variant = RapimentoManager.Variant.Tortura, OpLabel = "Interrogation", DropZonePos = new Vector3(144.06f, 0.06f, 5.84f), ReturnPos = new Vector3(-19.75f, -4.95f, 173.8f), VictimPos = new Vector3(158.08f, 0.14f, 22.36f), PlayerPos = new Vector3(153.32f, 0.08f, 20.18f), HasSceneVan = true, SceneVanPos = new Vector3(149.3f, 0.06f, 14.58f), VanColor = (VehicleColor)0, ExplicitGuards = false, WeaponItemIds = new string[1] { "baseballbat" }, WeaponPrefabs = new string[2] { "Avatar/Equippables/BaseballBat", "Avatar/Equippables/Baseballbat" }, PickupPrompt = "Pick up the bat", Popup = "

Interrogation

\nGrab the bat off the ground and put the mark on the floor — keep hitting until they're knocked out cold.", Hud = "INTERROGATION — beat the mark until they're out cold", ArmsUp = false, KillToWin = false, TimeLimit = 60f, Reward = 18000, OfficerBonus = 0, SmsBegin = "The mark's tied up and waiting, boss. There's a bat on the ground — put the work in and don't let up until they're out cold.", SmsDownEvent = "Out cold, boss — they got the message. Sit tight a second, then we're gone.", SmsSuccess = "Good work, boss. Your cut's handled." }; internal static readonly OpScene Execution = new OpScene { Variant = RapimentoManager.Variant.Esecuzione, OpLabel = "Execution", DropZonePos = new Vector3(4.91f, 0.25f, -112.48f), ReturnPos = new Vector3(-12.7f, 0.14f, -48.15f), ReturnYaw = 0f, VictimPos = new Vector3(-17.11f, 3.98f, -165.69f), PlayerPos = new Vector3(-16.82f, 4.69f, -161.12f), HasSceneVan = false, SceneVanPos = Vector3.zero, VanColor = (VehicleColor)11, ExplicitGuards = true, Guard1Pos = new Vector3(-13.21f, 4.09f, -162.5f), Guard1Yaw = 225f, Guard2Pos = new Vector3(-18.44f, 4.72f, -161.47f), Guard2Yaw = 157.5f, WeaponItemIds = new string[4] { "goldenm1911", "m1911", "revolver", "pistol" }, WeaponPrefabs = new string[3] { "Avatar/Equippables/GoldenM1911", "Avatar/Equippables/M1911", "Avatar/Equippables/Revolver" }, PickupPrompt = "Pick up the pistol", Popup = "

Execution

\nThere's a gold piece on the ground. Pick it up and finish this like a boss — put them down for good.", Hud = "EXECUTION — finish it like a boss", ArmsUp = true, KillToWin = true, TimeLimit = 20f, Reward = 20000, OfficerBonus = 10000, BenzieDealerBonus = 10000, BenzieGoonBonus = 7500, BeginSfx = "kill-you", SmsBegin = "They're on their knees, boss. The gold piece is on the ground — make it clean, make it count.", SmsDownEvent = "It's done, boss. Give it a second.", SmsSuccess = "Like a boss. Your cut's handled — and then some." }; private const float SAFETY_TIMEOUT = 300f; private const float BONUS_BANNER_SECS = 6f; private const float KO_DELAY = 5f; private const float KO_CONFIRM = 0.6f; private const float GUARD_SIDE = 1.4f; private const float RELOCK_DRIFT = 0.5f; private const float EMOTE_REASSERT = 3f; private const float SCARED_DURATION = 6f; private static bool _active; private static OpScene _scene; private static NPC _victim; private static bool _victimIsOfficer; private static PoliceOfficer _victimOfficer; private static BonusKind _bonusKind; private static int _bonusAmount; private static float _bonusBannerLeft; private static string _bonusBannerHeadline; private static string _bonusBannerAmount; private static Vector3 _anchor; private static Vector3 _returnPos; private static float _returnYaw = float.NaN; private static string _anchorWho; private static bool _hostRode; private static int _sceneBeginSeq; private static int _sceneEndSeq; private static float _timeLeft; private static float _emoteCd; private static bool _koReached; private static float _koDelayLeft; private static float _koHeldFor; private static bool _winArmed; private static ItemDefinition _weaponDef; private static bool _guardsUp; private static Vector3 _guardLeftPos; private static Vector3 _guardRightPos; private static float _guardLeftYaw; private static float _guardRightYaw; private static GameObject _bat; private static LandVehicle _van; private static string _vanGuid; private static VehicleLights _vanLights; private static float _vanLightCd; private static float _officerReassertCd; private static GUIStyle _hudStyle; private static GUIStyle _timerStyle; private static bool _isRival; private static bool _victimIsBenzie; private static bool _informantExtracted; private static bool _talkCycleDone; private static GameObject _talkProp; private static bool _miniActive; private static float _miniMarker; private static int _miniDir = 1; private static float _miniMult = 1f; private const float _miniCenter = 0.5f; private static string _miniFeedback; private static float _miniFeedbackLeft; private static readonly Random _dealRng = new Random(); private static int _clientBeginApplied = -1; private static int _clientEndApplied = -1; private static bool _clientGuardsUp; private static GameObject _clientWeapon; private static bool _clientWeaponTaken; private static readonly Color GOLD = new Color(0.83f, 0.69f, 0.22f, 0.95f); private static readonly Color RED = new Color(0.92f, 0.26f, 0.22f, 1f); private const float BANNER_Y = 72f; private const float TIMER_Y = 112f; private static readonly string[] DealPlaces = new string[7] { "the docks", "the old cannery", "the trainyard", "the motel lot", "the Westville underpass", "the marina", "the construction site" }; private static readonly string[] DealDays = new string[7] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; private static readonly string[] DealTimes = new string[5] { "midnight", "2 a.m.", "just after dark", "dawn", "late tonight" }; private static readonly Quaternion WEAPON_LIE_FLAT = Quaternion.Euler(90f, 0f, 0f); public static bool IsActive => _active; public static bool SceneActive => _active; public static Vector3 ScenePlayerPos => (_scene != null) ? _scene.PlayerPos : Vector3.zero; public static Vector3 SceneReturnPos => _returnPos; public static int SceneReturnYawInt => float.IsNaN(_returnYaw) ? 9999 : Mathf.RoundToInt(_returnYaw); public static int SceneBeginSeq => _sceneBeginSeq; public static int SceneEndSeq => _sceneEndSeq; public static int SceneTimeLeftInt => (_active && !_koReached) ? Mathf.CeilToInt(Mathf.Max(0f, _timeLeft)) : 0; public static bool SceneKoReached => _active && _koReached; internal static OpScene SceneFor(RapimentoManager.Variant v) { return v switch { RapimentoManager.Variant.Tortura => Torture, RapimentoManager.Variant.Esecuzione => Execution, _ => null, }; } public static bool ClientSceneText(int variant, bool koReached, out string title, out string objective) { title = "Operation"; objective = "Handle the mark."; try { OpScene opScene = SceneFor((RapimentoManager.Variant)variant); if (opScene == null) { return false; } title = opScene.OpLabel; objective = (koReached ? (opScene.OpLabel.ToUpper() + " — done, pulling out…") : opScene.Hud); return true; } catch { return false; } } public static void ClientSceneTick(Vector3 scenePlayerPos, Vector3 sceneReturnPos, int returnYaw, int beginSeq, int endSeq) { //IL_00e5: 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_00f7: 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) try { if (SessionGate.IsAuthority || !QuestNetSync.HasRemoteState) { return; } if (_clientBeginApplied < 0 || !TerritoryHandover.IsBossForLocalPeer) { _clientBeginApplied = beginSeq; _clientEndApplied = endSeq; return; } if (beginSeq > _clientBeginApplied) { _clientBeginApplied = beginSeq; if (((Vector3)(ref scenePlayerPos)).sqrMagnitude > 1f) { NDLog.Debug($"[TORTURA] client teleporting INTO scene @ {scenePlayerPos}."); try { MobTeleport.Fade(scenePlayerPos, false, float.NaN); } catch { } } } if (endSeq <= _clientEndApplied) { return; } _clientEndApplied = endSeq; if (!(((Vector3)(ref sceneReturnPos)).sqrMagnitude > 1f)) { return; } float num = ((returnYaw >= 9999) ? float.NaN : ((float)returnYaw)); NDLog.Debug($"[TORTURA] client teleporting BACK @ {sceneReturnPos}."); try { MobTeleport.Fade(sceneReturnPos, true, num); } catch { } } catch (Exception ex) { NDLog.DebugWarn("TortureManager.ClientSceneTick: " + ex.Message); } } public static void ClientGuardTick() { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: 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_017e: 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_018e: 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_0197: 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_01a1: 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_0151: 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_01b5: Unknown result type (might be due to invalid IL or missing references) try { if (SessionGate.IsAuthority) { return; } bool flag = QuestNetSync.RemoteSceneActive && TerritoryHandover.IsBossForLocalPeer; if (flag && (Object)(object)_clientWeapon == (Object)null && !_clientWeaponTaken) { OpScene opScene = SceneFor((RapimentoManager.Variant)QuestNetSync.RemoteOpVariant); if (opScene != null) { BuildClientWeapon(opScene); } } else if (!flag && ((Object)(object)_clientWeapon != (Object)null || _clientWeaponTaken)) { try { if ((Object)(object)_clientWeapon != (Object)null) { Object.Destroy((Object)(object)_clientWeapon); } } catch { } _clientWeapon = null; _clientWeaponTaken = false; } if (flag) { OpScene opScene2 = SceneFor((RapimentoManager.Variant)QuestNetSync.RemoteOpVariant); if (opScene2 == null) { return; } Vector3 target; float num; Vector3 target2; float faceYaw; if (opScene2.ExplicitGuards) { target = opScene2.Guard1Pos; num = opScene2.Guard1Yaw; target2 = opScene2.Guard2Pos; faceYaw = opScene2.Guard2Yaw; } else { Vector3 victimPos = opScene2.VictimPos; Vector3 val = opScene2.PlayerPos - victimPos; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = Vector3.Cross(Vector3.up, val); target = victimPos - val2 * 1.4f; num = FaceYaw(victimPos, opScene2.PlayerPos); target2 = victimPos + val2 * 1.4f; faceYaw = num; } GuardNPC.ClientWalkTo(7, target, num, faceWhenArrived: true); GuardNPC.ClientWalkTo(8, target2, faceYaw, faceWhenArrived: true); _clientGuardsUp = true; } else if (_clientGuardsUp) { _clientGuardsUp = false; GuardNPC.ClientPark(7); GuardNPC.ClientPark(8); } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] ClientGuardTick: " + ex.Message); } } private static void BuildClientWeapon(OpScene scene) { //IL_0003: 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_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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_002f: 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_0045: Expected O, but got Unknown //IL_004b: 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_0056: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0201: 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_0159: 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) try { Vector3 val = NavSnap((scene.PlayerPos + scene.VictimPos) * 0.5f, 3f); float num = FaceYaw(scene.PlayerPos, scene.VictimPos); GameObject val2 = new GameObject("Ndrangheta_OpWeapon_Client"); val2.transform.position = val + Vector3.up * 0.06f; val2.transform.rotation = Quaternion.Euler(0f, num, 0f); _clientWeapon = val2; ItemDefinition def = null; if (scene.WeaponItemIds != null) { string[] weaponItemIds = scene.WeaponItemIds; foreach (string text in weaponItemIds) { try { ItemDefinition item = Registry.GetItem(text); if ((Object)(object)item != (Object)null) { def = item; break; } } catch { } } } bool flag = false; GameObject val3 = ModelPrefabFromDef(def); if ((Object)(object)val3 != (Object)null) { GameObject val4 = null; try { val4 = Object.Instantiate(val3); StripModel(val4); ActivateRenderers(val4); if (HasRenderer(val4)) { val4.transform.SetParent(val2.transform, false); val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = WEAPON_LIE_FLAT; val4.transform.localScale = Vector3.one; flag = true; } else { Object.Destroy((Object)(object)val4); } } catch { if ((Object)(object)val4 != (Object)null) { try { Object.Destroy((Object)(object)val4); } catch { } } } } if (!flag) { GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)3); val5.transform.SetParent(val2.transform, false); val5.transform.localPosition = Vector3.zero; val5.transform.localScale = new Vector3(0.07f, 0.07f, 0.85f); try { Collider component = val5.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } catch { } try { PropVisuals.Apply(val5, new Color(0.45f, 0.3f, 0.16f)); } catch { } } try { val2.layer = LayerMask.NameToLayer("Default"); } catch { } try { BoxCollider val6 = val2.AddComponent(); val6.center = Vector3.zero; val6.size = new Vector3(0.2f, 0.2f, 0.95f); } catch { } try { InteractableObject val7 = val2.AddComponent(); val7.SetMessage(scene.PickupPrompt); val7.SetInteractionType((EInteractionType)0); val7.SetInteractableState((EInteractableState)0); val7.MaxInteractionRange = 3f; val7.RequiresUniqueClick = true; val7.Priority = 1; val7.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)OnClientWeaponPickup)); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] client weapon interactable: " + ex.Message); } NDLog.Debug($"[TORTURA] client weapon built (real-model={flag}, pickup wired)."); } catch (Exception ex2) { NDLog.DebugWarn("[TORTURA] BuildClientWeapon: " + ex2.Message); } } private static void OnClientWeaponPickup() { try { PlayerInventory instance = PlayerSingleton.Instance; if ((Object)(object)instance == (Object)null) { DestroyClientWeapon(); return; } OpScene opScene = SceneFor((RapimentoManager.Variant)QuestNetSync.RemoteOpVariant); if (opScene == null) { DestroyClientWeapon(); return; } ItemDefinition val = null; if (opScene.WeaponItemIds != null) { string[] weaponItemIds = opScene.WeaponItemIds; foreach (string text in weaponItemIds) { try { ItemDefinition item = Registry.GetItem(text); if ((Object)(object)item != (Object)null) { val = item; break; } } catch { } } } if ((Object)(object)val == (Object)null) { NDLog.DebugWarn("[TORTURA] client weapon item not in registry."); DestroyClientWeapon(); return; } ItemInstance val2 = null; try { val2 = val.GetDefaultInstance(1); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] client weapon instance: " + ex.Message); } if (val2 == null) { DestroyClientWeapon(); return; } bool flag = true; try { flag = instance.CanItemFitInInventory(val2, 1); } catch { } if (!flag) { NDLog.Debug("[TORTURA] client inventory full — weapon stays on the ground."); return; } try { instance.AddItemToInventory(val2); } catch (Exception ex2) { NDLog.DebugWarn("[TORTURA] client weapon add: " + ex2.Message); } NDLog.Debug("[TORTURA] client weapon picked up."); DestroyClientWeapon(); } catch (Exception ex3) { NDLog.DebugWarn("[TORTURA] OnClientWeaponPickup: " + ex3.Message); } } private static void DestroyClientWeapon() { try { if ((Object)(object)_clientWeapon != (Object)null) { Object.Destroy((Object)(object)_clientWeapon); } } catch { } _clientWeapon = null; _clientWeaponTaken = true; } internal static void Begin(NPC victim, Vector3 returnPos, RapimentoManager.Variant variant, string anchorWho = null, bool hostRode = false) { //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_033e: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_0368: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority) { return; } _anchorWho = anchorWho; _hostRode = hostRode; OpScene opScene = SceneFor(variant); if (opScene == null) { NDLog.Warn($"[TORTURA] no scene for variant {variant}."); return; } if ((Object)(object)victim == (Object)null) { NDLog.Warn("[TORTURA] Begin with no victim — aborted."); return; } if (_active) { NDLog.Warn("[TORTURA] already running — Begin ignored."); return; } _scene = opScene; _victim = victim; _returnPos = ((opScene.ReturnPos != Vector3.zero) ? opScene.ReturnPos : returnPos); _returnYaw = opScene.ReturnYaw; _timeLeft = ((opScene.TimeLimit > 0f) ? opScene.TimeLimit : 300f); _emoteCd = 0f; _vanLightCd = 0f; _officerReassertCd = 0f; _koReached = false; _koDelayLeft = 0f; _koHeldFor = 0f; _winArmed = false; _weaponDef = null; _isRival = false; _informantExtracted = false; _talkCycleDone = false; _miniActive = false; _miniFeedbackLeft = 0f; _miniFeedback = null; _bonusKind = BonusKind.None; _bonusAmount = 0; _bonusBannerLeft = 0f; _bonusBannerHeadline = null; _bonusBannerAmount = null; _victimOfficer = ResolveOfficer(victim); _victimIsOfficer = (Object)(object)_victimOfficer != (Object)null; ClassifyBonus(victim); _isRival = variant == RapimentoManager.Variant.Tortura; _victimIsBenzie = _bonusKind == BonusKind.BenzieDealer || _bonusKind == BonusKind.BenzieGoon; if ((Object)(object)_victimOfficer != (Object)null) { try { _victimOfficer.AutoDeactivate = false; } catch { } try { _victimOfficer.Activate(); } catch { } try { ((NPC)_victimOfficer).SetVisible(true, false); } catch { } try { _victimOfficer.IgnorePlayers = true; } catch { } try { SuppressOfficerAwareness(_victimOfficer); } catch { } } try { if ((Object)(object)((Component)victim).gameObject != (Object)null && !((Component)victim).gameObject.activeSelf) { ((Component)victim).gameObject.SetActive(true); } } catch { } try { victim.SetVisible(true, true); } catch { } EnsureConscious(victim); _anchor = NavSnap(opScene.VictimPos, 2f); float num = FaceYaw(_anchor, opScene.PlayerPos); WarpNpc(victim, _anchor); try { ((Component)victim).transform.rotation = Quaternion.Euler(0f, num, 0f); } catch { } FreezeAt(victim); ApplyPacifism(victim); AssertScared(victim); SpawnVan(); SpawnGuards(); SpawnWeapon(); if (_isRival) { SpawnTalkProp(); } float yaw = FaceYaw(opScene.PlayerPos, _anchor); string text = (string.IsNullOrEmpty(_anchorWho) ? "h" : "c"); TeleportMirror.Request(opScene.PlayerPos, yaw, 0, text); if (text == "c" && _hostRode) { TeleportMirror.Request(opScene.PlayerPos, yaw, 0, "h"); } if (!string.IsNullOrEmpty(opScene.BeginSfx)) { try { Sfx.PlayOneShot(opScene.BeginSfx); } catch { } } _active = true; _sceneBeginSeq++; try { Sfx.StartLoop("heartbeat"); } catch { } DonMessaging.SendDon(opScene.SmsBegin); if (_isRival) { if (_victimIsBenzie) { DonMessaging.SendDon("This one's a Benzie, boss — work them right and they'll give up their next deal. Walk up and press E to make them talk; time it on the green."); } else { DonMessaging.SendDon("Make them talk, boss — the street needs to know we don't get crossed. Walk up and press E; time it on the green."); } } NDLog.Info($"[TORTURA] {opScene.OpLabel} begun — victim @ {_anchor} (officer={_victimIsOfficer}, rival={_isRival}, killToWin={opScene.KillToWin})."); } catch (Exception ex) { NDLog.Warn("[TORTURA] Begin: " + ex.Message); try { Cleanup(restoreVictim: true, teleportBack: true); } catch { } } } public static void Tick(float dt) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) if (_bonusBannerLeft > 0f) { _bonusBannerLeft -= dt; if (_bonusBannerLeft <= 0f) { _bonusBannerLeft = 0f; _bonusBannerHeadline = null; _bonusBannerAmount = null; } } if (_miniFeedbackLeft > 0f) { _miniFeedbackLeft -= dt; if (_miniFeedbackLeft <= 0f) { _miniFeedbackLeft = 0f; _miniFeedback = null; } } if (!_active) { return; } if (!SessionGate.IsAuthority) { ForceDrop(); return; } if (_miniActive) { TickMinigame(dt); } if (_guardsUp) { try { GuardNPC.HoldPost(7, _guardLeftPos, _guardLeftYaw); } catch { } try { GuardNPC.HoldPost(8, _guardRightPos, _guardRightYaw); } catch { } } if (_scene != null && _scene.HasSceneVan) { _vanLightCd -= dt; if (_vanLightCd <= 0f) { _vanLightCd = 2f; ReassertHeadlights(); } } if ((Object)(object)_victimOfficer != (Object)null) { _officerReassertCd -= dt; if (_officerReassertCd <= 0f) { _officerReassertCd = 0.5f; try { _victimOfficer.AutoDeactivate = false; } catch { } try { ((NPC)_victimOfficer).SetVisible(true, false); } catch { } try { _victimOfficer.IgnorePlayers = true; } catch { } try { SuppressOfficerAwareness(_victimOfficer); } catch { } } } PoliceHeat.ClearLocal(); if (_koReached) { _koDelayLeft -= dt; if (_koDelayLeft <= 0f) { FinalizeSuccess(); } return; } NPC victim = _victim; if ((Object)(object)victim == (Object)null || (Object)(object)((Component)victim).gameObject == (Object)null) { EndFailure("we lost the mark"); return; } bool flag = false; bool flag2 = false; try { NPCHealth health = victim.Health; if ((Object)(object)health != (Object)null) { flag = health.IsDead; flag2 = health.IsKnockedOut; } } catch { } bool flag3 = false; try { Avatar avatar = victim.Avatar; if ((Object)(object)avatar != (Object)null) { flag3 = avatar.Ragdolled; } } catch { } if (flag2 || flag || flag3) { _talkCycleDone = false; } else if (_isRival && !_talkCycleDone && !_miniActive && (Object)(object)_talkProp == (Object)null) { SpawnTalkProp(); } if (!_winArmed) { if (!flag && !flag2) { _winArmed = true; } } else if (_scene.KillToWin) { if (flag) { OnWin(); return; } } else { if (flag2) { _koHeldFor += dt; } else { _koHeldFor = 0f; } if (_koHeldFor >= 0.6f) { OnWin(); return; } if (flag) { EndFailure("you killed them — keep 'em breathing next time"); return; } } float num = 0f; try { num = Vector3.Distance(((Component)victim).transform.position, _anchor); } catch { } if (num > 0.5f) { try { WarpNpc(victim, _anchor); } catch { } } FreezeAt(victim); ApplyPacifism(victim); _emoteCd -= dt; if (_emoteCd <= 0f) { _emoteCd = 3f; AssertScared(victim); } if (_scene.ArmsUp) { try { victim.SetAnimationBool("HandsUp", true); } catch { } } _timeLeft -= dt; if (_timeLeft <= 0f) { EndFailure("they held out — we ran out of time"); } } public static void OnGUI() { //IL_0076: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_025f: 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_01e4: 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) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) try { EnsureStyles(); float num = 660f; float x = ((float)Screen.width - num) * 0.5f; if (_active && _scene != null) { string text = (_koReached ? (_scene.OpLabel.ToUpper() + " — done, pulling out…") : _scene.Hud); DrawShadowed(text, x, 72f, num, 40f, _hudStyle, GOLD); if (!_koReached) { int num2 = Mathf.CeilToInt(Mathf.Max(0f, _timeLeft)); string text2 = $"{num2 / 60}:{num2 % 60:00}"; DrawShadowed(text2, x, 112f, num, 44f, _timerStyle, (num2 <= 5) ? RED : GOLD); } } else if (!SessionGate.IsAuthority && QuestNetSync.RemoteSceneActive && TerritoryHandover.IsBossForLocalPeer) { OpScene opScene = SceneFor((RapimentoManager.Variant)QuestNetSync.RemoteOpVariant); if (opScene != null) { bool remoteSceneKoReached = QuestNetSync.RemoteSceneKoReached; string text3 = (remoteSceneKoReached ? (opScene.OpLabel.ToUpper() + " — done, pulling out…") : opScene.Hud); if (!string.IsNullOrEmpty(text3)) { DrawShadowed(text3, x, 72f, num, 40f, _hudStyle, GOLD); } if (!remoteSceneKoReached) { int num3 = Mathf.Max(0, QuestNetSync.RemoteSceneTimeLeft); string text4 = $"{num3 / 60}:{num3 % 60:00}"; DrawShadowed(text4, x, 112f, num, 44f, _timerStyle, (num3 <= 5) ? RED : GOLD); } } } if (_bonusBannerLeft > 0f && !string.IsNullOrEmpty(_bonusBannerHeadline)) { DrawShadowed(_bonusBannerHeadline, x, 112f, num, 36f, _hudStyle, GOLD); if (!string.IsNullOrEmpty(_bonusBannerAmount)) { DrawShadowed(_bonusBannerAmount, x, 148f, num, 44f, _timerStyle, GOLD); } } if (_miniActive) { DrawMinigame(x, num); } else if (_miniFeedbackLeft > 0f && !string.IsNullOrEmpty(_miniFeedback)) { DrawShadowed(_miniFeedback, x, 182f, num, 28f, _hudStyle, GOLD); } } catch { } } private static void EnsureStyles() { //IL_0017: 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_0025: 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_003a: Expected O, but got Unknown //IL_0050: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown if (_hudStyle == null) { _hudStyle = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } if (_timerStyle == null) { _timerStyle = new GUIStyle(GUI.skin.label) { fontSize = 30, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } } private static void DrawShadowed(string text, float x, float y, float w, float h, GUIStyle style, Color fill) { //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_001b: 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_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.Label(new Rect(x + 2f, y + 2f, w, h), text, style); GUI.color = fill; GUI.Label(new Rect(x, y, w, h), text, style); GUI.color = color; } private static void OnWin() { _koReached = true; _koDelayLeft = 5f; try { Sfx.PlayOneShot("quest-effect", 0.8f); } catch { } DonMessaging.SendDon(_scene.SmsDownEvent); NDLog.Debug($"[TORTURA] {_scene.OpLabel} target down — holding {5f:0}s before extraction."); } private static void FinalizeSuccess() { OpScene scene = _scene; BonusKind bonusKind = _bonusKind; int bonusAmount = _bonusAmount; bool isRival = _isRival; bool victimIsBenzie = _victimIsBenzie; bool informantExtracted = _informantExtracted; string anchorWho = _anchorWho; Cleanup(restoreVictim: true, teleportBack: true); try { RapimentoMarkerQuest.CompleteAndClear(fanfare: true); } catch { } int num = scene.Reward + ((bonusAmount > 0) ? bonusAmount : 0); try { if (!string.IsNullOrEmpty(anchorWho)) { PizzoJobManager.EmitCoopPayoutExternal(num, "h", scene.OpLabel); } else { PayoutHelper.AddCash(num, scene.OpLabel); } } catch { } DonMessaging.SendDon(scene.SmsSuccess + BonusSmsTail(bonusKind, bonusAmount)); NDLog.Info($"[TORTURA] {scene.OpLabel} success — reward {num} paid (bonus {bonusKind}={bonusAmount})."); if (bonusAmount > 0 && bonusKind != BonusKind.None) { ShowBonusBanner(bonusKind, bonusAmount); } if (isRival) { GrantInformantOutcome(informantExtracted, victimIsBenzie); } try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static void GrantInformantOutcome(bool gotIntel, bool wasBenzie) { try { if (!gotIntel) { DonMessaging.SendDon("They passed out before they gave us anything solid, boss. Next time, lean on them proper — time it on the green."); } else if (wasBenzie) { FaidaState.RecordReveal(); RollDeal(out var place, out var time); DonMessaging.SendDon("Good job, boss — they spilled the beans. The Benzies are running a shipment at " + place + ", " + time + ". Let's take it."); try { GangBattleManager.Setup(place, time); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] GangBattle setup: " + ex.Message); } NDLog.Debug($"[TORTURA] informant intel extracted — deal '{place}' {time}; fear={FearState.Points}."); } else { DonMessaging.SendDon("That broke them, boss — word's out on the street we don't get crossed. Your name carries weight now."); NDLog.Debug($"[TORTURA] interrogation accurate (non-benzie victim) — fear={FearState.Points}."); } } catch (Exception ex2) { NDLog.DebugWarn("[TORTURA] GrantInformantOutcome: " + ex2.Message); } } private static void RollDeal(out string place, out string time) { place = DealPlaces[_dealRng.Next(DealPlaces.Length)]; string text = DealTimes[_dealRng.Next(DealTimes.Length)]; string text2 = DealDays[_dealRng.Next(DealDays.Length)]; time = text + " on " + text2; } private static void ClassifyBonus(NPC victim) { _bonusKind = ClassifyKind(victim); _bonusAmount = BonusAmountFor(_scene, _bonusKind); NDLog.Debug($"[TORTURA] victim bonus class = {_bonusKind} (amount {_bonusAmount})."); } private static BonusKind ClassifyKind(NPC victim) { if ((Object)(object)victim == (Object)null) { return BonusKind.None; } if ((Object)(object)_victimOfficer != (Object)null) { return BonusKind.Officer; } try { if ((Object)(object)GameCompat.Cast((Object)(object)victim) != (Object)null) { return BonusKind.BenzieDealer; } } catch { } try { CartelGoon val = GameCompat.Cast((Object)(object)victim); if ((Object)(object)val != (Object)null && IsGoonSpawnedSafe(val)) { return BonusKind.BenzieGoon; } } catch { } return BonusKind.None; } private static int BonusAmountFor(OpScene s, BonusKind k) { if (s == null) { return 0; } return k switch { BonusKind.Officer => Mathf.Max(0, s.OfficerBonus), BonusKind.BenzieDealer => Mathf.Max(0, s.BenzieDealerBonus), BonusKind.BenzieGoon => Mathf.Max(0, s.BenzieGoonBonus), _ => 0, }; } private static bool IsGoonSpawnedSafe(CartelGoon g) { try { return g.IsGoonSpawned; } catch { return false; } } private static void ShowBonusBanner(BonusKind kind, int amount) { _bonusBannerHeadline = BonusHeadline(kind); _bonusBannerAmount = "BONUS +$" + amount.ToString("N0", CultureInfo.InvariantCulture); _bonusBannerLeft = 6f; } private static string BonusHeadline(BonusKind kind) { return kind switch { BonusKind.Officer => "A badge in the dirt — the family pays for that.", BonusKind.BenzieDealer => "One of the Benzies' earners, off the board.", BonusKind.BenzieGoon => "A Benzies soldier won't be missed.", _ => "", }; } private static string BonusSmsTail(BonusKind kind, int amount) { if (amount <= 0) { return ""; } return kind switch { BonusKind.Officer => " That badge was worth extra.", BonusKind.BenzieDealer => " And one of the Benzies' earners is off the board — that's worth extra.", BonusKind.BenzieGoon => " And a Benzies soldier off the board — a little extra in it for us.", _ => "", }; } private static void EndFailure(string reason) { string text = ((_scene != null) ? _scene.OpLabel : "Operation"); try { RapimentoMarkerQuest.CompleteAndClear(); } catch { } Cleanup(restoreVictim: true, teleportBack: true); DonMessaging.SendDon("Call it, boss — " + reason + ". No payout this time."); NDLog.Info("[TORTURA] " + text + " failed (" + reason + ")."); try { LuckyChatController.RefreshIfHandoverActive(); } catch { } } private static void ForceDrop() { try { Cleanup(restoreVictim: false, teleportBack: false); } catch { } } private static void Cleanup(bool restoreVictim, bool teleportBack) { //IL_0007: 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_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) NPC victim = _victim; Vector3 returnPos = _returnPos; _victim = null; _active = false; _timeLeft = 0f; _emoteCd = 0f; _vanLightCd = 0f; _koReached = false; _koDelayLeft = 0f; _winArmed = false; _weaponDef = null; _isRival = false; _informantExtracted = false; _miniActive = false; _miniFeedbackLeft = 0f; _miniFeedback = null; _bonusKind = BonusKind.None; _bonusAmount = 0; try { if ((Object)(object)_victimOfficer != (Object)null) { _victimOfficer.AutoDeactivate = true; } } catch { } try { if ((Object)(object)_victimOfficer != (Object)null) { _victimOfficer.IgnorePlayers = false; } } catch { } try { if ((Object)(object)_victimOfficer != (Object)null) { NPCAwareness awareness = ((NPC)_victimOfficer).Awareness; if ((Object)(object)awareness != (Object)null) { awareness.SetAwarenessActive(true); } } } catch { } _victimOfficer = null; try { Sfx.StopLoop(); } catch { } DestroyGuards(); DespawnVan(); DestroyBat(); DestroyTalkProp(); if ((Object)(object)victim != (Object)null && restoreVictim) { try { if ((Object)(object)((Component)victim).gameObject != (Object)null && !((Component)victim).gameObject.activeSelf) { ((Component)victim).gameObject.SetActive(true); } } catch { } try { victim.SetAnimationBool("HandsUp", false); } catch { } try { RestoreNpcMovement(victim); } catch { } } if (teleportBack) { string text = (string.IsNullOrEmpty(_anchorWho) ? "h" : "c"); TeleportMirror.Request(returnPos, _returnYaw, 1, text); if (text == "c" && _hostRode) { TeleportMirror.Request(returnPos, _returnYaw, 1, "h"); } _sceneEndSeq++; } _anchorWho = null; _hostRode = false; _scene = null; } public static void ResetForSceneReload() { //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) _active = false; _scene = null; _victim = null; _victimOfficer = null; _timeLeft = 0f; _emoteCd = 0f; _vanLightCd = 0f; _koReached = false; _koDelayLeft = 0f; _winArmed = false; _weaponDef = null; _isRival = false; _informantExtracted = false; _miniActive = false; _miniFeedbackLeft = 0f; _miniFeedback = null; _returnPos = Vector3.zero; _bonusKind = BonusKind.None; _bonusAmount = 0; _bonusBannerLeft = 0f; _bonusBannerHeadline = null; _bonusBannerAmount = null; try { RapimentoMarkerQuest.CompleteAndClear(); } catch { } try { DestroyGuards(); } catch { } try { DestroyBat(); } catch { } try { DestroyTalkProp(); } catch { } try { DespawnVan(); } catch { } try { if ((Object)(object)_clientWeapon != (Object)null) { Object.Destroy((Object)(object)_clientWeapon); _clientWeapon = null; } _clientWeaponTaken = false; } catch { } try { _clientGuardsUp = false; } catch { } try { Sfx.StopLoop(); } catch { } } private static void SpawnGuards() { //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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_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_003e: 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) //IL_00ab: 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_00b1: 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_00b8: 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: 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_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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) //IL_00ee: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) try { if (_scene.ExplicitGuards) { _guardLeftPos = NavSnap(_scene.Guard1Pos, 3f); _guardLeftYaw = _scene.Guard1Yaw; _guardRightPos = NavSnap(_scene.Guard2Pos, 3f); _guardRightYaw = _scene.Guard2Yaw; } else { Vector3 val = _scene.PlayerPos - _anchor; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = Vector3.Cross(Vector3.up, val); _guardLeftPos = NavSnap(_anchor - val2 * 1.4f, 3f); _guardRightPos = NavSnap(_anchor + val2 * 1.4f, 3f); _guardLeftYaw = FaceYaw(_anchor, _scene.PlayerPos); _guardRightYaw = _guardLeftYaw; } bool flag = GuardNPC.DeployStationary(7, _guardLeftPos, _guardLeftYaw, invincible: true); bool flag2 = GuardNPC.DeployStationary(8, _guardRightPos, _guardRightYaw, invincible: true); _guardsUp = flag || flag2; if (!_guardsUp) { NDLog.DebugWarn("[TORTURA] torture guards not deployed (slots 7/8 unresolved)."); } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] SpawnGuards: " + ex.Message); } } private static void DestroyGuards() { try { GuardNPC.SetInvincible(7, value: false); } catch { } try { GuardNPC.SetInvincible(8, value: false); } catch { } try { GuardNPC.Retire(7); } catch { } try { GuardNPC.Retire(8); } catch { } _guardsUp = false; } private static void SpawnVan() { //IL_0166: 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_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) //IL_00ca: 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_00ec: Unknown result type (might be due to invalid IL or missing references) try { if (_scene == null || !_scene.HasSceneVan) { return; } VehicleManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { NDLog.DebugWarn("[TORTURA] no VehicleManager — skipping scene van."); return; } string text = "Veeper"; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { text = "veeper"; if ((Object)(object)instance.GetVehiclePrefab(text) == (Object)null) { NDLog.DebugWarn("[TORTURA] van prefab missing."); return; } } float num = FaceYaw(_scene.SceneVanPos, _anchor); LandVehicle val = VehicleRegistry.CreateVehicle(text); if (val == null) { NDLog.DebugWarn("[TORTURA] CreateVehicle null."); return; } val.Spawn(_scene.SceneVanPos, Quaternion.Euler(0f, num, 0f)); try { val.ApplyColor(_scene.VanColor); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] van color: " + ex.Message); } try { val.IsPlayerOwned = false; } catch { } _van = val; try { _vanGuid = val.GUID; } catch { _vanGuid = null; } TrySetHeadlights(instance); NDLog.Debug($"[TORTURA] scene van '{text}' spawned @ {_scene.SceneVanPos} ({_scene.VanColor}, GUID={_vanGuid})."); } catch (Exception ex2) { NDLog.DebugWarn("[TORTURA] SpawnVan: " + ex2.Message); } } private static void TrySetHeadlights(VehicleManager vm) { try { if ((Object)(object)vm == (Object)null || string.IsNullOrEmpty(_vanGuid)) { return; } List allVehicles = vm.AllVehicles; if (allVehicles == null) { return; } for (int i = 0; i < allVehicles.Count; i++) { LandVehicle val = allVehicles[i]; if ((Object)(object)val == (Object)null) { continue; } string text = null; try { text = val.GUID.ToString(); } catch { } if (text != null && !(text != _vanGuid)) { VehicleLights component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { _vanLights = component; component.HeadlightsOn = true; } break; } } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] TrySetHeadlights: " + ex.Message); } } private static void ReassertHeadlights() { try { if ((Object)(object)_vanLights == (Object)null) { VehicleManager instance = NetworkSingleton.Instance; if ((Object)(object)instance != (Object)null) { TrySetHeadlights(instance); } return; } try { if (!_vanLights.HeadlightsOn) { _vanLights.HeadlightsOn = true; } } catch { _vanLights = null; } } catch { } } private static void DespawnVan() { try { if (_van != null && SessionGate.IsAuthority) { _van.DestroyVehichle(); } } catch { } _van = null; _vanLights = null; _vanGuid = null; } private static void SpawnWeapon() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //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_0020: 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) //IL_002f: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0063: 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_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_0093: 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_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: 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) try { Vector3 val = NavSnap((_scene.PlayerPos + _scene.VictimPos) * 0.5f, 3f); float num = FaceYaw(_scene.PlayerPos, _scene.VictimPos); _bat = new GameObject("Ndrangheta_OpWeapon"); _bat.transform.position = val + Vector3.up * 0.06f; _bat.transform.rotation = Quaternion.Euler(0f, num, 0f); try { _bat.layer = LayerMask.NameToLayer("Default"); } catch { } _weaponDef = ResolveWeaponDef(); bool flag = TryPlaceModel(ModelPrefabFromDef(_weaponDef)); if (!flag) { string[] weaponPrefabs = _scene.WeaponPrefabs; foreach (string path in weaponPrefabs) { GameObject val2 = null; try { val2 = LuckyWeaponVisual.LoadEquippablePrefab(path); } catch { } if ((Object)(object)val2 != (Object)null && TryPlaceModel(val2)) { flag = true; break; } } } if (!flag) { GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)3); val3.transform.SetParent(_bat.transform, false); val3.transform.localPosition = Vector3.zero; val3.transform.localScale = new Vector3(0.07f, 0.07f, 0.85f); try { PropVisuals.Apply(val3, new Color(0.45f, 0.3f, 0.16f)); } catch { } NDLog.DebugWarn("[TORTURA] weapon model unresolved — fallback cube."); } try { BoxCollider val4 = _bat.AddComponent(); val4.center = Vector3.zero; val4.size = new Vector3(0.2f, 0.2f, 0.95f); } catch { } InteractableObject val5 = _bat.AddComponent(); val5.SetMessage(_scene.PickupPrompt); val5.SetInteractionType((EInteractionType)0); val5.SetInteractableState((EInteractableState)0); val5.MaxInteractionRange = 3f; val5.RequiresUniqueClick = true; val5.Priority = 1; val5.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)OnWeaponPickup)); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] SpawnWeapon: " + ex.Message); } } private static ItemDefinition ResolveWeaponDef() { if (_scene == null) { return null; } string[] weaponItemIds = _scene.WeaponItemIds; foreach (string text in weaponItemIds) { try { ItemDefinition item = Registry.GetItem(text); if ((Object)(object)item != (Object)null) { return item; } } catch { } } return null; } private static GameObject ModelPrefabFromDef(ItemDefinition def) { try { Equippable val = def?.Equippable; return ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null; } catch { return null; } } private static bool TryPlaceModel(GameObject prefab) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) if ((Object)(object)prefab == (Object)null) { return false; } GameObject val = null; try { val = Object.Instantiate(prefab); StripModel(val); ActivateRenderers(val); if (!HasRenderer(val)) { NDLog.DebugWarn("[TORTURA] weapon prefab has no renderer — trying next/cube."); Object.Destroy((Object)(object)val); return false; } val.transform.SetParent(_bat.transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = WEAPON_LIE_FLAT; val.transform.localScale = Vector3.one; NDLog.Debug("[TORTURA] real weapon model placed (visible renderer)."); return true; } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] weapon model: " + ex.Message); if ((Object)(object)val != (Object)null) { try { Object.Destroy((Object)(object)val); } catch { } } return false; } } private static void ActivateRenderers(GameObject go) { try { Transform[] componentsInChildren = go.GetComponentsInChildren(true); if (componentsInChildren != null) { for (int i = 0; i < componentsInChildren.Length; i++) { try { if ((Object)(object)componentsInChildren[i] != (Object)null && !((Component)componentsInChildren[i]).gameObject.activeSelf) { ((Component)componentsInChildren[i]).gameObject.SetActive(true); } } catch { } } } MeshRenderer[] componentsInChildren2 = go.GetComponentsInChildren(true); if (componentsInChildren2 != null) { for (int j = 0; j < componentsInChildren2.Length; j++) { try { if ((Object)(object)componentsInChildren2[j] != (Object)null) { ((Renderer)componentsInChildren2[j]).enabled = true; } } catch { } } } SkinnedMeshRenderer[] componentsInChildren3 = go.GetComponentsInChildren(true); if (componentsInChildren3 == null) { return; } for (int k = 0; k < componentsInChildren3.Length; k++) { try { if ((Object)(object)componentsInChildren3[k] != (Object)null) { ((Renderer)componentsInChildren3[k]).enabled = true; } } catch { } } } catch { } } private static bool HasRenderer(GameObject go) { try { if ((Object)(object)go.GetComponentInChildren(true) != (Object)null) { return true; } if ((Object)(object)go.GetComponentInChildren(true) != (Object)null) { return true; } } catch { } return false; } private static void OnWeaponPickup() { try { PlayerInventory instance = PlayerSingleton.Instance; if ((Object)(object)instance == (Object)null) { DestroyBat(); return; } ItemDefinition val = (((Object)(object)_weaponDef != (Object)null) ? _weaponDef : ResolveWeaponDef()); if ((Object)(object)val == (Object)null) { NDLog.DebugWarn("[TORTURA] weapon item not in registry."); DestroyBat(); return; } ItemInstance val2 = null; try { val2 = val.GetDefaultInstance(1); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] weapon instance: " + ex.Message); } if (val2 == null) { DestroyBat(); return; } bool flag = true; try { flag = instance.CanItemFitInInventory(val2, 1); } catch { } if (!flag) { NDLog.Debug("[TORTURA] inventory full — weapon stays on the ground."); return; } try { instance.AddItemToInventory(val2); } catch (Exception ex2) { NDLog.DebugWarn("[TORTURA] weapon add: " + ex2.Message); } NDLog.Debug("[TORTURA] weapon picked up."); DestroyBat(); } catch (Exception ex3) { NDLog.DebugWarn("[TORTURA] OnWeaponPickup: " + ex3.Message); } } private static void StripModel(GameObject go) { try { MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren(true); if (componentsInChildren != null) { for (int i = 0; i < componentsInChildren.Length; i++) { try { if ((Object)(object)componentsInChildren[i] != (Object)null) { ((Behaviour)componentsInChildren[i]).enabled = false; } } catch { } } } Collider[] componentsInChildren2 = go.GetComponentsInChildren(true); if (componentsInChildren2 != null) { for (int j = 0; j < componentsInChildren2.Length; j++) { try { if ((Object)(object)componentsInChildren2[j] != (Object)null) { componentsInChildren2[j].enabled = false; } } catch { } } } Rigidbody[] componentsInChildren3 = go.GetComponentsInChildren(true); if (componentsInChildren3 == null) { return; } for (int k = 0; k < componentsInChildren3.Length; k++) { try { if ((Object)(object)componentsInChildren3[k] != (Object)null) { componentsInChildren3[k].isKinematic = true; componentsInChildren3[k].useGravity = false; } } catch { } } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] StripModel: " + ex.Message); } } private static void DestroyBat() { try { if ((Object)(object)_bat != (Object)null) { Object.Destroy((Object)(object)_bat); } } catch { } _bat = null; } private static void SpawnTalkProp() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_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_006a: 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) try { DestroyTalkProp(); _talkProp = new GameObject("Ndrangheta_TalkProp"); _talkProp.transform.position = _anchor + Vector3.up * 1f; try { _talkProp.layer = LayerMask.NameToLayer("Default"); } catch { } BoxCollider val = _talkProp.AddComponent(); val.center = Vector3.zero; val.size = new Vector3(1.4f, 2f, 1.4f); ((Collider)val).isTrigger = true; InteractableObject val2 = _talkProp.AddComponent(); val2.SetMessage("Make them talk"); val2.SetInteractionType((EInteractionType)0); val2.SetInteractableState((EInteractableState)0); val2.MaxInteractionRange = 3f; val2.RequiresUniqueClick = true; val2.Priority = 2; val2.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)OnTalkInteract)); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] SpawnTalkProp: " + ex.Message); } } private static void DestroyTalkProp() { try { if ((Object)(object)_talkProp != (Object)null) { Object.Destroy((Object)(object)_talkProp); } } catch { } _talkProp = null; } private static void OnTalkInteract() { try { if (!_active || !_isRival || _talkCycleDone || _miniActive || _koReached) { return; } NPC victim = _victim; if ((Object)(object)victim == (Object)null) { return; } bool flag = false; bool flag2 = false; try { NPCHealth health = victim.Health; if ((Object)(object)health != (Object)null) { flag = health.IsKnockedOut; flag2 = health.IsDead; } } catch { } if (!(flag || flag2)) { bool flag3 = false; try { flag3 = (Object)(object)victim.Avatar != (Object)null && victim.Avatar.Ragdolled; } catch { } if (!flag3) { _miniActive = true; _miniMarker = 0f; _miniDir = 1; _miniMult = 1f; _miniFeedback = null; _miniFeedbackLeft = 0f; } } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] OnTalkInteract: " + ex.Message); } } private static void TickMinigame(float dt) { _miniMult = Mathf.Clamp(_miniMult + dt / 20f, 0f, 2f); _miniMarker = Mathf.Clamp01(_miniMarker + (float)_miniDir * dt * _miniMult); if (_miniMarker >= 1f) { _miniDir = -1; } else if (_miniMarker <= 0f) { _miniDir = 1; } bool flag = false; try { flag = !GameInput.IsTyping && GameInput.GetButtonDown((ButtonCode)7); } catch { } if (flag) { LockMinigame(); } } private static void LockMinigame() { _miniActive = false; float num = 0.05f; try { num = FearState.GreenHalf; } catch { } if (Mathf.Abs(_miniMarker - 0.5f) <= num + 0.01f) { _talkCycleDone = true; bool flag = !_informantExtracted; _informantExtracted = true; FearState.AddPoint(); DestroyTalkProp(); _miniFeedback = "They cracked — they're talking."; _miniFeedbackLeft = 3f; try { Sfx.PlayOneShot("quest-effect", 0.55f); } catch { } DonMessaging.SendDon(flag ? "That broke them, boss — they're talking. Finish the job and we'll move on what they gave us." : "They keep talking, boss — every time they come to, they give up a little more."); NDLog.Debug($"[TORTURA] interrogation accurate — fear={FearState.Points} (firstIntel={flag})."); } else { _miniFeedback = "They clammed up — work them again (E)."; _miniFeedbackLeft = 2.5f; } } private static void DrawMinigame(float x, float w) { //IL_003a: 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_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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_0124: 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) float num = 420f; float num2 = 26f; float num3 = ((float)Screen.width - num) * 0.5f; float num4 = 182f; DrawShadowed("Make them talk — stop on the GREEN (SPACE)", x, num4 - 28f, w, 24f, _hudStyle, GOLD); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.65f); ImguiCompat.DrawTexture(new Rect(num3, num4, num, num2), Texture2D.whiteTexture); float num5 = 0.05f; try { num5 = FearState.GreenHalf; } catch { } float num6 = Mathf.Clamp01(0.5f - num5); float num7 = Mathf.Clamp01(0.5f + num5); GUI.color = new Color(0.2f, 0.8f, 0.25f, 0.85f); ImguiCompat.DrawTexture(new Rect(num3 + num6 * num, num4, (num7 - num6) * num, num2), Texture2D.whiteTexture); GUI.color = Color.white; ImguiCompat.DrawTexture(new Rect(num3 + Mathf.Clamp01(_miniMarker) * num - 2f, num4 - 4f, 4f, num2 + 8f), Texture2D.whiteTexture); GUI.color = color; } private static void FreezeAt(NPC npc) { try { if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.MoveSpeedMultiplier = 0f; } catch { } try { npc.Movement.MoveSpeedMultiplier = 0f; } catch { } try { npc.Movement.PauseMovement(); } catch { } } try { if ((Object)(object)npc.Behaviour != (Object)null) { ((Behaviour)npc.Behaviour).enabled = false; } } catch { } DisableSchedule(npc); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] FreezeAt: " + ex.Message); } } private static void ApplyPacifism(NPC npc) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) try { NPCResponses responses = npc.Responses; NPCResponses_Civilian val = (NPCResponses_Civilian)(object)((responses is NPCResponses_Civilian) ? responses : null); if ((Object)(object)val != (Object)null) { ((NPCResponses)val).npc.NPCData.Behaviour.CanCallPolice = false; val.OverrideThreatResponses = true; val.ThreatResponseOverride = (EAttackResponse)0; } try { npc.NPCData.Behaviour.DefaultAggression = 0f; } catch { } NPCBehaviour behaviour = npc.Behaviour; if (!((Object)(object)behaviour != (Object)null)) { return; } try { CallPoliceBehaviour callPoliceBehaviour = behaviour.CallPoliceBehaviour; if ((Object)(object)callPoliceBehaviour != (Object)null && ((Behaviour)callPoliceBehaviour).Enabled) { ((Behaviour)callPoliceBehaviour).Disable_Server(); } } catch { } try { FleeBehaviour fleeBehaviour = behaviour.FleeBehaviour; if ((Object)(object)fleeBehaviour != (Object)null && ((Behaviour)fleeBehaviour).Enabled) { ((Behaviour)fleeBehaviour).Disable_Server(); } } catch { } try { CoweringBehaviour coweringBehaviour = behaviour.CoweringBehaviour; if ((Object)(object)coweringBehaviour != (Object)null && ((Behaviour)coweringBehaviour).Enabled) { ((Behaviour)coweringBehaviour).Disable_Server(); } } catch { } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] pacifism: " + ex.Message); } } private static void AssertScared(NPC npc) { try { npc.Avatar.EmotionManager.AddEmotionOverride("Scared", "TorturaPanic", 6f, 10); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] scared-emote: " + ex.Message); } if (_scene != null && _scene.ArmsUp) { try { npc.SetAnimationBool("HandsUp", true); } catch { } } } private static void RestoreNpcMovement(NPC npc) { try { if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.ResumeMovement(); } catch { } try { npc.Movement.MoveSpeedMultiplier = 1f; } catch { } try { npc.Movement.MoveSpeedMultiplier = 1f; } catch { } } try { if ((Object)(object)npc.Behaviour != (Object)null) { ((Behaviour)npc.Behaviour).enabled = true; } } catch { } try { NPCResponses responses = npc.Responses; NPCResponses_Civilian val = (NPCResponses_Civilian)(object)((responses is NPCResponses_Civilian) ? responses : null); if ((Object)(object)val != (Object)null) { val.OverrideThreatResponses = false; ((NPCResponses)val).npc.NPCData.Behaviour.CanCallPolice = true; } } catch { } EnableSchedule(npc); } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] RestoreNpcMovement: " + ex.Message); } } private static void EnsureConscious(NPC npc) { try { NPCHealth health = npc.Health; if ((Object)(object)health == (Object)null) { return; } try { health.npc.NPCData.Health.Invincible = false; } catch { } try { health.npc.NPCData.Health.MaxHealth = 100f; } catch { } try { if (health.IsDead || health.IsKnockedOut) { health.Revive(); } } catch { } try { health.RestoreHealth(); } catch { } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] EnsureConscious: " + ex.Message); } } private static void SuppressOfficerAwareness(PoliceOfficer officer) { if ((Object)(object)officer == (Object)null) { return; } try { NPCAwareness awareness = ((NPC)officer).Awareness; if ((Object)(object)awareness != (Object)null) { try { awareness.SetAwarenessActive(false); } catch { } VisionCone visionCone = awareness.VisionCone; if ((Object)(object)visionCone != (Object)null) { try { visionCone.WorldspaceIconsEnabled = false; } catch { } try { visionCone.ClearEvents(); } catch { } } } VisionCone val = (((Object)(object)((Component)officer).gameObject != (Object)null) ? ((Component)officer).gameObject.GetComponentInChildren(true) : null); if ((Object)(object)val != (Object)null) { try { val.WorldspaceIconsEnabled = false; } catch { } try { val.ClearEvents(); return; } catch { return; } } } catch (Exception ex) { NDLog.DebugWarn("[TORTURA] SuppressOfficerAwareness: " + ex.Message); } } private static PoliceOfficer ResolveOfficer(NPC npc) { try { if ((Object)(object)npc == (Object)null || (Object)(object)((Component)npc).gameObject == (Object)null) { return null; } PoliceOfficer val = ((Component)npc).gameObject.GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)npc).gameObject.GetComponentInChildren(true); } if ((Object)(object)val != (Object)null) { return val; } List officers = PoliceOfficer.Officers; if (officers != null) { for (int i = 0; i < officers.Count; i++) { PoliceOfficer val2 = officers[i]; if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && GameCompat.SameInstance((object)((Component)val2).gameObject, (object)((Component)npc).gameObject)) { return val2; } } } } catch { } return null; } private static void WarpNpc(NPC npc, Vector3 pos) { //IL_0066: 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_0047: Unknown result type (might be due to invalid IL or missing references) try { NavMeshAgent component = ((Component)npc).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { component.Warp(pos); return; } if ((Object)(object)npc.Movement != (Object)null) { try { npc.Movement.Warp(pos); return; } catch { } } } catch { } try { ((Component)npc).transform.position = pos; } catch { } } private static Vector3 NavSnap(Vector3 pos, float radius) { //IL_0002: 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_0023: 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_0026: Unknown result type (might be due to invalid IL or missing references) try { NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(pos, ref val, radius, -1)) { return ((NavMeshHit)(ref val)).position; } } catch { } return pos; } private static float FaceYaw(Vector3 from, Vector3 to) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_002f: 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_0035: 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) Vector3 val = to - from; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { return 0f; } Quaternion val2 = Quaternion.LookRotation(val); return ((Quaternion)(ref val2)).eulerAngles.y; } private static void DisableSchedule(NPC npc) { try { NPCScheduleManager componentInChildren = ((Component)npc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { try { componentInChildren.DisableSchedule(); } catch { } ((Behaviour)componentInChildren).enabled = false; } } catch { } } private static void EnableSchedule(NPC npc) { try { NPCScheduleManager componentInChildren = ((Component)npc).gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = true; try { componentInChildren.EnableSchedule(); return; } catch { return; } } } catch { } } } internal static class VillaLocator { public const string TargetFirstName = "Michael"; public const string TargetLastName = "Boog"; private static NPCEnterableBuilding _building; private static string _buildingName; private static bool _probed; private static NPC _owner; private static float _ownerNextProbeAt; private static float _noAccessWarnMuteUntil = -999f; public static string BuildingName => _buildingName; public static void ResetForSceneReload() { _building = null; _probed = false; _owner = null; _ownerNextProbeAt = 0f; } public static bool TryGetOwner(out NPC npc) { npc = null; try { if ((Object)(object)_owner != (Object)null && (Object)(object)((Component)_owner).gameObject != (Object)null) { npc = _owner; return true; } } catch { _owner = null; } if (Time.time < _ownerNextProbeAt) { return false; } _ownerNextProbeAt = Time.time + 15f; _owner = FindBoog(); npc = _owner; return (Object)(object)npc != (Object)null; } public static void LoadSavedBuildingName(string name) { if (!string.IsNullOrEmpty(name)) { _buildingName = name; } } public static bool TryGetVilla(out NPCEnterableBuilding building) { //IL_011b: Unknown result type (might be due to invalid IL or missing references) building = null; try { if ((Object)(object)_building != (Object)null && (Object)(object)((Component)_building).gameObject != (Object)null) { building = _building; return true; } } catch { _building = null; } if (!string.IsNullOrEmpty(_buildingName)) { _building = FindBuildingByName(_buildingName); if ((Object)(object)_building != (Object)null) { building = _building; return true; } } if (_probed) { return false; } _probed = true; try { NPC val = FindBoog(); if ((Object)(object)val == (Object)null) { NDLog.Warn("[VILLA] NPC 'Michael Boog' not found in NPCRegistry."); return false; } NPCEnterableBuilding val2 = ResolveHomeBuilding(val); if ((Object)(object)val2 == (Object)null) { NDLog.Warn("[VILLA] no StayInBuilding event in the schedule — home cannot be resolved."); return false; } _building = val2; try { _buildingName = val2.BuildingName; } catch { } NDLog.Debug($"[VILLA] resolved: building='{_buildingName}' @ {((Component)val2).transform.position}."); building = _building; return true; } catch (Exception ex) { NDLog.Warn("[VILLA] TryGetVilla: " + ex.Message); return false; } } public static bool TryGetEntrance(out Vector3 pos, out float yaw) { //IL_0002: 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_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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0111: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_00f6: 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) pos = Vector3.zero; yaw = 0f; try { if (!TryGetVilla(out var building)) { return false; } Transform val = null; StaticDoor[] doors = building.Doors; if (doors != null) { for (int i = 0; i < doors.Length; i++) { if (!((Object)(object)val == (Object)null)) { break; } try { StaticDoor val2 = doors[i]; if ((Object)(object)val2 != (Object)null && (Object)(object)val2.AccessPoint != (Object)null) { val = val2.AccessPoint; } } catch { } } } Vector3 position = ((Component)building).transform.position; if ((Object)(object)val == (Object)null) { if (Time.time >= _noAccessWarnMuteUntil) { _noAccessWarnMuteUntil = Time.time + 30f; NDLog.Warn("[VILLA] building without a door AccessPoint — using building center."); } else { NDLog.DebugWarn("[VILLA] building without a door AccessPoint — using building center."); } pos = position; return true; } pos = val.position; Vector3 val3 = pos - position; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude < 0.04f) { try { val3 = val.forward; val3.y = 0f; } catch { } } if (((Vector3)(ref val3)).sqrMagnitude > 0.001f) { yaw = Mathf.Atan2(val3.x, val3.z) * 57.29578f; } return true; } catch (Exception ex) { NDLog.DebugWarn("[VILLA] TryGetEntrance: " + ex.Message); return false; } } public static void DisableKnockOnVilla() { try { if (!TryGetVilla(out var building)) { return; } StaticDoor[] doors = building.Doors; if (doors == null) { return; } for (int i = 0; i < doors.Length; i++) { try { if ((Object)(object)doors[i] != (Object)null) { doors[i].CanKnock = false; } } catch { } } } catch { } } public static void EnableKnockOnVilla() { try { if (!TryGetVilla(out var building)) { return; } StaticDoor[] doors = building.Doors; if (doors == null) { return; } for (int i = 0; i < doors.Length; i++) { try { if ((Object)(object)doors[i] != (Object)null) { doors[i].CanKnock = true; } } catch { } } } catch { } } private static NPC FindBoog() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) try { List nPCRegistry = NPCManager.NPCRegistry; if (nPCRegistry == null) { return null; } for (int i = 0; i < nPCRegistry.Count; i++) { NPC val; try { val = nPCRegistry[i]; } catch { continue; } if ((Object)(object)val == (Object)null) { continue; } string text = null; string text2 = null; try { text = val.FirstName; text2 = val.LastName; } catch { } if (string.IsNullOrEmpty(text) || !text.Trim().Equals("Michael", StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(text2) || !text2.Trim().Equals("Boog", StringComparison.OrdinalIgnoreCase)) { continue; } try { NDLog.Debug($"[VILLA] NPC found: '{text} {text2}' (ID='{val.ID}', Region={val.Region})."); } catch { } return val; } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] FindBoog: " + ex.Message); } return null; } private static NPCEnterableBuilding ResolveHomeBuilding(NPC npc) { try { NPCScheduleManager val = (((Object)(object)npc.Behaviour != (Object)null) ? npc.Behaviour.ScheduleManager : null); List list = (((Object)(object)val != (Object)null) ? val.ActionList : null); if (list == null) { return null; } NPCEnterableBuilding result = null; int num = -1; for (int i = 0; i < list.Count; i++) { try { NPCAction val2 = list[i]; if ((Object)(object)val2 == (Object)null) { continue; } NPCEvent_StayInBuilding val3 = GameCompat.Cast((Object)(object)val2); if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.Building == (Object)null)) { int num2 = 0; try { num2 = ((NPCEvent)val3).Duration; } catch { } NDLog.Debug($"[VILLA] schedule: StayInBuilding '{SafeBuildingName(val3.Building)}' start={SafeStart(val3)} dur={num2}."); if (num2 > num) { num = num2; result = val3.Building; } } } catch { } } return result; } catch (Exception ex) { NDLog.DebugWarn("[VILLA] ResolveHome: " + ex.Message); return null; } } private static NPCEnterableBuilding FindBuildingByName(string name) { try { NPCEnterableBuilding[] array = Object.FindObjectsOfType(true); if (array == null) { return null; } for (int i = 0; i < array.Length; i++) { try { NPCEnterableBuilding val = array[i]; if ((Object)(object)val != (Object)null && string.Equals(val.BuildingName, name, StringComparison.Ordinal)) { return val; } } catch { } } } catch { } return null; } private static string SafeBuildingName(NPCEnterableBuilding b) { try { return ((Object)(object)b != (Object)null) ? b.BuildingName : ""; } catch { return ""; } } private static string SafeStart(NPCEvent_StayInBuilding e) { try { return ((NPCAction)e).StartTime.ToString(); } catch { return "?"; } } } internal static class VillaProbe { internal struct Result { public bool HasInterior; public Vector3 InteriorPoint; public Vector3 DoorOutside; public float FloorY; public bool NavMeshOk; } private static Result _cached; private static bool _resolved; private static float _resolveWarnMuteUntil = -999f; public static void ResetForSceneReload() { _resolved = false; _cached = default(Result); } public static bool TryResolve(out Result r) { //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_0079: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00d3: 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_00e9: 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_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) //IL_011d: 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_014d: Unknown result type (might be due to invalid IL or missing references) if (_resolved) { r = _cached; return true; } r = default(Result); try { if (!VillaLocator.TryGetVilla(out var building) || (Object)(object)building == (Object)null || (Object)(object)((Component)building).transform == (Object)null) { return false; } if (!VillaLocator.TryGetEntrance(out var pos, out var _)) { return false; } Vector3 position = ((Component)building).transform.position; float y = pos.y; LogMansionBounds(((Component)building).gameObject, position, pos); bool hit; float num = SampleFloorY(new Vector3(position.x, y, position.z), y, out hit); if (!hit || Mathf.Abs(num - y) > 3f) { num = y; } r.DoorOutside = pos; r.FloorY = num; r.NavMeshOk = false; r.InteriorPoint = new Vector3(position.x, num + 0.1f, position.z); r.HasInterior = true; NDLog.Debug($"[VILLAPROBE] center={position} door={pos} floorY={num:0.00} floorHit={hit} " + $"interior={r.InteriorPoint} (own glass room is built at the center)."); _cached = r; _resolved = true; return true; } catch (Exception ex) { if (Time.time >= _resolveWarnMuteUntil) { _resolveWarnMuteUntil = Time.time + 30f; NDLog.Warn("[VILLAPROBE] TryResolve: " + ex.Message); } else { NDLog.DebugWarn("[VILLAPROBE] TryResolve: " + ex.Message); } return false; } } private static void LogMansionBounds(GameObject go, Vector3 center, Vector3 doorPos) { //IL_000e: 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_00a0: 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_00be: 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_0161: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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_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_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) try { Renderer[] componentsInChildren = go.GetComponentsInChildren(true); bool flag = false; Bounds val = default(Bounds); int num = 0; if (componentsInChildren != null) { for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null)) { num++; if (!flag) { val = componentsInChildren[i].bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(componentsInChildren[i].bounds); } } } } if (flag) { NDLog.Debug($"[VILLABOUNDS] RENDERER center={((Bounds)(ref val)).center} size={((Bounds)(ref val)).size} min={((Bounds)(ref val)).min} max={((Bounds)(ref val)).max} (n={num})"); } else { NDLog.Debug("[VILLABOUNDS] no renderers found."); } Collider[] componentsInChildren2 = go.GetComponentsInChildren(true); bool flag2 = false; Bounds val2 = default(Bounds); int num2 = 0; if (componentsInChildren2 != null) { for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] == (Object)null) { continue; } bool flag3 = false; try { flag3 = componentsInChildren2[j].isTrigger; } catch { } if (!flag3) { num2++; if (!flag2) { val2 = componentsInChildren2[j].bounds; flag2 = true; } else { ((Bounds)(ref val2)).Encapsulate(componentsInChildren2[j].bounds); } } } } if (flag2) { NDLog.Debug($"[VILLABOUNDS] COLLIDER(solid) center={((Bounds)(ref val2)).center} size={((Bounds)(ref val2)).size} min={((Bounds)(ref val2)).min} max={((Bounds)(ref val2)).max} (n={num2})"); } if (!VillaLocator.TryGetVilla(out var building) || !((Object)(object)building != (Object)null)) { return; } StaticDoor[] doors = building.Doors; int num3 = ((doors != null) ? doors.Length : 0); NDLog.Debug($"[VILLABOUNDS] building.pos={go.transform.position} buildingCenter={center} doorAccess={doorPos} doors={num3}"); if (doors == null) { return; } for (int k = 0; k < doors.Length; k++) { try { StaticDoor val3 = doors[k]; if (!((Object)(object)val3 == (Object)null)) { Transform accessPoint = val3.AccessPoint; NDLog.Debug($"[VILLABOUNDS] door[{k}] pos={(((Object)(object)((Component)val3).transform != (Object)null) ? ((Component)val3).transform.position : Vector3.zero)} access={(((Object)(object)accessPoint != (Object)null) ? accessPoint.position : Vector3.zero)}"); } } catch { } } } catch (Exception ex) { NDLog.DebugWarn("[VILLABOUNDS] " + ex.Message); } } private static float SampleFloorY(Vector3 xz, float doorY, out bool hit) { //IL_0007: 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_001f: 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_003d: Unknown result type (might be due to invalid IL or missing references) hit = false; try { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(xz.x, doorY + 3f, xz.z); RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, Vector3.down, ref val2, 10f, -1, (QueryTriggerInteraction)1)) { hit = true; return ((RaycastHit)(ref val2)).point.y; } } catch (Exception ex) { NDLog.DebugWarn("[VILLAPROBE] SampleFloorY: " + ex.Message); } return doorY; } } internal static class VillaRoom { private static readonly Vector3 ROOM_CENTER = new Vector3(124.5f, -12f, 113.5f); private const float HALF_X = 7f; private const float HALF_Z = 5f; private const float HEIGHT = 3.4f; private static Vector3 _center = ROOM_CENTER; private static GameObject _root; private static GameObject _doorProp; private static Vector3 _doorOutside; private static bool _built; private static bool _useRealInterior; private static Vector3 _interiorPoint; private static readonly List _sealGos = new List(); internal const int VILLA_IDX = 3; private static readonly List _floorRends = new List(); private static readonly List _ceilRends = new List(); private static readonly Dictionary _origMat = new Dictionary(); private static GameObject[] _villaFurniture; private static GameObject _floorSurface; private static readonly Vector3[] _villaFloorPoly = (Vector3[])(object)new Vector3[8] { new Vector3(142.3f, 5.115f, 115.52f), new Vector3(133.2f, 5.115f, 115.52f), new Vector3(113.19f, 5.115f, 105.4f), new Vector3(113.4f, 5.115f, 107.5f), new Vector3(113.2f, 5.115f, 111.4f), new Vector3(113.2f, 5.115f, 113.05f), new Vector3(133f, 5.115f, 123.2f), new Vector3(142.3f, 5.115f, 123.3f) }; private const float GLASS_HEIGHT = 3.5f; private const float GLASS_THICK = 0.07f; private static readonly Color GLASS_COLOR = new Color(0.003f, 0.002f, 0.01f); private const float GLASS_ALPHA = 0.45f; private const float WALL_THICK = 0.1f; private static readonly Color WALL_COLOR = new Color(0.003f, 0.002f, 0.01f); private static readonly List _vanillaWalls = new List(); private static readonly Vector3[] _villaObjLocal = (Vector3[])(object)new Vector3[8] { new Vector3(-3.5f, 0f, 2.5f), new Vector3(3.5f, 0f, 2.5f), new Vector3(4f, 0f, 0f), new Vector3(0f, 0f, 2.8f), new Vector3(-4f, 0f, 0f), new Vector3(-3.5f, 0f, -2.5f), new Vector3(3.5f, 0f, -2.5f), new Vector3(0f, 0f, -3f) }; private static readonly Vector3 UPSTAIRS_TARGET = new Vector3(132.5f, 9.1f, 118.93f); private const float UPSTAIRS_YAW = 90f; private static readonly Vector3 DOWNSTAIRS_INTER = new Vector3(142.36f, 9.1f, 121f); private static readonly Vector3 DOWNSTAIRS_TARGET = new Vector3(141f, 5.1f, 119f); private const float DOWNSTAIRS_YAW = 270f; private static readonly Vector3 LEAVE_VILLA_POS = new Vector3(135.36f, 5.1f, 116f); private static readonly Vector3 HOTBOX_POS = new Vector3(143.62f, 5.07f, 104.37f); private const float HOTBOX_YAW = 45f; private const string HOTBOX_VEHICLE_CODE = "hotbox"; private static LandVehicle _hotbox; private static VehicleLights _hotboxLights; private static bool _hotboxAdopted; private static float _hotboxDedupCd; private static float _uprightNextAt; private static float _ensureVillaWarnMuteUntil = -999f; private static float _ensureVehWarnMuteUntil = -999f; private static bool _hotboxCodesLogged; private static readonly Vector3 TERRACE_MIN = new Vector3(135f, 9.1f, 116f); private static readonly Vector3 TERRACE_MAX = new Vector3(143f, 9.1f, 124f); private const float TERRACE_TILE = 0.5f; private static GameObject _terraceGridGo; private static Grid _terraceGrid; private static GameObject _salonGridGo; private static Grid _salonGrid; private static Property _surfaceProp; private static float _origCullDist = -1f; private const float ACTIVE_CULL_DIST = 100000f; private const float GHX = 6f; private const float GHZ = 5f; private const float GHGT = 3.2f; public static Grid TerraceGridRef => _terraceGrid; public static Grid SalonGridRef => _salonGrid; public static void ResetForSceneReload() { TeardownSalon(); ResetVehicleRefs(); DestroyTerraceGrid(); RestoreInteriorCulling(); } private static void TeardownSalon() { //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) RestoreVillaSurfaces(); try { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } catch { } try { if ((Object)(object)_doorProp != (Object)null) { Object.Destroy((Object)(object)_doorProp); } } catch { } for (int i = 0; i < _sealGos.Count; i++) { try { if ((Object)(object)_sealGos[i] != (Object)null) { Object.Destroy((Object)(object)_sealGos[i]); } } catch { } } _sealGos.Clear(); for (int j = 0; j < _vanillaWalls.Count; j++) { try { if ((Object)(object)_vanillaWalls[j] != (Object)null) { Object.Destroy((Object)(object)_vanillaWalls[j]); } } catch { } } _vanillaWalls.Clear(); if (_villaFurniture != null) { for (int k = 0; k < _villaFurniture.Length; k++) { try { if ((Object)(object)_villaFurniture[k] != (Object)null) { Object.Destroy((Object)(object)_villaFurniture[k]); } } catch { } } _villaFurniture = null; } _floorRends.Clear(); _ceilRends.Clear(); _origMat.Clear(); _root = null; _doorProp = null; _built = false; _useRealInterior = false; _center = ROOM_CENTER; } private static void RestoreVillaSurfaces() { try { foreach (KeyValuePair item in _origMat) { try { if ((Object)(object)item.Key != (Object)null && (Object)(object)item.Value != (Object)null) { item.Key.sharedMaterial = item.Value; } } catch { } } } catch { } } public static void Teardown() { SellTeardownVehicle(); TeardownSalon(); DestroyTerraceGrid(); RestoreInteriorCulling(); ResetVehicleRefs(); } public static void EnsureVilla() { //IL_005f: 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_00d8: 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_00f5: 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_0084: 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_0094: 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) try { if ((!_built || !((Object)(object)_root != (Object)null) || !((Object)(object)_doorProp != (Object)null)) && VillaLocator.TryGetEntrance(out var pos, out var yaw) && VillaProbe.TryResolve(out var r)) { TeardownSalon(); _doorOutside = pos; if (r.HasInterior) { _useRealInterior = true; _interiorPoint = r.InteriorPoint; _doorOutside = r.DoorOutside; BuildInteriorMode(); BuildDoor(pos, yaw); _built = true; NDLog.Debug($"[VILLA] Salone = REAL mansion interior (spawn @ {_interiorPoint})."); } else { _useRealInterior = false; NDLog.Warn("[VILLA] no walkable interior (probe) — falling back to procedural box."); BuildRoom(); BuildDoor(pos, yaw); _built = true; NDLog.Debug($"[VILLA] Salone ready (box @ {ROOM_CENTER}, door @ {pos})."); } } } catch (Exception ex) { if (Time.time >= _ensureVillaWarnMuteUntil) { _ensureVillaWarnMuteUntil = Time.time + 30f; NDLog.Warn("[VILLA] EnsureVilla: " + ex.Message); } else { NDLog.DebugWarn("[VILLA] EnsureVilla: " + ex.Message); } } } private static void BuildInteriorMode() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_001a: 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_0060: 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_008f: Unknown result type (might be due to invalid IL or missing references) _root = new GameObject("Ndrangheta_VillaInterior"); _root.transform.position = _interiorPoint; SealMansionWalls(); GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Ndrangheta_VillaLeaveInside"; val.transform.SetParent(_root.transform, true); val.transform.position = LEAVE_VILLA_POS + Vector3.up * 1.1f; val.transform.localScale = new Vector3(1.8f, 2.2f, 1.8f); try { Renderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } catch { } try { Collider component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.isTrigger = true; } } catch { } InteractableObject val2 = val.AddComponent(); val2.SetMessage("Leave the villa"); val2.SetInteractionType((EInteractionType)0); val2.MaxInteractionRange = 3f; val2.RequiresUniqueClick = true; val2.Priority = 2; val2.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) LagerRoom.TeleportTo(_doorOutside, snapToNavMesh: true); })); BuildSecondFloor(); } private static void BuildSecondFloor() { //IL_0024: 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_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_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_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_005d: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00fb: 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_011e: 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_0158: 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_018b: 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) try { if (!((Object)(object)_root == (Object)null)) { Vector3 val = _villaFloorPoly[_villaFloorPoly.Length - 1]; Vector3 val2 = _villaFloorPoly[0]; Vector3 val3 = (val + val2) * 0.5f; val3.y += 1.1f; MakeInteract("Ndrangheta_VillaUpstairsEnter", val3, new Vector3(0.6f, 2.2f, 2.4f), "Go upstairs", GoUpstairs); MakeInteract("Ndrangheta_VillaTunnelToLager", val3 + new Vector3(0f, 0f, 2f), new Vector3(0.6f, 2.2f, 1.2f), "Use the tunnel", GoToLagerTunnel); MakeInteract("Ndrangheta_VillaDownstairs", DOWNSTAIRS_INTER + Vector3.up * 1.1f, new Vector3(1.8f, 2.2f, 1.8f), "Go downstairs", delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) LagerRoom.TeleportTo(DOWNSTAIRS_TARGET, snapToNavMesh: false, 270f); }); NDLog.Debug($"[VILLA] 2nd floor: up @ {val3} -> {UPSTAIRS_TARGET} (yaw {90f}); " + $"down-interact @ {DOWNSTAIRS_INTER} -> {DOWNSTAIRS_TARGET} (yaw {270f}); leave @ {LEAVE_VILLA_POS}."); } } catch (Exception ex) { NDLog.Warn("[VILLA] BuildSecondFloor: " + ex.Message); } } private static void MakeInteract(string name, Vector3 pos, Vector3 scale, string message, Action onStart) { //IL_0036: 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) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = name; try { val.transform.SetParent(_root.transform, true); } catch { } val.transform.position = pos; val.transform.localScale = scale; try { Renderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } catch { } try { Collider component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.isTrigger = true; } } catch { } InteractableObject val2 = val.AddComponent(); val2.SetMessage(message); val2.SetInteractionType((EInteractionType)0); val2.MaxInteractionRange = 3.5f; val2.RequiresUniqueClick = true; val2.Priority = 2; val2.onInteractStart.AddListener(GameCompat.ToUnityAction(onStart)); } private static void GoUpstairs() { //IL_0040: 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) try { if ((Object)(object)_root == (Object)null) { NDLog.Warn("[VILLA] Salone was dead — rebuilding before 2nd-floor teleport."); _built = false; EnsureVilla(); if ((Object)(object)_root == (Object)null) { return; } } NDLog.Debug($"[VILLA] teleport -> 2nd floor {UPSTAIRS_TARGET} (yaw {90f})."); LagerRoom.TeleportTo(UPSTAIRS_TARGET, snapToNavMesh: false, 90f); } catch (Exception ex) { NDLog.Warn("[VILLA] GoUpstairs: " + ex.Message); } } private static void GoToLagerTunnel() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) try { if (LagerRoom.TryGetRoomEntry(out var p)) { LagerRoom.TeleportTo(p, snapToNavMesh: false); return; } try { Singleton.Instance.ShowHint("

Tunnel\nThe other end isn't dug yet — buy a Deposito first.", 0f, (string)null); } catch { } } catch (Exception ex) { NDLog.Warn("[VILLA] GoToLagerTunnel: " + ex.Message); } } public static bool TryGetSalonEntry(out Vector3 p) { //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_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) if (_built && (Object)(object)_root != (Object)null) { p = _interiorPoint; return true; } p = Vector3.zero; return false; } public static void EnsureVehicle() { try { if (!SessionGate.IsAuthority) { return; } if (_hotbox != null || _hotboxAdopted) { VehicleManager instance = NetworkSingleton.Instance; if (!((Object)(object)instance != (Object)null)) { return; } _hotboxDedupCd -= Time.deltaTime; if (_hotboxDedupCd <= 0f) { _hotboxDedupCd = 2f; DedupHotboxes(instance); } if ((Object)(object)_hotboxLights == (Object)null) { TrySetHeadlights(instance); } else { try { if (!_hotboxLights.HeadlightsOn) { _hotboxLights.HeadlightsOn = true; } } catch { _hotboxLights = null; } } if (Time.time >= _uprightNextAt) { _uprightNextAt = Time.time + 2f; UprightHotboxIfTipped(instance); } return; } VehicleManager instance2 = NetworkSingleton.Instance; if ((Object)(object)instance2 == (Object)null) { return; } if (AdoptExistingHotbox(instance2)) { _hotboxAdopted = true; try { RealEstateManager.MarkVillaCarSpawned(); return; } catch { return; } } bool flag = false; try { flag = RealEstateManager.VillaCarSpawned; } catch { } if (!flag) { SpawnVillaCarOnce(); } } catch (Exception ex) { if (Time.time >= _ensureVehWarnMuteUntil) { _ensureVehWarnMuteUntil = Time.time + 30f; NDLog.Warn("[VILLA] EnsureVehicle: " + ex.Message); } else { NDLog.DebugWarn("[VILLA] EnsureVehicle: " + ex.Message); } } } internal static bool IsHotbox(LandVehicle v) { try { if ((Object)(object)v == (Object)null || _hotbox == null || string.IsNullOrEmpty(_hotbox.GUID)) { return false; } string text = null; try { text = v.GUID.ToString(); } catch { } return text != null && text == _hotbox.GUID; } catch { return false; } } private static void TrySetHeadlights(VehicleManager vm) { try { if ((Object)(object)vm == (Object)null || _hotbox == null || string.IsNullOrEmpty(_hotbox.GUID)) { return; } List allVehicles = vm.AllVehicles; if (allVehicles == null) { return; } for (int i = 0; i < allVehicles.Count; i++) { LandVehicle val = allVehicles[i]; if ((Object)(object)val == (Object)null) { continue; } string text = null; try { text = val.GUID.ToString(); } catch { } if (text != null && !(text != _hotbox.GUID)) { VehicleLights component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { _hotboxLights = component; component.HeadlightsOn = true; } break; } } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] TrySetHeadlights: " + ex.Message); } } private static void ResetVehicleRefs() { _hotbox = null; _hotboxLights = null; _hotboxAdopted = false; } private static void SellTeardownVehicle() { //IL_00bc: 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) if (!SessionGate.IsAuthority) { return; } try { if (_hotbox != null) { _hotbox.DestroyVehichle(); } } catch { } try { VehicleManager instance = NetworkSingleton.Instance; List list = (((Object)(object)instance != (Object)null) ? instance.AllVehicles : null); if (list == null) { return; } for (int i = 0; i < list.Count; i++) { LandVehicle val = list[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } bool flag = false; try { flag = val.IsPlayerOwned; } catch { } if (!flag || Vector3.Distance(((Component)val).transform.position, HOTBOX_POS) > 8f) { continue; } bool flag2 = false; try { flag2 = val.IsOccupied; } catch { } if (!flag2) { try { val.DestroyVehicle(); NDLog.Debug("[VILLA] sold villa car despawned (AllVehicles scan)."); } catch { } } } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] SellTeardownVehicle: " + ex.Message); } } public static void SpawnVillaCarOnce() { //IL_0158: 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_00d9: Unknown result type (might be due to invalid IL or missing references) try { if (!SessionGate.IsAuthority) { return; } if (_hotbox != null || _hotboxAdopted) { try { RealEstateManager.MarkVillaCarSpawned(); return; } catch { return; } } VehicleManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { return; } if (AdoptExistingHotbox(instance)) { _hotboxAdopted = true; try { RealEstateManager.MarkVillaCarSpawned(); return; } catch { return; } } if ((Object)(object)instance.GetVehiclePrefab("hotbox") == (Object)null) { LogAvailableVehicleCodes(instance); return; } LandVehicle val = VehicleRegistry.CreateVehicle("hotbox"); if (val == null) { NDLog.Warn("[VILLA] S1API CreateVehicle returned null."); return; } val.Spawn(HOTBOX_POS, Quaternion.Euler(0f, 45f, 0f)); try { val.ApplyColor((VehicleColor)0); } catch (Exception ex) { NDLog.DebugWarn("[VILLA] Farbe: " + ex.Message); } try { val.IsPlayerOwned = true; } catch (Exception ex2) { NDLog.DebugWarn("[VILLA] IsPlayerOwned: " + ex2.Message); } _hotbox = val; TrySetHeadlights(instance); try { RealEstateManager.MarkVillaCarSpawned(); } catch { } NDLog.Info($"[VILLA] Hotbox vehicle spawned ONCE on purchase @ {HOTBOX_POS} (black, player-owned/drivable, GUID={_hotbox.GUID})."); } catch (Exception ex3) { NDLog.Warn("[VILLA] SpawnVillaCarOnce: " + ex3.Message); } } private static void UprightHotboxIfTipped(VehicleManager vm) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00d7: 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_0120: 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_0153: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)vm == (Object)null) { return; } List allVehicles = vm.AllVehicles; if (allVehicles == null) { return; } for (int i = 0; i < allVehicles.Count; i++) { LandVehicle val = allVehicles[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } bool flag = false; try { flag = val.IsPlayerOwned; } catch { } if (!flag || Vector3.Distance(((Component)val).transform.position, HOTBOX_POS) > 8f) { continue; } bool flag2 = false; try { flag2 = val.IsOccupied; } catch { } if (flag2) { continue; } float num = Vector3.Dot(((Component)val).transform.up, Vector3.up); if (num >= 0.77f) { continue; } float y = ((Component)val).transform.eulerAngles.y; ((Component)val).transform.rotation = Quaternion.Euler(0f, y, 0f); try { Rigidbody component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { component.velocity = Vector3.zero; component.angularVelocity = Vector3.zero; } } catch { } NDLog.Debug($"[VILLA] hotbox uprighted (was tilted, upDot={num:0.00})."); break; } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] UprightHotboxIfTipped: " + ex.Message); } } private static bool AdoptExistingHotbox(VehicleManager vm) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { List allVehicles = vm.AllVehicles; if (allVehicles == null) { return false; } for (int i = 0; i < allVehicles.Count; i++) { LandVehicle val = allVehicles[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } bool flag = false; try { flag = val.IsPlayerOwned; } catch { } if (!flag || Vector3.Distance(((Component)val).transform.position, HOTBOX_POS) > 8f) { continue; } try { VehicleLights component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { _hotboxLights = component; component.HeadlightsOn = true; } } catch { } NDLog.Debug("[VILLA] Hotbox adopted from save (player-owned at park point) — no respawn."); return true; } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] AdoptExistingHotbox: " + ex.Message); } return false; } private static void DedupHotboxes(VehicleManager vm) { //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) try { if ((Object)(object)vm == (Object)null) { return; } List allVehicles = vm.AllVehicles; if (allVehicles == null) { return; } string text = null; try { text = ((_hotbox != null) ? _hotbox.GUID : null); } catch { } LandVehicle val = null; List list = new List(); for (int i = 0; i < allVehicles.Count; i++) { LandVehicle val2 = allVehicles[i]; if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).transform == (Object)null) { continue; } bool flag = false; try { flag = val2.IsPlayerOwned; } catch { } if (flag && !(Vector3.Distance(((Component)val2).transform.position, HOTBOX_POS) > 8f)) { string text2 = null; try { text2 = val2.GUID.ToString(); } catch { } bool flag2 = text != null && text2 == text; if ((Object)(object)val == (Object)null) { val = val2; } else if (flag2) { list.Add(val); val = val2; } else { list.Add(val2); } } } for (int j = 0; j < list.Count; j++) { LandVehicle val3 = list[j]; bool flag3 = false; try { flag3 = val3.IsOccupied; } catch { } if (!flag3) { try { val3.DestroyVehicle(); NDLog.Debug("[VILLA] duplicate Hotbox at park point despawned (dedup)."); } catch { } } } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] DedupHotboxes: " + ex.Message); } } private static void BuildSalonGrid(Property ownedProp) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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) //IL_007d: 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_014c: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00a5: 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_00bd: 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) try { if ((Object)(object)_salonGridGo != (Object)null || (Object)(object)ownedProp == (Object)null) { return; } int num = LayerMask.NameToLayer("Tile"); if (num < 0) { NDLog.Warn("[VILLA] Layer 'Tile' missing — Salon grid aborted."); return; } float num2 = float.MaxValue; float num3 = float.MinValue; float num4 = float.MaxValue; float num5 = float.MinValue; for (int i = 0; i < _villaFloorPoly.Length; i++) { Vector3 val = _villaFloorPoly[i]; if (val.x < num2) { num2 = val.x; } if (val.x > num3) { num3 = val.x; } if (val.z < num4) { num4 = val.z; } if (val.z > num5) { num5 = val.z; } } float y = _villaFloorPoly[0].y; int num6 = Mathf.Max(2, Mathf.RoundToInt((num3 - num2) / 0.5f)) + 1; int num7 = Mathf.Max(2, Mathf.RoundToInt((num5 - num4) / 0.5f)) + 1; _salonGridGo = new GameObject("Ndrangheta_VillaSalonGrid"); _salonGridGo.SetActive(false); try { _salonGridGo.transform.SetParent(((Component)ownedProp).transform, true); } catch { } _salonGridGo.transform.position = new Vector3(num2, y, num4); _salonGridGo.transform.rotation = Quaternion.identity; _salonGrid = _salonGridGo.AddComponent(); GameCompat.SetGridParentProperty(_salonGrid, ownedProp); GameCompat.SetGridGuidString(_salonGrid, DeterministicGuid("Ndrangheta_VillaSalonGrid").ToString()); int num8 = 0; for (int j = 0; j < num6; j++) { for (int k = 0; k < num7; k++) { if (PointInPoly(num2 + (float)j * 0.5f, num4 + (float)k * 0.5f, _villaFloorPoly) && BuildSalonTile(j, k, num)) { num8++; } } } _salonGridGo.SetActive(true); NDLog.Debug($"[VILLA] Salon grid built @ corner ({num2:0.0},{y:0.00},{num4:0.0}); {num8} tiles (bbox {num6}x{num7}, point-in-poly), Layer 'Tile'={num}."); } catch (Exception ex) { NDLog.Warn("[VILLA] BuildSalonGrid: " + ex.Message); } } private static bool BuildSalonTile(int gx, int gz, int layer) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0058: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0098: 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_00d5: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject($"SalonTile_{gx}_{gz}"); val.layer = layer; val.transform.SetParent(_salonGridGo.transform, false); val.transform.localPosition = new Vector3((float)gx * 0.5f, 0f, (float)gz * 0.5f); val.transform.localRotation = Quaternion.identity; GameObject val2 = new GameObject("Model"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = Vector3.zero; BoxCollider val3 = val.AddComponent(); val3.size = new Vector3(0.5f, 0.1f, 0.5f); val3.center = new Vector3(0f, -0.05f, 0f); ((Collider)val3).isTrigger = false; Tile val4 = val.AddComponent(); val4.InitializePropertyTile(gx, gz, 1000f, _salonGrid); _salonGrid.RegisterTile(val4); return true; } catch (Exception ex) { NDLog.DebugWarn($"[VILLA] BuildSalonTile {gx},{gz}: {ex.Message}"); return false; } } private static bool PointInPoly(float x, float z, Vector3[] poly) { bool flag = false; int num = poly.Length; int num2 = 0; int num3 = num - 1; while (num2 < num) { float z2 = poly[num2].z; float z3 = poly[num3].z; if (z2 > z != z3 > z) { float num4 = (poly[num3].x - poly[num2].x) * (z - z2) / (z3 - z2) + poly[num2].x; if (x < num4) { flag = !flag; } } num3 = num2++; } return flag; } private static void BuildExteriorLights() { //IL_0027: 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_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) try { if (!((Object)(object)_root == (Object)null)) { SpawnSpot("walllamp", new Vector3(137.65f, 8.6f, 123.2f), Quaternion.identity); SpawnSpot("walllamp", new Vector3(123f, 8.6f, 118f), Quaternion.identity); NDLog.Debug("[VILLA] Exterior spots: 2 wall lamps (pool side). Driveway floor lamps removed (user)."); } } catch (Exception ex) { NDLog.Warn("[VILLA] BuildExteriorLights: " + ex.Message); } } private static void SpawnSpot(string kind, Vector3 pos, Quaternion rot) { //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_0044: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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) try { GameObject val = GameCompat.SpawnVanillaPrefab(kind, pos, rot); if ((Object)(object)val != (Object)null) { try { val.transform.SetParent(_root.transform, true); } catch { } RoomFurnish.MakeStatic(val); } Light("Spot", pos + Vector3.up * 0.5f, new Color(1f, 0.96f, 0.85f), 1.4f, 14f); } catch (Exception ex) { NDLog.DebugWarn("[VILLA] SpawnSpot " + kind + ": " + ex.Message); } } private static void BuildTerraceGrid(Property ownedProp) { //IL_013c: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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) //IL_0211: 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_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_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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown try { if ((Object)(object)_terraceGridGo != (Object)null || (Object)(object)ownedProp == (Object)null) { return; } int num = LayerMask.NameToLayer("Tile"); if (num < 0) { NDLog.Warn("[VILLA] Layer 'Tile' missing — terrace grid aborted."); return; } Vector3 val = (TERRACE_MIN + TERRACE_MAX) * 0.5f; val.y = TERRACE_MAX.y; int num2 = Mathf.Max(2, Mathf.RoundToInt(Mathf.Abs(TERRACE_MAX.x - TERRACE_MIN.x) / 0.5f)); int num3 = Mathf.Max(2, Mathf.RoundToInt(Mathf.Abs(TERRACE_MAX.z - TERRACE_MIN.z) / 0.5f)); float num4 = (float)(num2 - 1) * 0.5f * 0.5f; float num5 = (float)(num3 - 1) * 0.5f * 0.5f; _terraceGridGo = new GameObject("Ndrangheta_VillaTerraceGrid"); _terraceGridGo.SetActive(false); try { _terraceGridGo.transform.SetParent(((Component)ownedProp).transform, true); } catch { } _terraceGridGo.transform.position = new Vector3(val.x - num4, val.y, val.z - num5); _terraceGridGo.transform.rotation = Quaternion.identity; _terraceGrid = _terraceGridGo.AddComponent(); GameCompat.SetGridParentProperty(_terraceGrid, ownedProp); GameCompat.SetGridGuidString(_terraceGrid, DeterministicGuid("Ndrangheta_VillaTerraceGrid").ToString()); int num6 = 0; for (int i = 0; i < num2; i++) { for (int j = 0; j < num3; j++) { if (BuildTerraceTile(i, j, num)) { num6++; } } } _terraceGridGo.SetActive(true); NDLog.Debug($"[VILLA] Terrace grid built @ {val}, {num6}/{num2 * num3} tiles ({num2}x{num3}), Layer 'Tile'={num}."); } catch (Exception ex) { NDLog.Warn("[VILLA] BuildTerraceGrid: " + ex.Message); } } private static bool BuildTerraceTile(int gx, int gz, int layer) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0058: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0098: 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_00d5: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject($"TerraceTile_{gx}_{gz}"); val.layer = layer; val.transform.SetParent(_terraceGridGo.transform, false); val.transform.localPosition = new Vector3((float)gx * 0.5f, 0f, (float)gz * 0.5f); val.transform.localRotation = Quaternion.identity; GameObject val2 = new GameObject("Model"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = Vector3.zero; BoxCollider val3 = val.AddComponent(); val3.size = new Vector3(0.5f, 0.1f, 0.5f); val3.center = new Vector3(0f, -0.05f, 0f); ((Collider)val3).isTrigger = false; Tile val4 = val.AddComponent(); val4.InitializePropertyTile(gx, gz, 1000f, _terraceGrid); _terraceGrid.RegisterTile(val4); return true; } catch (Exception ex) { NDLog.DebugWarn($"[VILLA] BuildTerraceTile {gx},{gz}: {ex.Message}"); return false; } } private static void DestroyTerraceGrid() { try { if ((Object)(object)_terraceGridGo != (Object)null) { Object.Destroy((Object)(object)_terraceGridGo); } } catch { } _terraceGridGo = null; _terraceGrid = null; try { if ((Object)(object)_salonGridGo != (Object)null) { Object.Destroy((Object)(object)_salonGridGo); } } catch { } _salonGridGo = null; _salonGrid = null; try { GridPersistence.ResetReplayLatches(); } catch { } } private static void LogAvailableVehicleCodes(VehicleManager vm) { if (_hotboxCodesLogged) { return; } _hotboxCodesLogged = true; try { List vehiclePrefabs = vm.VehiclePrefabs; StringBuilder stringBuilder = new StringBuilder(); int num = vehiclePrefabs?.Count ?? 0; for (int i = 0; i < num; i++) { try { LandVehicle val = vehiclePrefabs[i]; if (!((Object)(object)val == (Object)null)) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(((Object)val).name); } } catch { } } NDLog.Warn(string.Format("[VILLA] Vehicle code '{0}' not found. Available prefabs ({1}): [{2}]", "hotbox", num, stringBuilder)); } catch (Exception ex) { NDLog.DebugWarn("[VILLA] LogAvailableVehicleCodes: " + ex.Message); } } private static void ActivateInterior(Property prop) { try { if ((Object)(object)prop == (Object)null) { return; } _surfaceProp = prop; if (_origCullDist < 0f) { try { _origCullDist = prop.MinimumCullingDistance; } catch { _origCullDist = 50f; } } try { prop.MinimumCullingDistance = 100000f; } catch { } try { prop.ContentCullingEnabled = false; } catch { } try { prop.SetContentCulled(false); } catch { } NDLog.Debug("[VILLA] active room: content culling of surface property OFF (pictures/shelves render now)."); } catch (Exception ex) { NDLog.DebugWarn("[VILLA] ActivateInterior: " + ex.Message); } } public static void KeepInteriorActive() { try { try { GridPersistence.ReplayIfReady(GridKey.Terrace, _terraceGrid); GridPersistence.ReplayIfReady(GridKey.Salon, _salonGrid); } catch (Exception ex) { NDLog.DebugWarn("[VILLA] grid replay: " + ex.Message); } if ((Object)(object)_surfaceProp == (Object)null || !(_surfaceProp.MinimumCullingDistance < 50000f)) { return; } _surfaceProp.MinimumCullingDistance = 100000f; try { _surfaceProp.ContentCullingEnabled = false; } catch { } try { _surfaceProp.SetContentCulled(false); } catch { } } catch { } } private static void RestoreInteriorCulling() { try { if ((Object)(object)_surfaceProp != (Object)null && (Object)(object)((Component)_surfaceProp).gameObject != (Object)null) { if (_origCullDist >= 0f) { try { _surfaceProp.MinimumCullingDistance = _origCullDist; } catch { } } try { _surfaceProp.ContentCullingEnabled = true; } catch { } } } catch { } _surfaceProp = null; _origCullDist = -1f; } private static void BuildRoom() { //IL_0006: 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_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) //IL_0033: Expected O, but got Unknown //IL_003d: 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_005c: 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_0075: 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_0099: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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) //IL_01d8: 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_01f1: 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_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0229: 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_0242: 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_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: 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_0301: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: 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_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_0415: 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_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_051a: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_0550: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_05ae: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Unknown result type (might be due to invalid IL or missing references) //IL_05dd: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_0618: Unknown result type (might be due to invalid IL or missing references) //IL_062c: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) _center = RoomSiting.FindFreeCenter("Salone", ROOM_CENTER, 7f, 5f, 3.4f); _root = new GameObject("Ndrangheta_VillaSalone"); _root.transform.position = _center; Slab("Floor", _center + Vector3.down * 0.1f, new Vector3(14f, 0.2f, 10f), new Color(0.16f, 0.13f, 0.1f)); Slab("Ceiling", _center + Vector3.up * 3.4f, new Vector3(14f, 0.2f, 10f), new Color(0.12f, 0.11f, 0.1f)); Slab("WallN", _center + new Vector3(0f, 1.7f, 5f), new Vector3(14f, 3.4f, 0.2f), new Color(0.24f, 0.2f, 0.16f)); Slab("WallS", _center + new Vector3(0f, 1.7f, -5f), new Vector3(14f, 3.4f, 0.2f), new Color(0.24f, 0.2f, 0.16f)); Slab("WallE", _center + new Vector3(7f, 1.7f, 0f), new Vector3(0.2f, 3.4f, 10f), new Color(0.24f, 0.2f, 0.16f)); Slab("WallW", _center + new Vector3(-7f, 1.7f, 0f), new Vector3(0.2f, 3.4f, 10f), new Color(0.24f, 0.2f, 0.16f)); Light("L1", _center + new Vector3(0f, 3f, 0f), new Color(1f, 0.95f, 0.85f), 1.2f, 18f); Light("L3", _center + new Vector3(5.5f, 1.9f, 2f), new Color(1f, 0.93f, 0.8f), 0.9f, 9f); Transform transform = _root.transform; Furniture.Rug(transform, new Vector3(0f, 0f, -1f), 0f, 5.6f, 3.4f); Furniture.Sofa(transform, new Vector3(0f, 0f, 0.4f), 180f, Furniture.Leather); Furniture.CoffeeTable(transform, new Vector3(0f, 0f, -1.2f), 0f); Furniture.Armchair(transform, new Vector3(-2.4f, 0f, -0.8f), 135f, Furniture.LeatherLt); Furniture.Armchair(transform, new Vector3(2.4f, 0f, -0.8f), 225f, Furniture.LeatherLt); Furniture.WallTV(transform, new Vector3(0f, 1.75f, -4.84f), 0f, 2.4f, 1.4f); Furniture.Sideboard(transform, new Vector3(0f, 0f, -4.55f), 0f); Furniture.BarCounter(transform, new Vector3(-6.3f, 0f, -2f), 0f, 4f); Furniture.BarStool(transform, new Vector3(-5.4f, 0f, -3.2f), 0f); Furniture.BarStool(transform, new Vector3(-5.4f, 0f, -0.8f), 0f); Furniture.DiningTable(transform, new Vector3(4.6f, 0f, 0.6f), 0f, 1.3f, 3.2f); for (int i = 0; i < 3; i++) { float num = 0.6f + (float)(i - 1) * 1f; Furniture.Chair(transform, new Vector3(3.85f, 0f, num), 90f); Furniture.Chair(transform, new Vector3(5.35f, 0f, num), 270f); } Furniture.Bookshelf(transform, new Vector3(4.6f, 0f, 4.6f), 180f); Furniture.Fireplace(transform, new Vector3(-3.6f, 0f, 4.55f), 180f); Furniture.PottedPlant(transform, new Vector3(6.3f, 0f, 4.2f)); Furniture.PottedPlant(transform, new Vector3(6.3f, 0f, -4.2f)); Furniture.PottedPlant(transform, new Vector3(-6.2f, 0f, 4.1f)); Furniture.FloorLamp(transform, new Vector3(3.4f, 0f, -1.8f)); Furniture.WallArt(transform, new Vector3(-1.7f, 1.95f, 4.88f), 180f, 1f, 0.7f, Furniture.BurgDark); Furniture.WallArt(transform, new Vector3(1.7f, 1.95f, 4.88f), 180f, 1f, 0.7f, Furniture.BurgDark); Furniture.WallArt(transform, new Vector3(6.88f, 2f, 0.6f), 270f, 1.2f, 0.8f, Furniture.WalnutLt); Furniture.Chandelier(transform, new Vector3(0f, 2.8500001f, -0.5f)); NDLog.Debug("[VILLA] Salone furnished (procedural luxury decor)."); GameObject val = RoomFurnish.BuildDoor(_root.transform, _center + new Vector3(0f, 0f, 4.78f), 180f); ((Object)val).name = "Ndrangheta_SaloneExit"; InteractableObject val2 = val.AddComponent(); val2.SetMessage("Leave the villa"); val2.SetInteractionType((EInteractionType)0); val2.MaxInteractionRange = 3f; val2.RequiresUniqueClick = true; val2.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) LagerRoom.TeleportTo(_doorOutside, snapToNavMesh: true); })); } private static void BuildDoor(Vector3 doorPos, float yaw) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0056: 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) _doorProp = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)_doorProp).name = "Ndrangheta_VillaEnter"; _doorProp.transform.position = doorPos + Vector3.up * 1.1f; _doorProp.transform.rotation = Quaternion.Euler(0f, yaw, 0f); _doorProp.transform.localScale = new Vector3(1.4f, 2.2f, 0.5f); try { Renderer component = _doorProp.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } catch { } try { Collider component2 = _doorProp.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.isTrigger = true; } } catch { } InteractableObject val = _doorProp.AddComponent(); val.SetMessage("Enter the villa"); val.SetInteractionType((EInteractionType)0); val.MaxInteractionRange = 3.5f; val.RequiresUniqueClick = true; val.Priority = 2; val.onInteractStart.AddListener(GameCompat.ToUnityAction((Action)EnterSalone)); } private static void EnterSalone() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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) try { if (!RealEstateManager.VillaOwnedView) { NDLog.DebugWarn("[VILLA] EnterSalone blocked — villa not owned."); return; } if ((Object)(object)_root == (Object)null) { NDLog.Warn("[VILLA] Salone was dead — rebuilding before teleport."); _built = false; EnsureVilla(); if ((Object)(object)_root == (Object)null) { return; } } if (_useRealInterior) { NDLog.Debug($"[VILLA] teleport -> glass Salon (own floor) {_interiorPoint}"); LagerRoom.TeleportTo(_interiorPoint, snapToNavMesh: false); } else { Vector3 val = _center + new Vector3(0f, 0.15f, 3.5f); NDLog.Debug($"[VILLA] teleport -> Salone (box) {val}"); LagerRoom.TeleportTo(val, snapToNavMesh: false); } } catch (Exception ex) { NDLog.Warn("[VILLA] EnterSalone: " + ex.Message); } } private static GameObject Slab(string name, Vector3 pos, Vector3 scale, Color color) { //IL_0037: 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_004c: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Ndrangheta_Salone_" + name; val.transform.SetParent(_root.transform, true); val.transform.position = pos; val.transform.localScale = scale; PropVisuals.ApplyFlat(val, color); return val; } private static void SealMansionWalls() { //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) //IL_005d: 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) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_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_0098: 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_00a5: 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_00be: 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_00c2: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_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) try { Vector3[] villaFloorPoly = _villaFloorPoly; int num = ((villaFloorPoly != null) ? villaFloorPoly.Length : 0); Property val = ResolveOwnedProperty(); Property val2 = GameCompat.ResolvePropertyAnchor(RealEstateManager.VillaOwnedView); ActivateInterior(val2); BuildTerraceGrid(val2); BuildSalonGrid(val2); BuildExteriorLights(); int num2 = 0; int num3 = 0; Vector3 val7 = default(Vector3); for (int i = 0; i + 1 < num; i++) { try { Vector3 val3 = villaFloorPoly[i]; Vector3 val4 = villaFloorPoly[i + 1]; Vector3 val5 = val4 - val3; val5.y = 0f; float magnitude = ((Vector3)(ref val5)).magnitude; if (magnitude < 0.05f) { continue; } Vector3 val6 = val5 / magnitude; ((Vector3)(ref val7))..ctor(0f - val6.z, 0f, val6.x); Vector3 pos = (val3 + val4) * 0.5f; pos.y = val3.y + 1.75f; Quaternion rot = Quaternion.LookRotation(val7, Vector3.up); if (i <= 2) { if (BuildVanillaWall(i, pos, rot, magnitude, val)) { num3++; } } else { BuildGlassPane(i, pos, rot, magnitude); num2++; } } catch (Exception ex) { NDLog.DebugWarn($"[VILLA] wall/glass edge {i}: {ex.Message}"); } } NDLog.Debug($"[VILLA] Outline: {num3} buildable vanilla walls (door side) + {num2} glass panes (left/pool); right end open. " + "ownedProp=" + (((Object)(object)val != (Object)null) ? "yes" : "NO → walls visual only") + "."); } catch (Exception ex2) { NDLog.Warn("[VILLA] SealMansionWalls: " + ex2.Message); } } private static void BuildGlassPane(int idx, Vector3 pos, Quaternion rot, float len) { //IL_0045: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = $"Ndrangheta_VillaGlass_{idx}"; try { val.transform.SetParent(_root.transform, true); } catch { } val.transform.position = pos; val.transform.rotation = rot; val.transform.localScale = new Vector3(len + 0.25f, 3.5f, 0.07f); PropVisuals.ApplyGlass(val, GLASS_COLOR, 0.45f); _sealGos.Add(val); } private static bool BuildVanillaWall(int idx, Vector3 pos, Quaternion rot, float len, Property ownedProp) { //IL_004d: 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_0078: 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) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = $"Ndrangheta_VillaWall_{idx}"; val.SetActive(false); try { val.transform.SetParent(_root.transform, true); } catch { } val.transform.position = pos; val.transform.rotation = rot; val.transform.localScale = new Vector3(len + 0.25f, 3.5f, 0.1f); PropVisuals.ApplyFlat(val, WALL_COLOR); bool flag = false; if ((Object)(object)ownedProp != (Object)null) { flag = GameCompat.MakePictureWall(val, ownedProp, DeterministicGuid($"Ndrangheta_VillaSurface_{idx}").ToString()); } val.SetActive(true); _vanillaWalls.Add(val); NDLog.Debug(string.Format("[VILLA] Door-side wall {0} built (Surface={1}, opaque, solid).", idx, flag ? "yes" : "no")); return true; } private static Guid DeterministicGuid(string seed) { using MD5 mD = MD5.Create(); return new Guid(mD.ComputeHash(Encoding.UTF8.GetBytes(seed))); } private static Property ResolveOwnedProperty() { try { Property[] array = Object.FindObjectsOfType(true); if (array != null) { foreach (Property val in array) { if (!((Object)(object)val == (Object)null)) { bool flag = false; try { flag = val.IsOwned; } catch { } if (flag) { return val; } } } } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] ResolveOwnedProperty: " + ex.Message); } return null; } private static void ScanVillaSurfaces() { //IL_0093: 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_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_00a3: 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_00b8: 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) _floorRends.Clear(); _ceilRends.Clear(); try { if (!VillaLocator.TryGetVilla(out var building) || (Object)(object)building == (Object)null || (Object)(object)((Component)building).gameObject == (Object)null) { return; } float num = _interiorPoint.y - 0.1f; Renderer[] componentsInChildren = ((Component)building).gameObject.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Bounds bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(size.y > 0.8f) && !(size.x * size.z < 8f)) { float num2 = ((Bounds)(ref bounds)).center.y - num; if (num2 >= -1.2f && num2 <= 1.5f) { _floorRends.Add(val); } else if (num2 >= 2.2f) { _ceilRends.Add(val); } } } NDLog.Debug($"[VILLA] Surface scan: {_floorRends.Count} floor, {_ceilRends.Count} ceiling renderers (floorY={num:0.00})."); } catch (Exception ex) { NDLog.DebugWarn("[VILLA] ScanVillaSurfaces: " + ex.Message); } } public static void ApplyFurnish() { try { int furnishA = RealEstateManager.GetFurnishA(3); ApplyFloorMesh(FurnishCatalog.Mat(furnishA, 0), FurnishCatalog.Col(furnishA, 0)); ApplyVillaObjects(0); } catch (Exception ex) { NDLog.DebugWarn("[VILLA] ApplyFurnish: " + ex.Message); } } private static void BuildFloorSurface() { //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_002b: 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_0038: 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_004f: 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_0057: 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_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_0084: 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_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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0140: Expected O, but got Unknown //IL_0165: 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) try { if (!((Object)(object)_root == (Object)null)) { int num = _villaFloorPoly.Length; Vector3 val = Vector3.zero; for (int i = 0; i < num; i++) { val += _villaFloorPoly[i]; } val /= (float)num; Vector3[] array = (Vector3[])(object)new Vector3[num + 1]; array[0] = val - _interiorPoint; for (int j = 0; j < num; j++) { array[j + 1] = _villaFloorPoly[j] - _interiorPoint; } int[] array2 = new int[num * 3]; for (int k = 0; k < num; k++) { int num2 = k + 1; int num3 = (k + 1) % num + 1; array2[k * 3] = 0; array2[k * 3 + 1] = num3; array2[k * 3 + 2] = num2; } Vector3[] array3 = (Vector3[])(object)new Vector3[array.Length]; for (int l = 0; l < array3.Length; l++) { array3[l] = Vector3.up; } Mesh sharedMesh = GameCompat.BuildMesh(array, array2, array3); _floorSurface = new GameObject("Ndrangheta_VillaFloor"); _floorSurface.transform.SetParent(_root.transform, false); _floorSurface.transform.localPosition = Vector3.zero; _floorSurface.transform.localRotation = Quaternion.identity; _floorSurface.AddComponent().sharedMesh = sharedMesh; _floorSurface.AddComponent(); NDLog.Debug("[VILLA] Floor surface (polygon) created in measured interior area."); } } catch (Exception ex) { NDLog.DebugWarn("[VILLA] BuildFloorSurface: " + ex.Message); } } private static void ApplyFloorMesh(int matIdx, int colIdx) { //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) //IL_002f: 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_0035: 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_007d: 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_0089: 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_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_0069: 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) if (!((Object)(object)_floorSurface == (Object)null)) { matIdx = FurnishCatalog.ClampMat(matIdx); colIdx = FurnishCatalog.ClampCol(colIdx); MatDef val = FurnishCatalog.Materials[matIdx]; Color val2 = FurnishCatalog.ColorOf(colIdx); if (val.Textured) { PropVisuals.ApplyVanilla(_floorSurface, val.Kind, val.Base, (Color)((val2.a > 0f) ? val2 : default(Color))); } else { PropVisuals.ApplyPreset(_floorSurface, val.Base, val.Metallic, val.Smoothness, val2); } } } private static void ReskinReal(List list, int matIdx, int colIdx) { for (int i = 0; i < list.Count; i++) { Renderer val = list[i]; if ((Object)(object)val == (Object)null) { continue; } if (!_origMat.ContainsKey(val)) { try { _origMat[val] = val.sharedMaterial; } catch { } } ApplySurfaceToRenderer(val, matIdx, colIdx); } } private static void RestoreReal(List list) { for (int i = 0; i < list.Count; i++) { Renderer val = list[i]; if ((Object)(object)val != (Object)null && _origMat.TryGetValue(val, out var value) && (Object)(object)value != (Object)null) { try { val.sharedMaterial = value; } catch { } } } } private static void ApplySurfaceToRenderer(Renderer r, int matIdx, int colIdx) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001d: 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_0057: 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_005d: 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_0069: 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_002f: 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_0035: 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_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) MatDef val = FurnishCatalog.Materials[FurnishCatalog.ClampMat(matIdx)]; Color val2 = FurnishCatalog.ColorOf(FurnishCatalog.ClampCol(colIdx)); if (val.Textured) { PropVisuals.ApplyVanillaToRenderer(r, val.Kind, val.Base, (Color)((val2.a > 0f) ? val2 : default(Color))); } else { PropVisuals.ApplyPresetToRenderer(r, val.Base, val.Metallic, val.Smoothness, val2); } } private static void ReskinWalls(int matIdx, int colIdx) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001d: 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_007a: 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_0080: 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_008c: 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_0051: 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_0057: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) MatDef val = FurnishCatalog.Materials[FurnishCatalog.ClampMat(matIdx)]; Color val2 = FurnishCatalog.ColorOf(FurnishCatalog.ClampCol(colIdx)); for (int i = 0; i < _sealGos.Count; i++) { GameObject val3 = _sealGos[i]; if (!((Object)(object)val3 == (Object)null)) { if (val.Textured) { PropVisuals.ApplyVanilla(val3, val.Kind, val.Base, (Color)((val2.a > 0f) ? val2 : default(Color))); } else { PropVisuals.ApplyPreset(val3, val.Base, val.Metallic, val.Smoothness, val2); } } } } private static void RestoreWalls() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _sealGos.Count; i++) { if ((Object)(object)_sealGos[i] != (Object)null) { PropVisuals.ApplyGlass(_sealGos[i], GLASS_COLOR, 0.45f); } } } private static void ApplyVillaObjects(int mask) { if (_villaFurniture == null || (Object)(object)_root == (Object)null) { return; } for (int i = 0; i < FurnishCatalog.Objects.Length && i < _villaFurniture.Length; i++) { bool flag = (mask & (1 << i)) != 0; bool flag2 = (Object)(object)_villaFurniture[i] != (Object)null; if (flag && !flag2) { _villaFurniture[i] = SpawnVillaObject(i); } else if (!flag && flag2) { try { Object.Destroy((Object)(object)_villaFurniture[i]); } catch { } _villaFurniture[i] = null; } } } private static GameObject SpawnVillaObject(int objIdx) { //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_0026: 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_0019: 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_0037: 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_004d: 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) try { ObjDef val = FurnishCatalog.Objects[objIdx]; Vector3 val2 = ((objIdx < _villaObjLocal.Length) ? _villaObjLocal[objIdx] : val.Local); GameObject val3 = GameCompat.SpawnVanillaPrefab(val.Kind, _interiorPoint + val2, Quaternion.Euler(0f, val.Yaw, 0f)); if ((Object)(object)val3 == (Object)null) { NDLog.DebugWarn("[VILLA] Furniture '" + val.Name + "' not spawnable (S1MAPI null?)."); return null; } try { val3.transform.SetParent(_root.transform, true); } catch { } RoomFurnish.MakeStatic(val3); return val3; } catch (Exception ex) { NDLog.DebugWarn($"[VILLA] SpawnVillaObject {objIdx}: {ex.Message}"); return null; } } private static void Light(string name, Vector3 pos, Color color, float intensity, float range) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0030: 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) try { GameObject val = new GameObject("Ndrangheta_Salone_" + name); val.transform.SetParent(_root.transform, true); val.transform.position = pos; Light val2 = val.AddComponent(); val2.type = (LightType)2; val2.color = color; val2.intensity = intensity; val2.range = range; val2.shadows = (LightShadows)0; } catch { } } } public static class VisualMirror { public struct MirrorObj { public string Id; public byte Kind; public Vector3 Pos; public int Yaw; public Vector3 Scale; public byte Style; public bool Visible; } public const byte KIND_ZONEBOX = 0; public const byte KIND_CUBE = 1; public const byte KIND_CYL = 2; public const byte STYLE_GREEN = 0; public const byte STYLE_AZURE = 1; public const byte STYLE_RED = 2; public const byte STYLE_DARK = 3; private static readonly Dictionary _objs = new Dictionary(); public static void Set(string id, byte kind, Vector3 pos, float yaw, Vector3 scale, byte style, bool visible = true) { //IL_0034: 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_0049: 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) if (string.IsNullOrEmpty(id)) { return; } try { _objs[id] = new MirrorObj { Id = SafeId(id), Kind = kind, Pos = pos, Yaw = Mathf.RoundToInt(yaw), Scale = scale, Style = style, Visible = visible }; } catch (Exception ex) { NDLog.DebugWarn("VisualMirror.Set: " + ex.Message); } } public static void SetVisible(string id, bool visible) { if (!string.IsNullOrEmpty(id) && _objs.TryGetValue(id, out var value)) { value.Visible = visible; _objs[id] = value; } } public static void Move(string id, Vector3 pos, float yaw) { //IL_0021: 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) if (!string.IsNullOrEmpty(id) && _objs.TryGetValue(id, out var value)) { value.Pos = pos; value.Yaw = Mathf.RoundToInt(yaw); _objs[id] = value; } } public static void Remove(string id) { if (!string.IsNullOrEmpty(id)) { _objs.Remove(id); } } public static void Clear(string prefix) { if (string.IsNullOrEmpty(prefix)) { _objs.Clear(); return; } try { List list = null; foreach (KeyValuePair obj2 in _objs) { if (obj2.Key.StartsWith(prefix, StringComparison.Ordinal)) { (list ?? (list = new List())).Add(obj2.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { _objs.Remove(list[i]); } } } catch { } } public static void Reset() { _objs.Clear(); } public static string Encode() { //IL_0089: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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) try { if (_objs.Count == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(); bool flag = true; foreach (KeyValuePair obj2 in _objs) { MirrorObj value = obj2.Value; if (!flag) { stringBuilder.Append('~'); } flag = false; stringBuilder.Append(value.Id).Append(',').Append(value.Kind) .Append(',') .Append(F1(value.Pos.x)) .Append(',') .Append(F1(value.Pos.y)) .Append(',') .Append(F1(value.Pos.z)) .Append(',') .Append(value.Yaw) .Append(',') .Append(F1(value.Scale.x)) .Append(',') .Append(F1(value.Scale.y)) .Append(',') .Append(F1(value.Scale.z)) .Append(',') .Append(value.Style) .Append(',') .Append(value.Visible ? 1 : 0); } return stringBuilder.ToString(); } catch { return ""; } } public static List Decode(string s) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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) List list = new List(); if (string.IsNullOrEmpty(s)) { return list; } try { string[] array = s.Split(new char[1] { '~' }); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { string[] array2 = text.Split(new char[1] { ',' }); if (array2.Length >= 11) { int.TryParse(array2[1], out var result); int.TryParse(array2[5], out var result2); int.TryParse(array2[9], out var result3); int.TryParse(array2[10], out var result4); list.Add(new MirrorObj { Id = array2[0], Kind = (byte)result, Pos = new Vector3(PF(array2[2]), PF(array2[3]), PF(array2[4])), Yaw = result2, Scale = new Vector3(PF(array2[6]), PF(array2[7]), PF(array2[8])), Style = (byte)result3, Visible = (result4 != 0) }); } } } } catch { } return list; } private static string F1(float v) { return v.ToString("F1", CultureInfo.InvariantCulture); } private static float PF(string s) { float result; return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out result) ? result : 0f; } private static string SafeId(string id) { return id.Replace("~", "").Replace(",", "").Replace("|", ""); } } public static class WeaponSpawner { private static readonly string[] RevolverIdCandidates = new string[3] { "revolver", "m1911", "pistol" }; public static string ResolveRevolverId() { string[] revolverIdCandidates = RevolverIdCandidates; foreach (string text in revolverIdCandidates) { try { ItemDefinition item = Registry.GetItem(text); if ((Object)(object)item != (Object)null) { return text; } } catch { } } return null; } public static ItemInstance SpawnRevolverInStash() { try { string text = ResolveRevolverId(); if (text == null) { NDLog.Warn("WeaponSpawner: no revolver item in Registry."); return null; } ItemDefinition item = Registry.GetItem(text); if ((Object)(object)item == (Object)null) { return null; } DeadDrop val = ResolveStash(); if ((Object)(object)val == (Object)null) { return null; } WorldStorageEntity storage = val.Storage; if ((Object)(object)storage == (Object)null) { return null; } ItemInstance val2 = null; try { val2 = item.GetDefaultInstance(1); } catch (Exception ex) { NDLog.DebugWarn("GetDefaultInstance(revolver): " + ex.Message); } if (val2 == null) { return null; } bool flag = true; try { flag = ((StorageEntity)storage).CanItemFit(val2, 1); } catch { } if (!flag) { NDLog.Warn("WeaponSpawner: revolver doesn't fit in stash."); return null; } try { ((StorageEntity)storage).InsertItem(val2, true); } catch (Exception ex2) { NDLog.DebugWarn("InsertItem(revolver): " + ex2.Message); return null; } NDLog.Debug("Revolver spawned in famiglia stash."); return val2; } catch (Exception ex3) { NDLog.Warn("SpawnRevolverInStash: " + ex3.Message); return null; } } public static int ClearRevolverFromStash() { try { string text = ResolveRevolverId(); if (text == null) { return 0; } DeadDrop val = ResolveStash(); if ((Object)(object)val == (Object)null) { return 0; } WorldStorageEntity storage = val.Storage; List list = ((storage != null) ? ((StorageEntity)storage).ItemSlots : null); if (list == null) { return 0; } int num = 0; for (int num2 = list.Count - 1; num2 >= 0; num2--) { ItemSlot val2 = list[num2]; ItemInstance val3 = ((val2 != null) ? val2.ItemInstance : null); if (val3 != null) { string a = null; try { a = ((BaseItemInstance)val3).ID; } catch { } if (string.Equals(a, text, StringComparison.OrdinalIgnoreCase)) { try { val2.ClearStoredInstance(false); num++; } catch { } } } } if (num > 0) { NDLog.Debug($"Removed {num} revolver(s) from stash."); } return num; } catch (Exception ex) { NDLog.DebugWarn("ClearRevolverFromStash: " + ex.Message); return 0; } } public static bool HasRevolverInStash() { try { DeadDrop val = ResolveStash(); if ((Object)(object)val == (Object)null) { return false; } WorldStorageEntity storage = val.Storage; List list = ((storage != null) ? ((StorageEntity)storage).ItemSlots : null); if (list == null) { return false; } for (int i = 0; i < list.Count; i++) { ItemSlot val2; try { val2 = list[i]; } catch { continue; } ItemInstance val3 = ((val2 != null) ? val2.ItemInstance : null); if (val3 == null) { continue; } string text = null; try { text = ((BaseItemInstance)val3).ID; } catch { } if (string.IsNullOrEmpty(text)) { continue; } string[] revolverIdCandidates = RevolverIdCandidates; foreach (string b in revolverIdCandidates) { if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase)) { return true; } } } } catch (Exception ex) { NDLog.DebugWarn("HasRevolverInStash: " + ex.Message); } return false; } private static DeadDrop ResolveStash() { try { List deadDrops = DeadDrop.DeadDrops; if (deadDrops == null) { return null; } string value = "Gazebo"; for (int i = 0; i < deadDrops.Count; i++) { DeadDrop val; try { val = deadDrops[i]; } catch { continue; } if (!((Object)(object)val == (Object)null)) { string text; try { text = val.DeadDropName; } catch { text = null; } if (!string.IsNullOrEmpty(text) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return val; } } } } catch { } return null; } } internal static class WorldReaction { private const float GUNSHOT_NOISE_RANGE = 28f; private const float POLICE_SIC_RADIUS = 22f; public static void EmitGunshot(Vector3 pos, GameObject source) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) try { NoiseUtility.EmitNoise(pos, (ENoiseType)1, 28f, source); } catch (Exception ex) { NDLog.DebugWarn("WorldReaction.EmitGunshot: " + ex.Message); } } public static void SicNearbyPoliceOn(NPC lucky) { //IL_00de: 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_00e4: 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) //IL_0057: 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) try { if ((Object)(object)lucky == (Object)null || (Object)(object)((Component)lucky).transform == (Object)null || (Object)(object)((Component)lucky).gameObject == (Object)null) { return; } NetworkObject component = ((Component)lucky).gameObject.GetComponent(); if ((Object)(object)component == (Object)null) { return; } Vector3 position = ((Component)lucky).transform.position; List officers = PoliceOfficer.Officers; if (officers == null) { return; } float num = 484f; for (int i = 0; i < officers.Count; i++) { PoliceOfficer val; try { val = officers[i]; } catch { continue; } if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } try { if (KillDetector.IsDead((NPC)(object)val)) { continue; } } catch { } Vector3 val2 = ((Component)val).transform.position - position; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } CombatBehaviour val3 = null; try { val3 = ((NPC)val).Behaviour?.CombatBehaviour; } catch { } if ((Object)(object)val3 == (Object)null) { continue; } try { if (val3.Target != null) { continue; } } catch { } try { val3.SetTargetAndEnable_Server(component); } catch (Exception ex) { NDLog.DebugWarn("SicPolice set target: " + ex.Message); } } } catch (Exception ex2) { NDLog.DebugWarn("WorldReaction.SicNearbyPoliceOn: " + ex2.Message); } } } } namespace Ndrangheta.Families { public sealed class NdranghetaFamily : MobFamily { private sealed class RealEstateFurnishTarget : IMobFurnishTarget { private readonly int _idx; private readonly string _name; private readonly Func _owned; public string Name => _name; public bool Available { get { try { return _owned != null && _owned(); } catch { return false; } } } public RealEstateFurnishTarget(int idx, string name, Func owned) { _idx = idx; _name = name; _owned = owned; } public int GetMat(int surface) { return RealEstateManager.GetMat(_idx, surface); } public int GetCol(int surface) { return RealEstateManager.GetCol(_idx, surface); } public bool GetObj(int objIndex) { return RealEstateManager.GetObj(_idx, objIndex); } public void SetMat(int surface, int matIndex) { RealEstateManager.SetMat(_idx, surface, matIndex); } public void SetCol(int surface, int colIndex) { RealEstateManager.SetCol(_idx, surface, colIndex); } public void ToggleObj(int objIndex) { RealEstateManager.ToggleObj(_idx, objIndex); } } [CompilerGenerated] private static class <>O { public static MobTransaction <0>__BuyVillaFromApp; public static MobTransaction <1>__SellVillaFromApp; public static Func <2>__AnyLagerOwnedView; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__63_0; public static Func <>9__63_1; public static Func <>9__63_2; public static Func <>9__63_3; public static Func <>9__63_4; public static Func <>9__63_5; public static Func <>9__71_0; public static MobTransaction <>9__71_1; public static Func <>9__72_0; public static Action <>9__72_1; public static Func <>9__72_2; public static Action <>9__72_3; public static Func <>9__72_4; public static Action <>9__72_5; public static Func <>9__72_6; public static Action <>9__72_7; public static MobTransaction <>9__75_0; public static MobTransaction <>9__75_1; public static MobTransaction <>9__75_2; public static MobTransaction <>9__75_3; public static MobTransaction <>9__75_4; public static MobTransaction <>9__75_5; public static Func <>9__76_0; public static Func <>9__81_0; public static Func <>9__81_1; public static Func <>9__81_2; public static Func <>9__81_3; internal bool b__63_0() { return LittleHelper.GiveCalabrianBrick(); } internal Sprite b__63_1() { return LittleHelper.GetItemIcon("cream"); } internal bool b__63_2() { return LittleHelper.GiveBomb(); } internal Sprite b__63_3() { return LittleHelper.GetItemIcon("bomb"); } internal bool b__63_4() { return LittleHelper.GiveGoldenM1912(); } internal Sprite b__63_5() { return LittleHelper.GetItemIcon("m1912"); } internal bool b__71_0() { return TerritoryHandover.IsBossForLocalPeer && !GangWarManager.IsActive && !GangBattleManager.IsActive; } internal bool b__71_1(out string m) { if (!SessionGate.IsAuthority) { ClientActionNet.SendAction("hq", "gangwar"); m = "Word's out, boss — the Famiglia's rolling out to the docks."; return true; } bool flag = GangWarManager.Declare(); m = (flag ? "We move now, boss. They won't see it coming." : "Not now, boss — we've already got a fight on our hands."); return flag; } internal bool b__72_0() { return true; } internal void b__72_1() { RapimentoManager.StartRapimentoFromChat(); } internal bool b__72_2() { return true; } internal void b__72_3() { RapimentoManager.StartTortura(); } internal bool b__72_4() { return true; } internal void b__72_5() { RapimentoManager.StartEsecuzione(); } internal bool b__72_6() { return true; } internal void b__72_7() { CarBombManager.BeginPlacementFromChat(); } internal bool b__75_0(out string m) { bool flag = PizzoJobManager.StartSmugglingFromChat(weapons: true); m = (flag ? "Weapons run ordered — details in the Don's chat." : "Couldn't start that run — check the Don's chat."); return flag; } internal bool b__75_1(out string m) { bool flag = PizzoJobManager.StartSmugglingFromChat(weapons: false); m = (flag ? "Drug run ordered — details in the Don's chat." : "Couldn't start that run — check the Don's chat."); return flag; } internal bool b__75_2(out string m) { bool flag = PizzoJobManager.StartProtectionFromChat(); m = (flag ? "Protection collection ordered — details in the Don's chat." : "No collection lined up — check the Don's chat."); return flag; } internal bool b__75_3(out string m) { bool flag = LuckyBrawlManager.StartBrawlFromChat(officers: true); m = (flag ? "Scouting badges — confirm the hit in the Don's chat." : "No badges to hit right now — check the Don's chat."); return flag; } internal bool b__75_4(out string m) { bool flag = LuckyBrawlManager.StartBrawlFromChat(officers: false); m = (flag ? "Scouting Benzies — confirm the hit in the Don's chat." : "No Benzies to crash right now — check the Don's chat."); return flag; } internal bool b__75_5(out string m) { bool flag = InformantiManager.StartFromChat(); m = (flag ? "Reaching out to our informants — watch your phone." : "No informant work right now — check the Don's chat."); return flag; } internal bool b__76_0() { return true; } internal string b__81_0() { string buildingName = VillaLocator.BuildingName; return string.IsNullOrEmpty(buildingName) ? "The Villa (Uptown)" : ("The Villa — " + buildingName); } internal Sprite b__81_1() { return AssetLoader.LoadSprite("Ndrangheta.assets.Villa.villa.png"); } internal bool b__81_2() { return RealEstateManager.VillaOwnedView; } internal string b__81_3() { return RealEstateManager.VillaOwnedView ? "OWNED" : RealEstateManager.VillaStatusText(); } } private List _faida; private List _hq; private List _shop; private List _ops; private MobOperation _faidaAction; private List _props; private List _furnish; public override string Id => "ndrangheta"; public override string DisplayName => "Ndrangheta"; public override bool Available => true; public override bool AppUnlocked => TerritoryHandover.IsBossForLocalPeer; public override string AppLockedTitle => "ACCESS DENIED"; public override string AppLockedText => "You're not the Boss yet.\n\nThe Don still runs the famiglia. Finish his contracts and earn the territory — once he hands it over, this line opens up."; public override string BrandTitle => "THE MOB"; public override string BrandSubtitle => "CALABRIA"; public override string Motto => "OMERTA"; public override string HomeTitle => "LA FAMIGLIA"; public override Color Accent => new Color(0.1f, 0.22f, 0.4f); public override Color Highlight => new Color(0.83f, 0.69f, 0.22f); private static int LocalFearPoints => SessionGate.IsAuthority ? FearState.Points : QuestNetSync.RemoteFearPoints; private static int LocalFaidaPoints => SessionGate.IsAuthority ? FaidaState.BenziePoints : QuestNetSync.RemoteFaidaPoints; private static int LocalTriadPoints => SessionGate.IsAuthority ? FaidaState.TriadPoints : QuestNetSync.RemoteTriadPoints; public override string MoralTitle => TerritoryHandover.IsBossForLocalPeer ? FearState.TitleUpperFromPoints(LocalFearPoints) : ""; public override bool FaidaUnlocked => TerritoryHandover.IsBossForLocalPeer; public override string FaidaTitle => "FAIDA"; public override string FaidaLockedText => "Locked.\n\nFinish the Don's business and earn the territory first — the feud is the Boss's to wage."; public override string FaidaEmptyText => "No bad blood on the books yet.\nTorture a Benzie and make them talk to start the feud."; public override string FaidaIntro { get { try { string text = FearState.TitleNameFromPoints(LocalFearPoints); int localFaidaPoints = LocalFaidaPoints; int localTriadPoints = LocalTriadPoints; string text2 = "Your name on the street: " + text + ".\n" + string.Format("{0} Benzie shipment{1} taken · {2} gang war{3} won vs. the Triads.", localFaidaPoints, (localFaidaPoints == 1) ? "" : "s", localTriadPoints, (localTriadPoints == 1) ? "" : "s"); if (SessionGate.IsAuthority && !FearState.IsMaxed) { text2 += string.Format("\n{0} more clean interrogation{1} to the next title.", FearState.PointsToNext, (FearState.PointsToNext == 1) ? "" : "s"); } return text2; } catch { return ""; } } } public override IReadOnlyList FaidaTargets { get { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown int localFaidaPoints = LocalFaidaPoints; if (_faida == null) { _faida = new List(3); } _faida.Clear(); _faida.Add(new MobFaidaTarget("Benzies", localFaidaPoints, string.Format("{0} shipment{1} taken", localFaidaPoints, (localFaidaPoints == 1) ? "" : "s"))); int localTriadPoints = LocalTriadPoints; _faida.Add(new MobFaidaTarget("Triads", localTriadPoints, (localTriadPoints > 0) ? string.Format("Sun Yee On routed — {0} gang war{1} won against the Triads", localTriadPoints, (localTriadPoints == 1) ? "" : "s") : "Sun Yee On — new blood muscling in on the docks")); _faida.Add(new MobFaidaTarget("I Corvi", 0, "An old vendetta from the old country — the embers still burn")); return _faida; } } public override bool RealEstateUnlocked => TerritoryHandover.IsBossForLocalPeer; public override string RealEstateLockedText => "Locked.\n\nFinish the Don's business first — the famiglia buys nothing while he watches."; public override MobLockedPage ListaNera => new MobLockedPage("LISTA NERA", "Bounty board — coming soon. For now the Don's chat handles the contracts."); public override MobLockedPage Cassa => new MobLockedPage("CASSA", "The famiglia vault — coming soon. The Gazebo stash holds the money for now."); public override bool HeadquarterUnlocked => TerritoryHandover.IsBossForLocalPeer; public override string HeadquarterLockedText => "Locked.\n\nFinish the Don's contracts first — the famiglia takes its own orders only once he hands you the territory."; public override IReadOnlyList HeadquarterActions => _hq ?? (_hq = BuildHeadquarter()); public override IReadOnlyList ShopItems { get { //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_0076: Expected O, but got Unknown //IL_00ab: 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_00da: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown List list = _shop; if (list == null) { List obj = new List { new MobShopItem("cream", "Calabrian Cream — Brick", "Famiglia-grade, white star.\nWholesale brick, move it your way.", 2500, (Func)(() => LittleHelper.GiveCalabrianBrick())) { IconFunc = () => LittleHelper.GetItemIcon("cream") }, new MobShopItem("bomb", "Pacco Bomba", "One charge, ready to plant.\nFor when talking stops working.", 1500, (Func)(() => LittleHelper.GiveBomb())) { IconFunc = () => LittleHelper.GetItemIcon("bomb") }, new MobShopItem("m1912", "M1912 — Gold", "The boss's piece, solid gold.\nStraight from our man at the warehouse.", 5000, (Func)(() => LittleHelper.GiveGoldenM1912())) { IconFunc = () => LittleHelper.GetItemIcon("m1912") } }; List list2 = obj; _shop = obj; list = list2; } return list; } } public override bool OperationsUnlocked => TerritoryHandover.IsBossForLocalPeer; public override IReadOnlyList Operations => _ops ?? (_ops = BuildOperations()); public override MobOperation FaidaAction { get { //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_0061: Expected O, but got Unknown //IL_0066: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown MobOperation obj = _faidaAction; if (obj == null) { Func obj2 = () => TerritoryHandover.IsBossForLocalPeer && !GangWarManager.IsActive && !GangBattleManager.IsActive; object obj3 = <>c.<>9__71_1; if (obj3 == null) { MobTransaction val = delegate(out string m) { if (!SessionGate.IsAuthority) { ClientActionNet.SendAction("hq", "gangwar"); m = "Word's out, boss — the Famiglia's rolling out to the docks."; return true; } bool flag = GangWarManager.Declare(); m = (flag ? "We move now, boss. They won't see it coming." : "Not now, boss — we've already got a fight on our hands."); return flag; }; <>c.<>9__71_1 = val; obj3 = (object)val; } MobOperation val2 = new MobOperation("gangwar", "DECLARE WAR", "Bring the whole Famiglia to the docks and end it — Don Salvatore against Sun Yee On and his Triads. Win the street or lose it.", (Sprite[])null, (float[])null, obj2, (MobTransaction)obj3); MobOperation val3 = val2; _faidaAction = val2; obj = val3; } return obj; } } public override IReadOnlyList Properties => _props ?? (_props = BuildProperties()); public override IReadOnlyList FurnishTargets => _furnish ?? (_furnish = BuildFurnishTargets()); public override string FurnishEmptyText => "Buy the Villa or a Deposito in Real Estate first."; public override string GetHomeText() { try { bool isBossForLocalPeer = TerritoryHandover.IsBossForLocalPeer; string arg = (RealEstateManager.VillaOwnedView ? "the Villa is ours" : "no base yet"); int num = 0; for (int i = 0; i < 3; i++) { if (RealEstateManager.LagerOwnedView(i)) { num++; } } return "Ndrangheta\n" + (isBossForLocalPeer ? "You run the famiglia now, boss." : "The Don still runs the business. Earn his trust.") + "\n" + $"Holdings: {arg}, {num}/3 depositi.\n\n" + "La famiglia prima di tutto."; } catch { return ""; } } private static List BuildOperations() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown Gif.GifFrames gifFrames = Gif.Load("Ndrangheta.assets.gif.kidnap.gif"); Gif.GifFrames gifFrames2 = Gif.Load("Ndrangheta.assets.gif.torture.gif"); Gif.GifFrames gifFrames3 = Gif.Load("Ndrangheta.assets.gif.execution.gif"); Gif.GifFrames gifFrames4 = Gif.Load("Ndrangheta.assets.gif.car-bomb.gif"); return new List { new MobOperation("OpKidnap", "Kidnapping", "Snatch a mark off the street, bag them and run them out in the van. Hold them a while, then turn them loose — shaken, bloodied and not talking to anyone.", gifFrames?.Frames, gifFrames?.Delays, (Func)(() => true), CoopOp("OpKidnap", delegate { RapimentoManager.StartRapimentoFromChat(); })), new MobOperation("OpTorture", "Torture", "Grab a Benzie and work them over in the back of the van until they give up a name. Every session they survive feeds the faida against their crew.", gifFrames2?.Frames, gifFrames2?.Delays, (Func)(() => true), CoopOp("OpTorture", delegate { RapimentoManager.StartTortura(); })), new MobOperation("OpExecution", "Execution", "Same as a snatch, but the mark doesn't ride back. Drive them out, finish the job, and leave no loose ends behind.", gifFrames3?.Frames, gifFrames3?.Delays, (Func)(() => true), CoopOp("OpExecution", delegate { RapimentoManager.StartEsecuzione(); })), new MobOperation("OpCarBomb", "Car Bomb", "Wire a charge under a target's car and walk away. When they turn the key, the whole street gets the message.", gifFrames4?.Frames, gifFrames4?.Delays, (Func)(() => true), LocalOp(delegate { CarBombManager.BeginPlacementFromChat(); })) }; } private static MobTransaction LocalOp(Action run) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown return (MobTransaction)delegate(out string m) { try { run(); } catch { } m = "On it, boss — watch your phone."; return true; }; } private static MobTransaction CoopOp(string key, Action hostStart) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return (MobTransaction)delegate(out string m) { if (!SessionGate.IsAuthority) { ClientActionNet.SendAction("hq", key); m = "Word's out to the crew — watch your phone."; return true; } try { hostStart(); } catch { } m = "It's in motion — watch your phone."; return true; }; } private static List BuildHeadquarter() { //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) //IL_0030: 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_0065: 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_009a: Expected O, but got Unknown //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: Expected O, but got Unknown //IL_00f9: 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_0104: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown //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_0139: Expected O, but got Unknown List list = new List(); object obj = <>c.<>9__75_0; if (obj == null) { MobTransaction val = delegate(out string m) { bool flag = PizzoJobManager.StartSmugglingFromChat(weapons: true); m = (flag ? "Weapons run ordered — details in the Don's chat." : "Couldn't start that run — check the Don's chat."); return flag; }; <>c.<>9__75_0 = val; obj = (object)val; } list.Add((IMobAction)(object)CoopHq("SmugWeapons", "Smuggling — Weapons", (MobTransaction)obj)); object obj2 = <>c.<>9__75_1; if (obj2 == null) { MobTransaction val2 = delegate(out string m) { bool flag = PizzoJobManager.StartSmugglingFromChat(weapons: false); m = (flag ? "Drug run ordered — details in the Don's chat." : "Couldn't start that run — check the Don's chat."); return flag; }; <>c.<>9__75_1 = val2; obj2 = (object)val2; } list.Add((IMobAction)(object)CoopHq("SmugDrugs", "Smuggling — Drugs", (MobTransaction)obj2)); object obj3 = <>c.<>9__75_2; if (obj3 == null) { MobTransaction val3 = delegate(out string m) { bool flag = PizzoJobManager.StartProtectionFromChat(); m = (flag ? "Protection collection ordered — details in the Don's chat." : "No collection lined up — check the Don's chat."); return flag; }; <>c.<>9__75_2 = val3; obj3 = (object)val3; } list.Add((IMobAction)(object)CoopHq("Protection", "Protection (Pizzo)", (MobTransaction)obj3)); object obj4 = <>c.<>9__75_3; if (obj4 == null) { MobTransaction val4 = delegate(out string m) { bool flag = LuckyBrawlManager.StartBrawlFromChat(officers: true); m = (flag ? "Scouting badges — confirm the hit in the Don's chat." : "No badges to hit right now — check the Don's chat."); return flag; }; <>c.<>9__75_3 = val4; obj4 = (object)val4; } list.Add((IMobAction)(object)CoopHq("BrawlOfficers", "Brawl — Officers", (MobTransaction)obj4)); object obj5 = <>c.<>9__75_4; if (obj5 == null) { MobTransaction val5 = delegate(out string m) { bool flag = LuckyBrawlManager.StartBrawlFromChat(officers: false); m = (flag ? "Scouting Benzies — confirm the hit in the Don's chat." : "No Benzies to crash right now — check the Don's chat."); return flag; }; <>c.<>9__75_4 = val5; obj5 = (object)val5; } list.Add((IMobAction)(object)CoopHq("BrawlBenzies", "Brawl — Benzies", (MobTransaction)obj5)); object obj6 = <>c.<>9__75_5; if (obj6 == null) { MobTransaction val6 = delegate(out string m) { bool flag = InformantiManager.StartFromChat(); m = (flag ? "Reaching out to our informants — watch your phone." : "No informant work right now — check the Don's chat."); return flag; }; <>c.<>9__75_5 = val6; obj6 = (object)val6; } list.Add((IMobAction)(object)CoopHq("Informanti", "Informanti (buy a tip)", (MobTransaction)obj6)); list.Add((IMobAction)new MobAction { Key = "RealEstate", Label = "Real Estate", NavigateTo = (MobAppTab)2 }); return list; } private static MobAction CoopHq(string key, string label, MobTransaction hostInvoke) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0055: 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_0067: Expected O, but got Unknown //IL_0069: Expected O, but got Unknown return new MobAction { Key = key, Label = label, AvailableFunc = () => true, InvokeFunc = (MobTransaction)delegate(out string m) { if (!SessionGate.IsAuthority) { ClientActionNet.SendAction("hq", key); m = "Order sent to the boss — watch your phone."; return true; } return hostInvoke.Invoke(ref m); } }; } internal static void HostTriggerHq(string key, string who = "") { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Invalid comparison between Unknown and I4 try { if (!SessionGate.IsAuthority || string.IsNullOrEmpty(key)) { return; } switch (key) { case "BrawlOfficers": LuckyBrawlManager.StartBrawlFromChat(officers: true, who); NDLog.Debug("[HQ] brawl(officers) for client '" + who + "'."); return; case "BrawlBenzies": LuckyBrawlManager.StartBrawlFromChat(officers: false, who); NDLog.Debug("[HQ] brawl(benzies) for client '" + who + "'."); return; case "OpKidnap": RapimentoManager.HostStartForClient(who, null); NDLog.Debug("[HQ] rapimento for client '" + who + "'."); return; case "OpTorture": RapimentoManager.StartTortura(who); NDLog.Debug("[HQ] tortura for client '" + who + "'."); return; case "OpExecution": RapimentoManager.StartEsecuzione(who); NDLog.Debug("[HQ] esecuzione for client '" + who + "'."); return; case "gangwar": GangWarManager.HostDeclareForClient(who); NDLog.Debug("[HQ] gang war for client '" + who + "'."); return; } string text = default(string); foreach (IMobAction item in BuildHeadquarter()) { if (item != null && item.Key == key && (int)item.NavigateTo == 0) { item.Invoke(ref text); NDLog.Debug("[HQ] client-requested action '" + key + "' executed on host."); return; } } NDLog.DebugWarn("[HQ] unknown client trigger key '" + key + "'."); } catch (Exception ex) { NDLog.Warn("HostTriggerHq(" + key + "): " + ex.Message); } } private static List BuildProperties() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_00d5: 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_00e0: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0153: 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) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_01a9: 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_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_01e5: 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_01f8: Expected O, but got Unknown //IL_01fe: Expected O, but got Unknown List list = new List(); MobProperty val = new MobProperty(); val.Key = "Villa"; val.NameFunc = delegate { string buildingName = VillaLocator.BuildingName; return string.IsNullOrEmpty(buildingName) ? "The Villa (Uptown)" : ("The Villa — " + buildingName); }; val.Description = "The famiglia base. Own driveway, tall hedge.\n4 men on the gate, patrols on the grounds."; val.ImageFunc = () => AssetLoader.LoadSprite("Ndrangheta.assets.Villa.villa.png"); val.OwnedFunc = () => RealEstateManager.VillaOwnedView; val.StatusFunc = () => RealEstateManager.VillaOwnedView ? "OWNED" : RealEstateManager.VillaStatusText(); object obj = <>O.<0>__BuyVillaFromApp; if (obj == null) { MobTransaction val2 = RealEstateManager.BuyVillaFromApp; <>O.<0>__BuyVillaFromApp = val2; obj = (object)val2; } val.BuyFunc = (MobTransaction)obj; object obj2 = <>O.<1>__SellVillaFromApp; if (obj2 == null) { MobTransaction val3 = RealEstateManager.SellVillaFromApp; <>O.<1>__SellVillaFromApp = val3; obj2 = (object)val3; } val.SellFunc = (MobTransaction)obj2; list.Add((IMobProperty)(object)val); string[] imgs = new string[3] { "westdocks", "downtown", "downtown2" }; for (int num = 0; num < 3; num++) { int idx = num; list.Add((IMobProperty)new MobProperty { Key = $"Lager{idx}", Name = RealEstateManager.SpotNames[idx], Description = "A quiet spot with a hidden room below.\nStep down, store what shouldn't be seen.", ImageFunc = () => AssetLoader.LoadSprite("Ndrangheta.assets.Lager." + imgs[idx] + ".png"), OwnedFunc = () => RealEstateManager.LagerOwnedView(idx), StatusFunc = () => RealEstateManager.LagerOwnedView(idx) ? "OWNED" : $"${7500:N0}", BuyFunc = (MobTransaction)delegate(out string m) { return RealEstateManager.BuyLagerFromApp(idx, out m); }, SellFunc = (MobTransaction)delegate(out string m) { return RealEstateManager.SellLagerFromApp(idx, out m); } }); } return list; } private static List BuildFurnishTargets() { List list = new List(); list.Add((IMobFurnishTarget)(object)new RealEstateFurnishTarget(0, "Il Deposito (warehouse)", RealEstateManager.AnyLagerOwnedView)); return list; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }