using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Il2CppFishNet; using Il2CppFishNet.Managing; using Il2CppFishNet.Object; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne.Cartel; using Il2CppScheduleOne.Combat; using Il2CppScheduleOne.Doors; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Behaviour; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.PlayerScripts.Health; using Il2CppScheduleOne.Police; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using MultiplayerPVP.Addons; using MultiplayerPVP.Core; using Riot; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonAdditionalDependencies(new string[] { "MultiplayerPVP" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: MelonInfo(typeof(RiotMod), "Riot", "1.0.1", "Virtunerd", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: AssemblyFileVersion("1.0.1")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyVersion("1.0.1.0")] [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 Riot { internal static class ChaosDirector { private const float RETARGET_INTERVAL = 1.5f; private const float NPC_GIVE_UP = 200f; private static readonly List _engaged = new List(); private static readonly List _civilians = new List(); private static float _cd; internal static bool On { get; private set; } internal static void SetOn(bool on) { if (On != on) { On = on; if (!on) { Teardown(); } else { _cd = 0f; } MelonLogger.Msg("[Riot] CHAOS " + (on ? "ON — the city hunts the players." : "OFF.")); } } internal static void Reset() { _engaged.Clear(); _civilians.Clear(); On = false; } internal static void Tick(float dt) { //IL_02f2: 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_022a: Unknown result type (might be due to invalid IL or missing references) if (!On) { return; } try { if (!RiotCompat.IsAuthority) { SetOn(on: false); return; } _cd -= dt; if (_cd > 0f) { return; } _cd = 1.5f; float num = Mathf.Clamp(RiotConfig.ChaosRadius.Value, 15f, 200f); 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) { Player val2 = NearestAlivePlayer(((Component)val).transform.position, num); if (!((Object)(object)val2 == (Object)null)) { SicNpc((NPC)(object)val, val2, civilian: false); } } } catch { } } } } catch { } if (!RiotConfig.CiviliansJoinChaos.Value) { return; } PruneCivilians(); int num2 = Mathf.Clamp(RiotConfig.MaxChaosCivilians.Value, 1, 16); try { List nPCRegistry = NPCManager.NPCRegistry; if (nPCRegistry != null) { for (int j = 0; j < nPCRegistry.Count; j++) { if (_civilians.Count >= num2) { break; } try { NPC val3 = nPCRegistry[j]; if ((Object)(object)val3 == (Object)null || (Object)(object)((Component)val3).transform == (Object)null || (Object)(object)RiotCompat.Cast((Object)(object)val3) != (Object)null || (Object)(object)RiotCompat.Cast((Object)(object)val3) != (Object)null) { continue; } NPCHealth health2 = val3.Health; if (!((Object)(object)health2 == (Object)null) && !health2.IsDead && !health2.IsKnockedOut) { Player val4 = NearestAlivePlayer(((Component)val3).transform.position, num); if (!((Object)(object)val4 == (Object)null) && SicNpc(val3, val4, civilian: true) && !_civilians.Contains(val3)) { _civilians.Add(val3); } } } catch { } } } } catch { } for (int k = 0; k < _civilians.Count; k++) { try { NPC val5 = _civilians[k]; if (!((Object)(object)val5 == (Object)null) && !((Object)(object)((Component)val5).transform == (Object)null)) { Player val6 = NearestAlivePlayer(((Component)val5).transform.position, num * 2f); if ((Object)(object)val6 != (Object)null) { SicNpc(val5, val6, civilian: true); } } } catch { } } } catch (Exception ex) { MelonLogger.Warning("[Riot] Chaos tick: " + ex.Message); } } private static bool SicNpc(NPC npc, Player target, bool civilian) { try { object obj; if (target == null) { obj = null; } else { GameObject gameObject = ((Component)target).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent() : null); } NetworkObject val = (NetworkObject)obj; object obj2; if (npc == null) { obj2 = null; } else { NPCBehaviour behaviour = npc.Behaviour; obj2 = ((behaviour != null) ? behaviour.CombatBehaviour : null); } CombatBehaviour val2 = (CombatBehaviour)obj2; if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } try { val2.GiveUpRange = 200f; } catch { } val2.SetTargetAndEnable_Server(val); if (!_engaged.Contains(npc)) { _engaged.Add(npc); } return true; } catch { return false; } } private static void PruneCivilians() { for (int num = _civilians.Count - 1; num >= 0; num--) { try { NPC val = _civilians[num]; NPCHealth val2 = (((Object)(object)val != (Object)null) ? val.Health : null); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null || (Object)(object)val2 == (Object)null || val2.IsDead || val2.IsKnockedOut) { _civilians.RemoveAt(num); } } catch { _civilians.RemoveAt(num); } } } internal static Player NearestAlivePlayer(Vector3 pos, float radius) { //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) Player result = null; float num = radius; try { List playerList = Player.PlayerList; if (playerList == null) { return null; } for (int i = 0; i < playerList.Count; i++) { try { Player val = playerList[i]; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { continue; } PlayerHealth componentInChildren = ((Component)val).GetComponentInChildren(true); if (!((Object)(object)componentInChildren != (Object)null) || componentInChildren.IsAlive) { float num2 = Vector3.Distance(((Component)val).transform.position, pos); if (num2 < num) { num = num2; result = val; } } } catch { } } } catch { } return result; } private static void Teardown() { for (int i = 0; i < _engaged.Count; i++) { try { NPC obj = _engaged[i]; object obj2; if (obj == null) { obj2 = null; } else { NPCBehaviour behaviour = obj.Behaviour; obj2 = ((behaviour != null) ? behaviour.CombatBehaviour : null); } CombatBehaviour val = (CombatBehaviour)obj2; if ((Object)(object)val != (Object)null) { try { ((Behaviour)val).Deactivate(); } catch { } try { ((Behaviour)val).Disable(); } catch { } } } catch { } } _engaged.Clear(); _civilians.Clear(); } } internal sealed class RiotAddon : PvpAddonBase { private PvpMatchToggle _riotToggle; private PvpMatchToggle _chaosToggle; private PvpChannel _channel; private int _seq; private readonly Dictionary _seen = new Dictionary(); private bool _chaosActiveLocal; private string _lastState = ""; private bool _prevRiotReq; private bool _prevChaosReq; public override string Id => "Riot"; public override void OnRegistered() { RiotConfig.Load(); _channel = PvpApi.Channel("riot"); if (_channel != null) { _channel.OnMessage += OnRiotMsg; } _riotToggle = PvpApi.RegisterMatchToggle("riot", "Riot", "City riot for this round: Benzies storm out of the door nearest each cop and brawl with the police while you play. Mutually exclusive with Chaos."); _chaosToggle = PvpApi.RegisterMatchToggle("chaos", "Chaos", "The city turns on YOU for this round: cops, Benzies and civilians hunt every player on sight until KO. NPC knock-outs confiscate weapons. Mutually exclusive with Riot."); if (_riotToggle != null) { _riotToggle.Activated += OnRiotActivated; _riotToggle.Deactivated += OnRoundDeactivated; } if (_chaosToggle != null) { _chaosToggle.Activated += OnChaosActivated; _chaosToggle.Deactivated += OnRoundDeactivated; } PvpApi.RegisterNpcKoAttributor((Func)IsKoFromChaos); } private void OnRiotActivated() { if (PvpApi.IsMultiplayer && RiotCompat.IsAuthority) { ChaosDirector.SetOn(on: false); RiotManager.SetOn(on: true); PublishState(); } } private void OnChaosActivated() { if (PvpApi.IsMultiplayer && RiotCompat.IsAuthority) { ChaosDirector.SetOn(on: true); RiotManager.SetOn(on: true); _chaosActiveLocal = true; PublishState(); } } private void OnRoundDeactivated() { bool flag = RiotManager.On || ChaosDirector.On; ChaosDirector.SetOn(on: false); RiotManager.SetOn(on: false); _chaosActiveLocal = false; if (flag) { PublishState(); } } public override void OnUpdate(float dt) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 try { if (_chaosToggle != null && _riotToggle != null) { bool requested = _riotToggle.Requested; bool requested2 = _chaosToggle.Requested; if (requested && requested2) { if (requested2 && !_prevChaosReq) { _riotToggle.Requested = false; } else { _chaosToggle.Requested = false; } } _prevRiotReq = _riotToggle.Requested; _prevChaosReq = _chaosToggle.Requested; } } catch { } bool flag = (int)PvpApi.Phase != 2 || !PvpApi.IsMultiplayer; if (ChaosDirector.On && flag) { ChaosDirector.SetOn(on: false); _chaosActiveLocal = false; } if (RiotManager.On && flag) { RiotManager.SetOn(on: false); } RiotManager.Tick(dt); ChaosDirector.Tick(dt); if (_channel != null) { List> list = _channel.ReadAll(); for (int i = 0; i < list.Count; i++) { OnRiotMsg(list[i].Key, list[i].Value); } } } private void PublishState() { bool flag = RiotManager.On && !ChaosDirector.On; string text = (flag ? "1" : "0") + "~" + (ChaosDirector.On ? "1" : "0"); ShowState(flag, ChaosDirector.On); PvpChannel channel = _channel; if (channel != null) { int num = ++_seq; channel.Publish(num + "~" + text); } } private void OnRiotMsg(ulong fromSteamId, string record) { if (string.IsNullOrEmpty(record) || (_seen.TryGetValue(fromSteamId, out var value) && value == record)) { return; } _seen[fromSteamId] = record; if (!RiotCompat.IsAuthority) { string[] array = record.Split('~'); if (array.Length >= 3) { bool riot = array[1] == "1"; ShowState(riot, _chaosActiveLocal = array[2] == "1"); } } } private void ShowState(bool riot, bool chaos) { //IL_005c: 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_0087: Unknown result type (might be due to invalid IL or missing references) string text = (riot ? "r" : "") + (chaos ? "c" : ""); if (!(text == _lastState)) { _lastState = text; if (chaos) { PvpApi.ShowLocalBanner("☠ CHAOS — the whole city is out for YOUR blood!", 5f, new Color(1f, 0.15f, 0.15f)); } else if (riot) { PvpApi.ShowLocalBanner("⚠ RIOT — the Benzies are out!", 5f, new Color(1f, 0.35f, 0.2f)); } else { PvpApi.ShowLocalBanner("The streets calm down.", 4f, Color.white); } } } private bool IsKoFromChaos() { //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_0169: 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_0209: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!_chaosActiveLocal) { return false; } try { 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; float num = float.MaxValue; List playerList = Player.PlayerList; if (playerList != null) { for (int i = 0; i < playerList.Count; i++) { try { Player val = playerList[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)local || (Object)(object)((Component)val).transform == (Object)null) { continue; } PlayerHealth componentInChildren = ((Component)val).GetComponentInChildren(true); if (!((Object)(object)componentInChildren != (Object)null) || componentInChildren.IsAlive) { float num2 = Vector3.Distance(position, ((Component)val).transform.position); if (num2 < num) { num = num2; } } } catch { } } } float num3 = float.MaxValue; try { List officers = PoliceOfficer.Officers; if (officers != null) { for (int j = 0; j < officers.Count; j++) { try { PoliceOfficer val2 = officers[j]; if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).transform == (Object)null)) { float num4 = Vector3.Distance(position, ((Component)val2).transform.position); if (num4 < num3) { num3 = num4; } } } catch { } } } } catch { } try { Il2CppArrayBase val3 = Object.FindObjectsOfType(); if (val3 != null) { for (int k = 0; k < val3.Length; k++) { try { CartelGoon val4 = val3[k]; if (!((Object)(object)val4 == (Object)null) && val4.IsGoonSpawned && !((Object)(object)((Component)val4).transform == (Object)null)) { float num5 = Vector3.Distance(position, ((Component)val4).transform.position); if (num5 < num3) { num3 = num5; } } } catch { } } } } catch { } return (num3 <= 25f && num3 < num) || num > 60f; } catch { return false; } } public override void OnSceneLoaded(int buildIndex, string sceneName) { RiotManager.Reset(); ChaosDirector.Reset(); _chaosActiveLocal = false; _seen.Clear(); _lastState = ""; } public override void OnDeinit() { ChaosDirector.SetOn(on: false); RiotManager.SetOn(on: false); RiotManager.Reset(); ChaosDirector.Reset(); try { PvpApi.UnregisterNpcKoAttributor((Func)IsKoFromChaos); } catch { } try { PvpApi.UnregisterMatchToggle(_riotToggle); } catch { } try { PvpApi.UnregisterMatchToggle(_chaosToggle); } catch { } } } internal static class RiotCompat { public static bool IsAuthority { get { try { NetworkManager networkManager = InstanceFinder.NetworkManager; if ((Object)(object)networkManager == (Object)null) { return true; } return networkManager.IsServer; } catch { return true; } } } public static T Cast(Object o) where T : Object { return (o == (Object)null) ? default(T) : ((Il2CppObjectBase)o).TryCast(); } public static T CastTargetable(Il2CppObjectBase o) where T : Il2CppObjectBase { return (o == null) ? default(T) : o.TryCast(); } } internal static class RiotConfig { internal static MelonPreferences_Entry BenziesPerOfficer; internal static MelonPreferences_Entry BenziesMax; internal static MelonPreferences_Entry OfficerScanRadius; internal static MelonPreferences_Entry DoorMaxDistance; internal static MelonPreferences_Entry WaveCooldownSeconds; internal static MelonPreferences_Entry OfficersFightBack; internal static MelonPreferences_Entry ChaosRadius; internal static MelonPreferences_Entry CiviliansJoinChaos; internal static MelonPreferences_Entry MaxChaosCivilians; private static bool _loaded; internal static void Load() { if (!_loaded) { _loaded = true; MelonPreferences_Category val = MelonPreferences.CreateCategory("Riot", "Riot"); BenziesPerOfficer = val.CreateEntry("BenziesPerOfficer", 2, "Benzies per officer", "How many Benzies gang up on each targeted officer (1-4).", false, false, (ValueValidator)null, (string)null); BenziesMax = val.CreateEntry("BenziesMax", 8, "Max active Benzies", "Hard cap of simultaneously active riot Benzies (1-16).", false, false, (ValueValidator)null, (string)null); OfficerScanRadius = val.CreateEntry("OfficerScanRadius", 80f, "Officer scan radius (m)", "Waves target the nearest under-staffed officer within this radius of ANY player.", false, false, (ValueValidator)null, (string)null); DoorMaxDistance = val.CreateEntry("DoorMaxDistance", 80f, "Door search radius (m)", "The Benzies spawn at the door nearest to the targeted officer within this radius (ring fallback beyond).", false, false, (ValueValidator)null, (string)null); WaveCooldownSeconds = val.CreateEntry("WaveCooldownSeconds", 20f, "Wave cooldown (s)", "Minimum seconds between spawn waves while the riot runs (min 5).", false, false, (ValueValidator)null, (string)null); OfficersFightBack = val.CreateEntry("OfficersFightBack", true, "Officers fight back", "Explicitly trigger officer counter-attacks (vanilla cops NEVER retaliate against NPCs on their own).", false, false, (ValueValidator)null, (string)null); ChaosRadius = val.CreateEntry("ChaosRadius", 60f, "Chaos radius (m)", "CHAOS toggle: cops/civilians within this radius of a player join the hunt against the players.", false, false, (ValueValidator)null, (string)null); CiviliansJoinChaos = val.CreateEntry("CiviliansJoinChaos", true, "Civilians join chaos", "CHAOS toggle: nearby civilian NPCs also attack players (fists). CAUTION: this can pull in other mods' NPCs that stand near a player.", false, false, (ValueValidator)null, (string)null); MaxChaosCivilians = val.CreateEntry("MaxChaosCivilians", 8, "Max chaos civilians", "CHAOS toggle: cap of civilians simultaneously hunting players (1-16).", false, false, (ValueValidator)null, (string)null); } } } internal static class RiotManager { private sealed class ActiveGoon { internal CartelGoon Goon; internal PoliceOfficer Target; internal Player TargetPlayer; internal float DespawnAt; } private const int POOL_RESERVE = 1; private const float GOON_GIVE_UP = 200f; private const float RETARGET_INTERVAL = 1.5f; private const float GOON_LIFETIME = 180f; private const float ORPHAN_RADIUS = 90f; private const float DOOR_FALLBACK_DIST = 18f; private static readonly List _active = new List(); private static readonly List _engagedOfficers = new List(); private static float _nextWave; private static float _retargetCd; internal static bool On { get; private set; } internal static int ActiveCount => _active.Count; internal static void SetOn(bool on) { if (On != on) { On = on; if (!on) { Teardown(); } else { _nextWave = 0f; _retargetCd = 0f; } MelonLogger.Msg("[Riot] " + (on ? "ON — Benzies are hunting the badges." : "OFF — streets calm down.")); } } internal static void Reset() { _active.Clear(); _engagedOfficers.Clear(); On = false; } internal static void Tick(float dt) { if (!On) { return; } try { if (!RiotCompat.IsAuthority) { SetOn(on: false); return; } float time = Time.time; Prune(time); _retargetCd -= dt; if (_retargetCd <= 0f) { _retargetCd = 1.5f; Retarget(); } if (time >= _nextWave && _active.Count < Mathf.Clamp(RiotConfig.BenziesMax.Value, 1, 16)) { _nextWave = time + Mathf.Max(5f, RiotConfig.WaveCooldownSeconds.Value); SpawnWave(); } } catch (Exception ex) { MelonLogger.Warning("[Riot] Tick: " + ex.Message); } } private static void SpawnWave() { //IL_020d: 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_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_00e8: 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_00cb: 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_02b7: 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) int num = Mathf.Clamp(RiotConfig.BenziesPerOfficer.Value, 1, 4); int num2 = Mathf.Clamp(RiotConfig.BenziesMax.Value, 1, 16); if (_active.Count >= num2) { return; } PoliceOfficer val; Vector3 officerPos; if (ChaosDirector.On) { val = NearestOfficerToAnyPlayer(RiotConfig.OfficerScanRadius.Value, int.MaxValue, out officerPos); if ((Object)(object)val == (Object)null && !TryAnyAlivePlayerPos(out officerPos)) { return; } } else { val = NearestOfficerToAnyPlayer(RiotConfig.OfficerScanRadius.Value, num, out officerPos); if ((Object)(object)val == (Object)null) { return; } } if (!TryNearestDoor(officerPos, RiotConfig.DoorMaxDistance.Value, out var doorPos)) { doorPos = officerPos + RandomRingDir() * 18f; } doorPos = NavPoint(doorPos); GoonPool val2 = Object.FindObjectOfType(true); if ((Object)(object)val2 == (Object)null) { return; } int num3; try { num3 = val2.UnspawnedGoonCount - 1; } catch { return; } int num4 = (ChaosDirector.On ? num : (num - AssignedCount(val))); int num5 = Mathf.Min(num4, Mathf.Min(num3, num2 - _active.Count)); if (num5 <= 0) { return; } List val3 = val2.SpawnMultipleGoons(doorPos, num5, false); if (val3 == null) { return; } int num6 = 0; for (int i = 0; i < val3.Count; i++) { CartelGoon val4 = val3[i]; if ((Object)(object)val4 == (Object)null) { continue; } try { NPCBehaviour behaviour = ((NPC)val4).Behaviour; CombatBehaviour val5 = ((behaviour != null) ? behaviour.CombatBehaviour : null); if ((Object)(object)val5 != (Object)null) { val5.GiveUpRange = 200f; } } catch { } ActiveGoon activeGoon = new ActiveGoon { Goon = val4, DespawnAt = Time.time + 180f }; if (ChaosDirector.On) { Player val6 = ChaosDirector.NearestAlivePlayer(doorPos, 180f); if ((Object)(object)val6 != (Object)null && SicPlayer(activeGoon, val6)) { num6++; } } else if (Sic(activeGoon, val)) { num6++; } _active.Add(activeGoon); } if (num6 > 0) { MelonLogger.Msg($"[Riot] Wave: {num6} Benzies out of the door at {doorPos} → officer hunt ({_active.Count} active)."); } } private static int AssignedCount(PoliceOfficer officer) { int num = 0; for (int i = 0; i < _active.Count; i++) { try { if ((Object)(object)_active[i].Target == (Object)(object)officer) { num++; } } catch { } } return num; } private static void Retarget() { //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_00a8: 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) for (int num = _active.Count - 1; num >= 0; num--) { ActiveGoon activeGoon = _active[num]; Vector3 position; try { position = ((Component)activeGoon.Goon).transform.position; } catch { Despawn(num); continue; } if (ChaosDirector.On) { if (PlayerInvalid(activeGoon.TargetPlayer)) { Player val = ChaosDirector.NearestAlivePlayer(position, 180f); if ((Object)(object)val != (Object)null) { SicPlayer(activeGoon, val); } } continue; } activeGoon.TargetPlayer = null; if (TargetInvalid(activeGoon.Target)) { PoliceOfficer val2 = NearestOfficerTo(position, 90f); if ((Object)(object)val2 == (Object)null) { Despawn(num); } else { Sic(activeGoon, val2); } } } } private static bool SicPlayer(ActiveGoon ag, Player prey) { try { ICombatTargetable val = RiotCompat.CastTargetable((Il2CppObjectBase)(object)prey); if (val == null) { return false; } bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (!flag) { return false; } ag.Goon.AttackEntity(val, false); ag.TargetPlayer = prey; ag.Target = null; return true; } catch { return false; } } private static bool PlayerInvalid(Player p) { try { if ((Object)(object)p == (Object)null || (Object)(object)((Component)p).transform == (Object)null) { return true; } PlayerHealth componentInChildren = ((Component)p).GetComponentInChildren(true); return (Object)(object)componentInChildren != (Object)null && !componentInChildren.IsAlive; } catch { return true; } } private static bool TryAnyAlivePlayerPos(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_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) pos = Vector3.zero; try { List playerList = Player.PlayerList; if (playerList == null) { return false; } for (int i = 0; i < playerList.Count; i++) { Player val = playerList[i]; if (!PlayerInvalid(val)) { pos = ((Component)val).transform.position; return true; } } } catch { } return false; } private static void Prune(float now) { for (int num = _active.Count - 1; num >= 0; num--) { ActiveGoon activeGoon = _active[num]; bool flag; try { flag = (Object)(object)activeGoon.Goon == (Object)null || !activeGoon.Goon.IsGoonSpawned; } catch { flag = true; } if (flag) { _active.RemoveAt(num); } else if (now >= activeGoon.DespawnAt) { Despawn(num); } } } private static void Despawn(int idx) { try { CartelGoon goon = _active[idx].Goon; if ((Object)(object)goon != (Object)null && goon.IsGoonSpawned) { goon.Despawn(); } } catch { } _active.RemoveAt(idx); } private static bool Sic(ActiveGoon ag, PoliceOfficer officer) { try { ICombatTargetable val = RiotCompat.CastTargetable((Il2CppObjectBase)(object)officer); if (val == null) { return false; } bool flag = false; try { flag = !val.IsNull() && val.IsCurrentlyTargetable; } catch { } if (!flag) { return false; } ag.Goon.AttackEntity(val, false); ag.Target = officer; ag.TargetPlayer = null; if (RiotConfig.OfficersFightBack.Value && !ChaosDirector.On) { try { CartelGoon goon = ag.Goon; object obj2; if (goon == null) { obj2 = null; } else { GameObject gameObject = ((Component)goon).gameObject; obj2 = ((gameObject != null) ? gameObject.GetComponent() : null); } NetworkObject val2 = (NetworkObject)obj2; object obj3; if (officer == null) { obj3 = null; } else { NPCBehaviour behaviour = ((NPC)officer).Behaviour; obj3 = ((behaviour != null) ? behaviour.CombatBehaviour : null); } CombatBehaviour val3 = (CombatBehaviour)obj3; if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null) { val3.SetTargetAndEnable_Server(val2); if (!_engagedOfficers.Contains(officer)) { _engagedOfficers.Add(officer); } } } catch { } } return true; } catch (Exception ex) { MelonLogger.Warning("[Riot] Sic: " + ex.Message); return false; } } private static void Teardown() { for (int i = 0; i < _engagedOfficers.Count; i++) { try { PoliceOfficer obj = _engagedOfficers[i]; object obj2; if (obj == null) { obj2 = null; } else { NPCBehaviour behaviour = ((NPC)obj).Behaviour; obj2 = ((behaviour != null) ? behaviour.CombatBehaviour : null); } CombatBehaviour val = (CombatBehaviour)obj2; if ((Object)(object)val != (Object)null) { try { ((Behaviour)val).Deactivate(); } catch { } try { ((Behaviour)val).Disable(); } catch { } } } catch { } } _engagedOfficers.Clear(); for (int j = 0; j < _active.Count; j++) { try { CartelGoon goon = _active[j].Goon; if ((Object)(object)goon != (Object)null && goon.IsGoonSpawned) { goon.Despawn(); } } catch { } } _active.Clear(); } private static bool TargetInvalid(PoliceOfficer o) { try { if ((Object)(object)o == (Object)null || (Object)(object)((Component)o).transform == (Object)null) { return true; } NPCHealth health = ((NPC)o).Health; return (Object)(object)health == (Object)null || health.IsDead || health.IsKnockedOut; } catch { return true; } } private static PoliceOfficer NearestOfficerToAnyPlayer(float radius, int perOfficer, out Vector3 officerPos) { //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_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_00a5: 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_00d5: 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) officerPos = Vector3.zero; PoliceOfficer result = null; float num = float.MaxValue; try { List officers = PoliceOfficer.Officers; List playerList = Player.PlayerList; if (officers == null || playerList == null) { return null; } for (int i = 0; i < officers.Count; i++) { try { PoliceOfficer val = officers[i]; if (TargetInvalid(val) || AssignedCount(val) >= perOfficer) { continue; } Vector3 position = ((Component)val).transform.position; for (int j = 0; j < playerList.Count; j++) { Player val2 = playerList[j]; if (!((Object)(object)val2 == (Object)null)) { float num2 = Vector3.Distance(position, ((Component)val2).transform.position); if (num2 <= radius && num2 < num) { num = num2; result = val; officerPos = position; } } } } catch { } } } catch (Exception ex) { MelonLogger.Warning("[Riot] OfficerScan: " + ex.Message); } return result; } private static PoliceOfficer NearestOfficerTo(Vector3 pos, float radius) { //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) PoliceOfficer result = null; float num = radius; try { List officers = PoliceOfficer.Officers; if (officers == null) { return null; } for (int i = 0; i < officers.Count; i++) { try { PoliceOfficer val = officers[i]; if (!TargetInvalid(val)) { float num2 = Vector3.Distance(((Component)val).transform.position, pos); if (num2 < num) { num = num2; result = val; } } } catch { } } } catch { } return result; } private static bool TryNearestDoor(Vector3 from, float maxDistance, out Vector3 doorPos) { //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_0080: 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_0085: 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_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_0096: 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) doorPos = from; try { Il2CppArrayBase val = Object.FindObjectsOfType(); if (val == null || val.Length == 0) { return false; } float num = maxDistance * maxDistance; bool result = false; for (int i = 0; i < val.Length; i++) { StaticDoor val2; try { val2 = val[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; doorPos = val3; result = true; } } } return result; } catch { return false; } } 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 NavPoint(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; } } public class RiotMod : MelonMod { private RiotAddon _addon; public override void OnInitializeMelon() { _addon = new RiotAddon(); if (PvpApi.RegisterAddon((IPvpAddon)(object)_addon)) { MelonLogger.Msg("[Riot] registered with MultiplayerPVP."); } else { MelonLogger.Warning("[Riot] registration failed — is MultiplayerPVP loaded?"); } } public override void OnDeinitializeMelon() { try { PvpApi.UnregisterAddon((IPvpAddon)(object)_addon); } catch { } } } }