Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DroneImprovements v1.1.0
DroneImprovements.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DroneImprovements.Skills; using EntityStates; using HarmonyLib; using Microsoft.CodeAnalysis; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; using RoR2.ContentManagement; using RoR2.Navigation; using RoR2.Networking; using RoR2.Orbs; using RoR2.Skills; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DroneImprovements")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DroneImprovements")] [assembly: AssemblyTitle("DroneImprovements")] [assembly: AssemblyVersion("1.0.0.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 DroneImprovements { internal static class DroneBodySetup { public static void OnGameLoaded() { int num = 0; foreach (DroneDef allDroneDef in DroneCatalog.allDroneDefs) { if (!Object.op_Implicit((Object)(object)allDroneDef) || !Object.op_Implicit((Object)(object)allDroneDef.remoteOpBody)) { continue; } num++; GameObject remoteOpBody = allDroneDef.remoteOpBody; StringBuilder stringBuilder = new StringBuilder(((Object)remoteOpBody).name); if (!Object.op_Implicit((Object)(object)remoteOpBody.GetComponent<Interactor>())) { remoteOpBody.AddComponent<Interactor>().maxInteractionDistance = 3f; stringBuilder.Append(" [added Interactor]"); } if (!Object.op_Implicit((Object)(object)remoteOpBody.GetComponent<InteractionDriver>())) { if (Object.op_Implicit((Object)(object)remoteOpBody.GetComponent<InputBankTest>())) { remoteOpBody.AddComponent<InteractionDriver>(); stringBuilder.Append(" [added InteractionDriver]"); } else { stringBuilder.Append(" [no InputBankTest, cannot interact]"); } } SkillLocator component = remoteOpBody.GetComponent<SkillLocator>(); if (Object.op_Implicit((Object)(object)component)) { stringBuilder.Append(" skills:"); AppendSkill(stringBuilder, "primary", component.primary); AppendSkill(stringBuilder, "secondary", component.secondary); AppendSkill(stringBuilder, "utility", component.utility); AppendSkill(stringBuilder, "special", component.special); } DroneImprovementsPlugin.Log.LogInfo((object)stringBuilder.ToString()); } DroneImprovementsPlugin.Log.LogInfo((object)$"Prepared {num} remote-op drone bodies."); } private static void AppendSkill(StringBuilder log, string slot, GenericSkill skill) { object obj; if (!Object.op_Implicit((Object)(object)skill)) { obj = null; } else { SkillFamily skillFamily = skill.skillFamily; obj = ((skillFamily != null) ? skillFamily.defaultSkillDef : null); } SkillDef val = (SkillDef)obj; if (Object.op_Implicit((Object)(object)val)) { log.Append(' ').Append(slot).Append('=') .Append(val.skillName ?? ((Object)val).name); } } } internal static class DroneNetworking { private class DisconnectRequestMessage : MessageBase { public GameObject networkUserObject; public override void Serialize(NetworkWriter writer) { writer.Write(networkUserObject); } public override void Deserialize(NetworkReader reader) { networkUserObject = reader.ReadGameObject(); } } [HarmonyPatch(typeof(NetworkMessageHandlerAttribute), "RegisterServerMessages")] private static class RegisterServerMessagesPatch { [CompilerGenerated] private static class <>O { public static NetworkMessageDelegate <0>__HandleDisconnectRequest; } private static void Postfix() { //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_0020: Expected O, but got Unknown object obj = <>O.<0>__HandleDisconnectRequest; if (obj == null) { NetworkMessageDelegate val = HandleDisconnectRequest; <>O.<0>__HandleDisconnectRequest = val; obj = (object)val; } NetworkServer.RegisterHandler((short)17392, (NetworkMessageDelegate)obj); } } public const short DisconnectRequestMsgType = 17392; private static readonly MethodInfo deathFootPositionSetter = AccessTools.PropertySetter(typeof(CharacterMaster), "deathFootPosition"); private static readonly MethodInfo lostBodyToDeathSetter = AccessTools.PropertySetter(typeof(CharacterMaster), "lostBodyToDeath"); private static readonly FieldRef<CharacterMaster, bool> preventRespawnUntilNextStageServer = AccessTools.FieldRefAccess<CharacterMaster, bool>("preventRespawnUntilNextStageServer"); private static readonly MethodInfo restoreOriginalBodyPrefab = AccessTools.Method(typeof(CharacterMaster), "RestoreOriginalBodyPrefab", (Type[])null, (Type[])null); private static GameObject disconnectEffectPrefab; public static void RequestDisconnect(CharacterBody drone) { CharacterMaster val = (Object.op_Implicit((Object)(object)drone) ? drone.master : null); if (!Object.op_Implicit((Object)(object)val)) { return; } if (NetworkServer.active) { ServerDisconnect(val); return; } NetworkUser val2 = (Object.op_Implicit((Object)(object)val.playerCharacterMasterController) ? val.playerCharacterMasterController.networkUser : null); if (Object.op_Implicit((Object)(object)val2)) { NetworkConnection readyConnection = ClientScene.readyConnection; if (readyConnection != null) { readyConnection.Send((short)17392, (MessageBase)(object)new DisconnectRequestMessage { networkUserObject = ((Component)val2).gameObject }); } } } private static void HandleDisconnectRequest(NetworkMessage netMsg) { DisconnectRequestMessage disconnectRequestMessage = netMsg.ReadMessage<DisconnectRequestMessage>(); NetworkUser val = (Object.op_Implicit((Object)(object)disconnectRequestMessage.networkUserObject) ? disconnectRequestMessage.networkUserObject.GetComponent<NetworkUser>() : null); if (Object.op_Implicit((Object)(object)val)) { NetworkConnection connectionToClient = ((NetworkBehaviour)val).connectionToClient; if (connectionToClient == null || netMsg.conn == null || connectionToClient.connectionId != netMsg.conn.connectionId) { DroneImprovementsPlugin.Log.LogWarning((object)("Rejected drone disconnect request for " + val.userName + " from a connection that does not own it.")); } else { ServerDisconnect(val.master); } } } public static void ServerDisconnect(CharacterMaster master) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)master)) { return; } CharacterBody body = master.GetBody(); if (DroneUtil.IsDronePlayer(body) && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive) { SpawnDisconnectEffect(body); deathFootPositionSetter.Invoke(master, new object[1] { body.footPosition }); lostBodyToDeathSetter.Invoke(master, new object[1] { true }); master.preventGameOver = false; preventRespawnUntilNextStageServer.Invoke(master) = true; master.inventory.SetEquipmentDisabled(false); if (Object.op_Implicit((Object)(object)((Component)body).GetComponent<Inventory>())) { Object.Destroy((Object)(object)((Component)body).gameObject); master.OnBodyDestroyed(body); } else { master.DestroyBody(); } restoreOriginalBodyPrefab.Invoke(master, null); DroneImprovementsPlugin.Log.LogInfo((object)(((Object)master).name + " disconnected from their drone.")); } } private static void SpawnDisconnectEffect(CharacterBody body) { //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_0033: 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_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_005a: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)disconnectEffectPrefab)) { disconnectEffectPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/TeleportOutBoom"); } if (Object.op_Implicit((Object)(object)disconnectEffectPrefab)) { EffectManager.SpawnEffect(disconnectEffectPrefab, new EffectData { origin = body.corePosition, rotation = Quaternion.identity, scale = body.radius }, true); } } } internal static class DroneTeleport { private static readonly List<CharacterBody> candidates = new List<CharacterBody>(); private static readonly float[] ringDistances = new float[4] { 4f, 6f, 2.5f, 9f }; private static readonly float[] flierHeights = new float[3] { 2.5f, 1.5f, 4f }; private static readonly float[] groundHeights = new float[1]; private static GameObject teleportEffectPrefab; public static bool TryTeleport(CharacterBody drone, out string failReason) { //IL_003d: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006d: Unknown result type (might be due to invalid IL or missing references) CharacterBody val = FindNearestTarget(drone); if (!Object.op_Implicit((Object)(object)val)) { failReason = "No living player to teleport to."; return false; } if (!TryFindDestination(drone, val, out var destinationCore)) { failReason = "Couldn't find a safe spot near " + GetName(val) + "."; return false; } SpawnEffect(drone.corePosition, drone.radius); Vector3 val2 = drone.footPosition - drone.corePosition; TeleportHelper.TeleportBody(drone, destinationCore + val2, false); SpawnEffect(destinationCore, drone.radius); failReason = null; return true; } public static bool HasTarget(CharacterBody drone) { return Object.op_Implicit((Object)(object)FindNearestTarget(drone)); } private static CharacterBody FindNearestTarget(CharacterBody drone) { //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_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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) candidates.Clear(); foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.master)) { candidates.Add(instance.master.GetBody()); } } DroneTeleportApi.InvokeCollectAdditionalTargets(drone, candidates); CharacterBody result = null; float num = float.PositiveInfinity; Vector3 corePosition = drone.corePosition; foreach (CharacterBody candidate in candidates) { if (Object.op_Implicit((Object)(object)candidate) && !((Object)(object)candidate == (Object)(object)drone) && !candidate.isRemoteOp && Object.op_Implicit((Object)(object)candidate.healthComponent) && candidate.healthComponent.alive) { Vector3 val = candidate.corePosition - corePosition; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = candidate; } } } candidates.Clear(); return result; } private static bool TryFindDestination(CharacterBody drone, CharacterBody target, out Vector3 destinationCore) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) //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_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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00d2: 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_0216: 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_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: 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_0249: Unknown result type (might be due to invalid IL or missing references) //IL_023c: 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_024f: 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_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_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_0131: 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_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_0143: 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_0174: 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_0183: 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_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_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_016e: 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_01b0: 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) //IL_01ba: 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_01be: 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_01cc: Unknown result type (might be due to invalid IL or missing references) LayerIndex world = LayerIndex.world; int num = LayerMask.op_Implicit(((LayerIndex)(ref world)).mask); float num2 = Mathf.Max(drone.radius, 0.5f) + 0.25f; bool flag = !Object.op_Implicit((Object)(object)drone.characterMotor) || drone.characterMotor.isFlying; float num3 = drone.corePosition.y - drone.footPosition.y; Vector3 corePosition = target.corePosition; Vector3 footPosition = target.footPosition; Vector3 val = drone.corePosition - corePosition; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = -((Component)target).transform.forward; val.y = 0f; } val = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.forward); float[] array = (flag ? flierHeights : groundHeights); float[] array2 = ringDistances; RaycastHit val5 = default(RaycastHit); foreach (float num4 in array2) { for (int j = 0; j < 12; j++) { int num5 = ((j % 2 == 0) ? 1 : (-1)); Vector3 val2 = Quaternion.AngleAxis((float)((j + 1) / 2) * 30f * (float)num5, Vector3.up) * val; Vector3 val3 = footPosition + val2 * num4; float[] array3 = array; foreach (float num6 in array3) { Vector3 val4; if (flag) { val4 = val3 + Vector3.up * num6; } else { if (!Physics.Raycast(val3 + Vector3.up * 2f, Vector3.down, ref val5, 6f, num, (QueryTriggerInteraction)1)) { continue; } val4 = ((RaycastHit)(ref val5)).point + Vector3.up * (num3 + 0.1f); } if (IsValidSpot(val4, corePosition, num2, num)) { destinationCore = val4; return true; } } } } if (TryNodeGraphFallback(drone, target, flag, num3, num2, num, out destinationCore)) { return true; } Vector3 val6 = corePosition + Vector3.up * (target.radius + num2); destinationCore = ((!Physics.CheckSphere(val6, num2, num, (QueryTriggerInteraction)1) && !Physics.Linecast(corePosition, val6, num, (QueryTriggerInteraction)1)) ? val6 : corePosition); return true; } private static bool IsValidSpot(Vector3 core, Vector3 anchor, float clearance, int worldMask) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (Physics.CheckSphere(core, clearance, worldMask, (QueryTriggerInteraction)1)) { return false; } if (Physics.Linecast(anchor, core, worldMask, (QueryTriggerInteraction)1)) { return false; } return Physics.Raycast(core, Vector3.down, 150f, worldMask, (QueryTriggerInteraction)1); } private static bool TryNodeGraphFallback(CharacterBody drone, CharacterBody target, bool flier, float footToCore, float clearance, int worldMask, out Vector3 destinationCore) { //IL_0002: 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_0033: 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_0043: 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_0051: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) destinationCore = default(Vector3); SceneInfo instance = SceneInfo.instance; NodeGraph val = (Object.op_Implicit((Object)(object)instance) ? instance.GetNodeGraph((GraphType)0) : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } NodeIndex val2 = val.FindClosestNode(target.footPosition, drone.hullClassification, 30f); Vector3 val3 = default(Vector3); if (val2 == NodeIndex.invalid || !val.GetNodePosition(val2, ref val3)) { return false; } float[] array = ((!flier) ? new float[1] { footToCore + 0.1f } : new float[3] { 2f, 1f, footToCore + 0.1f }); foreach (float num in array) { Vector3 val4 = val3 + Vector3.up * num; if (!Physics.CheckSphere(val4, clearance, worldMask, (QueryTriggerInteraction)1)) { destinationCore = val4; return true; } } return false; } private static void SpawnEffect(Vector3 position, float radius) { //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_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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)teleportEffectPrefab)) { teleportEffectPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/TeleportOutBoom"); } if (Object.op_Implicit((Object)(object)teleportEffectPrefab)) { EffectManager.SpawnEffect(teleportEffectPrefab, new EffectData { origin = position, rotation = Quaternion.identity, scale = radius }, true); } } private static string GetName(CharacterBody body) { return body.GetUserName() ?? body.GetDisplayName(); } } public static class DroneTeleportApi { public static event Action<CharacterBody, List<CharacterBody>> CollectAdditionalTargets; internal static void InvokeCollectAdditionalTargets(CharacterBody drone, List<CharacterBody> targets) { DroneTeleportApi.CollectAdditionalTargets?.Invoke(drone, targets); } } internal static class DroneUtil { public static bool IsDronePlayer(CharacterBody body) { if (Object.op_Implicit((Object)(object)body) && body.isPlayerControlled) { return body.isRemoteOp; } return false; } public static int CountLivingNonDronePlayers() { int num = 0; foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.master)) { CharacterBody body = instance.master.GetBody(); if (Object.op_Implicit((Object)(object)body) && !body.isRemoteOp) { num++; } } } return num; } } internal static class HostSettings { private class SettingsMessage : MessageBase { public bool survivorActions; public DroneGoldMode goldMode; public override void Serialize(NetworkWriter writer) { writer.Write(survivorActions); writer.Write((byte)goldMode); } public override void Deserialize(NetworkReader reader) { survivorActions = reader.ReadBoolean(); goldMode = (DroneGoldMode)reader.ReadByte(); } } [HarmonyPatch(typeof(NetworkMessageHandlerAttribute), "RegisterClientMessages")] private static class RegisterClientMessagesPatch { [CompilerGenerated] private static class <>O { public static NetworkMessageDelegate <0>__HandleSettings; } private static void Postfix(NetworkClient client) { //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_0021: Expected O, but got Unknown object obj = <>O.<0>__HandleSettings; if (obj == null) { NetworkMessageDelegate val = HandleSettings; <>O.<0>__HandleSettings = val; obj = (object)val; } client.RegisterHandler((short)17393, (NetworkMessageDelegate)obj); } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static EventHandler <>9__8_0; public static EventHandler <>9__8_1; public static Action<Run> <>9__8_2; public static Action<Run> <>9__8_3; public static NetworkUserGenericDelegate <>9__8_4; internal void <Init>b__8_0(object sender, EventArgs args) { if (NetworkServer.active) { Broadcast(); ApplyToExistingDrones(); } } internal void <Init>b__8_1(object sender, EventArgs args) { if (NetworkServer.active) { Broadcast(); } } internal void <Init>b__8_2(Run run) { if (NetworkServer.active) { Broadcast(); } } internal void <Init>b__8_3(Run run) { receivedSurvivorActions = false; receivedGoldMode = DroneGoldMode.Full; } internal void <Init>b__8_4(NetworkUser networkUser) { if (NetworkServer.active) { Broadcast(); } } } public const short SettingsMsgType = 17393; private static bool receivedSurvivorActions; private static DroneGoldMode receivedGoldMode; public static bool SurvivorActions { get { if (!NetworkServer.active) { return receivedSurvivorActions; } return PluginConfig.DroneSurvivorActions.Value; } } public static DroneGoldMode GoldMode { get { if (!NetworkServer.active) { return receivedGoldMode; } return PluginConfig.DroneGold.Value; } } public static void Init() { //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: Expected O, but got Unknown PluginConfig.DroneSurvivorActions.SettingChanged += delegate { if (NetworkServer.active) { Broadcast(); ApplyToExistingDrones(); } }; PluginConfig.DroneGold.SettingChanged += delegate { if (NetworkServer.active) { Broadcast(); } }; Run.onRunStartGlobal += delegate { if (NetworkServer.active) { Broadcast(); } }; Run.onRunDestroyGlobal += delegate { receivedSurvivorActions = false; receivedGoldMode = DroneGoldMode.Full; }; object obj = <>c.<>9__8_4; if (obj == null) { NetworkUserGenericDelegate val = delegate { if (NetworkServer.active) { Broadcast(); } }; <>c.<>9__8_4 = val; obj = (object)val; } NetworkUser.onPostNetworkUserStart += (NetworkUserGenericDelegate)obj; } private static void Broadcast() { NetworkServer.SendToAll((short)17393, (MessageBase)(object)new SettingsMessage { survivorActions = PluginConfig.DroneSurvivorActions.Value, goldMode = PluginConfig.DroneGold.Value }); } private static void HandleSettings(NetworkMessage netMsg) { SettingsMessage settingsMessage = netMsg.ReadMessage<SettingsMessage>(); receivedSurvivorActions = settingsMessage.survivorActions; receivedGoldMode = settingsMessage.goldMode; ApplyToExistingDrones(); } private static void ApplyToExistingDrones() { Interactor val = default(Interactor); foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances) && readOnlyInstances.isRemoteOp && ((Component)readOnlyInstances).TryGetComponent<Interactor>(ref val)) { val.isRemoteOp = !SurvivorActions; } } } } [BepInPlugin("revor.DroneImprovements", "DroneImprovements", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class DroneImprovementsPlugin : BaseUnityPlugin { public const string PluginGUID = "revor.DroneImprovements"; public const string PluginName = "DroneImprovements"; public const string PluginVersion = "1.1.0"; internal static ManualLogSource Log; private Harmony harmony; private void Awake() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; PluginConfig.Init(((BaseUnityPlugin)this).Config); DroneSkills.Init(); HostSettings.Init(); if (RiskOfOptionsCompat.Enabled) { RiskOfOptionsCompat.Init(); } harmony = new Harmony("revor.DroneImprovements"); harmony.PatchAll(typeof(DroneImprovementsPlugin).Assembly); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(DroneBodySetup.OnGameLoaded)); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } public enum DroneGoldMode { Full, NoKillGold, None } internal static class PluginConfig { public static ConfigEntry<bool> DroneSurvivorActions; public static ConfigEntry<DroneGoldMode> DroneGold; public static ConfigEntry<bool> DronesCanChargeHoldoutZones; public static ConfigEntry<bool> IgnoreDronesForAllPlayerChecks; public static ConfigEntry<bool> SpareDronesFromArenaVoidKill; public static ConfigEntry<bool> DisconnectEnabled; public static ConfigEntry<float> DisconnectHoldSeconds; public static ConfigEntry<bool> TeleportEnabled; public static ConfigEntry<float> TeleportCooldown; public static void Init(ConfigFile config) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown DroneSurvivorActions = config.Bind<bool>("Host", "DroneSurvivorActions", true, "(host) Drones can interact, buy and pick up items like survivors."); DroneGold = config.Bind<DroneGoldMode>("Host", "DroneGold", DroneGoldMode.Full, "(host) How drones earn gold. They keep the gold they had.\nFull: like survivors\nNoKillGold: no gold from combat, barrels and shrines still pay\nNone: no gold, can't use barrels or Shrine of Blood"); DronesCanChargeHoldoutZones = config.Bind<bool>("Objectives", "DronesCanChargeHoldoutZones", true, "(host) Drones inside the teleporter zone help charge it. Drones outside never slow it down."); IgnoreDronesForAllPlayerChecks = config.Bind<bool>("Objectives", "IgnoreDronesForAllPlayerChecks", true, "(host) The Mithrix cutscene and escape ship don't wait for drones."); SpareDronesFromArenaVoidKill = config.Bind<bool>("Objectives", "SpareDronesFromArenaVoidKill", true, "(host) Drones outside the sealed Mithrix arena aren't killed."); DisconnectEnabled = config.Bind<bool>("Abilities", "DisconnectEnabled", true, "Drone Utility skill: hold to disconnect and return to spectating."); DisconnectHoldSeconds = config.Bind<float>("Abilities", "DisconnectHoldSeconds", 1f, new ConfigDescription("Seconds to hold Disconnect. Needs a game restart.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); TeleportEnabled = config.Bind<bool>("Abilities", "TeleportEnabled", true, "Drone Special skill (R): teleport to the nearest living player."); TeleportCooldown = config.Bind<float>("Abilities", "TeleportCooldown", 30f, new ConfigDescription("Teleport cooldown in seconds. Needs a game restart.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), Array.Empty<object>())); } } internal static class RiskOfOptionsCompat { public const string Guid = "com.rune580.riskofoptions"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void Init() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown ModSettingsManager.SetModDescription("Remote Operation improvements. Settings marked (host) are decided by the host for everyone."); if (Object.op_Implicit((Object)(object)DroneSkills.TeleportSkill) && Object.op_Implicit((Object)(object)((SkillDef)DroneSkills.TeleportSkill).icon)) { ModSettingsManager.SetModIcon(((SkillDef)DroneSkills.TeleportSkill).icon); } ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.DroneSurvivorActions)); ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)PluginConfig.DroneGold)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.DronesCanChargeHoldoutZones)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.IgnoreDronesForAllPlayerChecks)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.SpareDronesFromArenaVoidKill)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.DisconnectEnabled)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.TeleportEnabled)); } } } namespace DroneImprovements.Skills { internal static class DroneSkills { [HarmonyPatch(typeof(BodyCatalog), "SetBodyPrefabs")] private static class BodyCatalogSetBodyPrefabsPatch { private static void Prefix(GameObject[] newBodyPrefabs) { foreach (GameObject val in newBodyPrefabs) { if (Object.op_Implicit((Object)(object)val) && ((Object)val).name.EndsWith("BodyRemoteOp")) { AddToBody(val); } } } } private class DroneContentPackProvider : IContentPackProvider { private readonly ContentPack contentPack = new ContentPack(); public string identifier => "revor.DroneImprovements"; public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args) { contentPack.skillDefs.Add((SkillDef[])(object)new SkillDef[2] { TeleportSkill, DisconnectSkill }); contentPack.skillFamilies.Add((SkillFamily[])(object)new SkillFamily[2] { TeleportFamily, DisconnectFamily }); contentPack.entityStateTypes.Add(new Type[2] { typeof(DroneTeleportState), typeof(DroneDisconnectState) }); args.ReportProgress(1f); yield break; } public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args) { ContentPack.Copy(contentPack, args.output); args.ReportProgress(1f); yield break; } public IEnumerator FinalizeAsync(FinalizeAsyncArgs args) { args.ReportProgress(1f); yield break; } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static CollectContentPackProvidersDelegate <>9__18_0; internal void <Init>b__18_0(AddContentPackProviderDelegate add) { add.Invoke((IContentPackProvider)(object)new DroneContentPackProvider()); } } public const string StateMachineName = "DroneImprovementsAbility"; private static readonly FieldInfo skillFamilyField = AccessTools.Field(typeof(GenericSkill), "_skillFamily"); public static DroneTeleportSkillDef TeleportSkill { get; private set; } public static DroneDisconnectSkillDef DisconnectSkill { get; private set; } public static SkillFamily TeleportFamily { get; private set; } public static SkillFamily DisconnectFamily { get; private set; } public static void Init() { //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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_026d: 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_0278: Expected O, but got Unknown TeleportSkill = ScriptableObject.CreateInstance<DroneTeleportSkillDef>(); ((Object)TeleportSkill).name = "DroneImprovementsTeleport"; ((SkillDef)TeleportSkill).skillName = "DroneImprovementsTeleport"; ((SkillDef)TeleportSkill).skillNameToken = "Teleport to Player"; ((SkillDef)TeleportSkill).skillDescriptionToken = $"Teleport next to the nearest living player. <style=cIsUtility>{PluginConfig.TeleportCooldown.Value:0.#}s cooldown</style>."; ((SkillDef)TeleportSkill).icon = LoadIcon("texDroneTeleportIcon.png"); ((SkillDef)TeleportSkill).activationStateMachineName = "DroneImprovementsAbility"; ((SkillDef)TeleportSkill).activationState = new SerializableEntityStateType(typeof(DroneTeleportState)); ((SkillDef)TeleportSkill).interruptPriority = (InterruptPriority)1; ((SkillDef)TeleportSkill).baseRechargeInterval = PluginConfig.TeleportCooldown.Value; ((SkillDef)TeleportSkill).baseMaxStock = 1; ((SkillDef)TeleportSkill).rechargeStock = 1; ((SkillDef)TeleportSkill).requiredStock = 1; ((SkillDef)TeleportSkill).stockToConsume = 1; ((SkillDef)TeleportSkill).fullRestockOnAssign = true; ((SkillDef)TeleportSkill).isCombatSkill = false; ((SkillDef)TeleportSkill).cancelSprintingOnActivation = false; ((SkillDef)TeleportSkill).canceledFromSprinting = false; ((SkillDef)TeleportSkill).mustKeyPress = true; DisconnectSkill = ScriptableObject.CreateInstance<DroneDisconnectSkillDef>(); ((Object)DisconnectSkill).name = "DroneImprovementsDisconnect"; ((SkillDef)DisconnectSkill).skillName = "DroneImprovementsDisconnect"; ((SkillDef)DisconnectSkill).skillNameToken = "Disconnect"; ((SkillDef)DisconnectSkill).skillDescriptionToken = "<style=cIsUtility>Hold</style> to end remote operation and return to spectating."; ((SkillDef)DisconnectSkill).icon = LoadIcon("texDroneDisconnectIcon.png"); ((SkillDef)DisconnectSkill).activationStateMachineName = "DroneImprovementsAbility"; ((SkillDef)DisconnectSkill).activationState = new SerializableEntityStateType(typeof(DroneDisconnectState)); ((SkillDef)DisconnectSkill).interruptPriority = (InterruptPriority)0; ((SkillDef)DisconnectSkill).baseRechargeInterval = Mathf.Max(0.1f, PluginConfig.DisconnectHoldSeconds.Value); ((SkillDef)DisconnectSkill).beginSkillCooldownOnSkillEnd = true; ((SkillDef)DisconnectSkill).baseMaxStock = 1; ((SkillDef)DisconnectSkill).rechargeStock = 1; ((SkillDef)DisconnectSkill).requiredStock = 1; ((SkillDef)DisconnectSkill).stockToConsume = 1; ((SkillDef)DisconnectSkill).fullRestockOnAssign = true; ((SkillDef)DisconnectSkill).isCombatSkill = false; ((SkillDef)DisconnectSkill).cancelSprintingOnActivation = false; ((SkillDef)DisconnectSkill).canceledFromSprinting = false; ((SkillDef)DisconnectSkill).mustKeyPress = true; TeleportFamily = CreateFamily("DroneImprovementsTeleportFamily", (SkillDef)(object)TeleportSkill); DisconnectFamily = CreateFamily("DroneImprovementsDisconnectFamily", (SkillDef)(object)DisconnectSkill); object obj = <>c.<>9__18_0; if (obj == null) { CollectContentPackProvidersDelegate val = delegate(AddContentPackProviderDelegate add) { add.Invoke((IContentPackProvider)(object)new DroneContentPackProvider()); }; <>c.<>9__18_0 = val; obj = (object)val; } ContentManager.collectContentPackProviders += (CollectContentPackProvidersDelegate)obj; } private static SkillFamily CreateFamily(string name, SkillDef skill) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //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) SkillFamily val = ScriptableObject.CreateInstance<SkillFamily>(); ((Object)val).name = name; Variant[] array = new Variant[1]; Variant val2 = new Variant { skillDef = skill }; ((Variant)(ref val2)).viewableNode = new Node(skill.skillName, false, (Node)null); array[0] = val2; val.variants = (Variant[])(object)array; return val; } public static void AddToBody(GameObject prefab) { //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_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) if (Object.op_Implicit((Object)(object)EntityStateMachine.FindByCustomName(prefab, "DroneImprovementsAbility"))) { return; } SkillLocator component = prefab.GetComponent<SkillLocator>(); if (!Object.op_Implicit((Object)(object)component)) { DroneImprovementsPlugin.Log.LogWarning((object)(((Object)prefab).name + " has no SkillLocator; drone abilities not added.")); return; } EntityStateMachine obj = prefab.AddComponent<EntityStateMachine>(); obj.customName = "DroneImprovementsAbility"; obj.initialStateType = new SerializableEntityStateType(typeof(Idle)); obj.mainStateType = new SerializableEntityStateType(typeof(Idle)); if (!Object.op_Implicit((Object)(object)component.utility)) { component.utility = AddSkill(prefab, DisconnectFamily, "DroneDisconnect"); } else { DroneImprovementsPlugin.Log.LogWarning((object)(((Object)prefab).name + " already has a utility skill; Disconnect not added.")); } if (!Object.op_Implicit((Object)(object)component.special)) { component.special = AddSkill(prefab, TeleportFamily, "DroneTeleport"); } else { DroneImprovementsPlugin.Log.LogWarning((object)(((Object)prefab).name + " already has a special skill; Teleport not added.")); } } private static GenericSkill AddSkill(GameObject prefab, SkillFamily family, string slotName) { GenericSkill val = prefab.AddComponent<GenericSkill>(); val.skillName = slotName; val.hideInCharacterSelect = true; skillFamilyField.SetValue(val, family); return val; } private static Sprite LoadIcon(string fileName) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_009f: 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) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); using (Stream stream = typeof(DroneSkills).Assembly.GetManifestResourceStream("DroneImprovements.Assets." + fileName)) { if (stream == null) { DroneImprovementsPlugin.Log.LogError((object)("Missing embedded icon " + fileName)); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); ImageConversion.LoadImage(val, array); } ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).name = Path.GetFileNameWithoutExtension(fileName); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } public class DroneTeleportSkillDef : SkillDef { public override bool IsReady(GenericSkill skillSlot) { if (((SkillDef)this).IsReady(skillSlot)) { return IsAvailable(skillSlot); } return false; } public override bool CanExecute(GenericSkill skillSlot) { if (((SkillDef)this).CanExecute(skillSlot)) { return IsAvailable(skillSlot); } return false; } private static bool IsAvailable(GenericSkill skillSlot) { if (PluginConfig.TeleportEnabled.Value && Object.op_Implicit((Object)(object)skillSlot.characterBody)) { return DroneTeleport.HasTarget(skillSlot.characterBody); } return false; } } public class DroneDisconnectSkillDef : SkillDef { public override bool IsReady(GenericSkill skillSlot) { if (((SkillDef)this).IsReady(skillSlot)) { return PluginConfig.DisconnectEnabled.Value; } return false; } public override bool CanExecute(GenericSkill skillSlot) { if (((SkillDef)this).CanExecute(skillSlot)) { return PluginConfig.DisconnectEnabled.Value; } return false; } } public class DroneTeleportState : BaseSkillState { public override void OnEnter() { ((BaseState)this).OnEnter(); if (((EntityState)this).isAuthority && !DroneTeleport.TryTeleport(((EntityState)this).characterBody, out var failReason)) { DroneImprovementsPlugin.Log.LogInfo((object)("Teleport failed: " + failReason)); GenericSkill activatorSkillSlot = ((BaseSkillState)this).activatorSkillSlot; if (activatorSkillSlot != null) { activatorSkillSlot.AddOneStock(); } } } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)0; } } public class DroneDisconnectState : BaseSkillState { private float holdDuration; private bool requested; public override void OnEnter() { ((BaseState)this).OnEnter(); holdDuration = Mathf.Max(0f, PluginConfig.DisconnectHoldSeconds.Value); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (!((EntityState)this).isAuthority) { return; } if (!requested) { if (!IsDisconnectKeyHeld()) { ((EntityState)this).outer.SetNextStateToMain(); return; } if (Object.op_Implicit((Object)(object)((BaseSkillState)this).activatorSkillSlot)) { ((BaseSkillState)this).activatorSkillSlot.rechargeStopwatch = Mathf.Min(((EntityState)this).fixedAge, ((BaseSkillState)this).activatorSkillSlot.CalculateFinalRechargeInterval() - 0.01f); } if (((EntityState)this).fixedAge >= holdDuration) { requested = true; DroneNetworking.RequestDisconnect(((EntityState)this).characterBody); } } else if (((EntityState)this).fixedAge >= holdDuration + 3f) { ((EntityState)this).outer.SetNextStateToMain(); } } private bool IsDisconnectKeyHeld() { //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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected I4, but got Unknown CharacterMaster val = (Object.op_Implicit((Object)(object)((EntityState)this).characterBody) ? ((EntityState)this).characterBody.master : null); PlayerCharacterMasterController val2 = (Object.op_Implicit((Object)(object)val) ? val.playerCharacterMasterController : null); NetworkUser val3 = (Object.op_Implicit((Object)(object)val2) ? val2.networkUser : null); LocalUser val4 = (Object.op_Implicit((Object)(object)val3) ? val3.localUser : null); if (((val4 != null) ? val4.inputPlayer : null) == null) { return ((BaseSkillState)this).IsKeyDownAuthority(); } if (val4.isUIFocused) { return false; } SkillSlot val5 = (SkillSlot)((!Object.op_Implicit((Object)(object)((EntityState)this).skillLocator)) ? (-1) : ((int)((EntityState)this).skillLocator.FindSkillSlot(((BaseSkillState)this).activatorSkillSlot))); int num; switch ((int)val5) { case 0: num = 7; break; case 1: num = 8; break; case 2: num = 9; break; case 3: num = 10; break; default: return ((BaseSkillState)this).IsKeyDownAuthority(); } return val4.inputPlayer.GetButton(num); } public override void OnExit() { if (Object.op_Implicit((Object)(object)((BaseSkillState)this).activatorSkillSlot)) { ((BaseSkillState)this).activatorSkillSlot.stock = ((BaseSkillState)this).activatorSkillSlot.maxStock; ((BaseSkillState)this).activatorSkillSlot.rechargeStopwatch = 0f; } ((EntityState)this).OnExit(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)0; } } } namespace DroneImprovements.Patches { internal static class CombatGold { [ThreadStatic] private static int depth; private static readonly ConditionalWeakTable<GoldOrb, object> combatOrbs = new ConditionalWeakTable<GoldOrb, object>(); private static readonly object marker = new object(); public static bool InCombatContext => depth > 0; private static DroneGoldMode Mode => HostSettings.GoldMode; public static bool ExcludeDronesFromTeamPayout { get { if (Mode != DroneGoldMode.None) { if (Mode == DroneGoldMode.NoKillGold) { return InCombatContext; } return false; } return true; } } public static bool BlocksAllGold => Mode == DroneGoldMode.None; public static bool BlockOrbForDrone(GoldOrb orb) { if (Mode != DroneGoldMode.None) { if (Mode == DroneGoldMode.NoKillGold) { return IsCombatOrb(orb); } return false; } return true; } public static void Enter() { depth++; } public static void Exit() { depth = Math.Max(0, depth - 1); } public static void MarkOrb(GoldOrb orb) { combatOrbs.GetValue(orb, (GoldOrb _) => marker); } public static bool IsCombatOrb(GoldOrb orb) { object value; return combatOrbs.TryGetValue(orb, out value); } } [HarmonyPatch(typeof(DeathRewards), "OnKilledServer")] internal static class DeathRewardsContextPatch { private static void Prefix() { CombatGold.Enter(); } private static void Finalizer() { CombatGold.Exit(); } } [HarmonyPatch(typeof(MoneyPickup), "OnTriggerStay")] internal static class MoneyPickupContextPatch { private static void Prefix() { CombatGold.Enter(); } private static void Finalizer() { CombatGold.Exit(); } } [HarmonyPatch(typeof(GlobalEventManager), "ProcessHitEnemy")] internal static class HitEnemyContextPatch { private static void Prefix() { CombatGold.Enter(); } private static void Finalizer() { CombatGold.Exit(); } } [HarmonyPatch(typeof(HealthComponent), "TakeDamageProcess")] internal static class TakeDamageContextPatch { private static void Prefix() { CombatGold.Enter(); } private static void Finalizer() { CombatGold.Exit(); } } [HarmonyPatch(typeof(TeamManager), "GiveTeamMoney", new Type[] { typeof(TeamIndex), typeof(uint) })] internal static class GiveTeamMoneyPatch { private static bool Prefix(TeamIndex teamIndex, uint money) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!CombatGold.ExcludeDronesFromTeamPayout) { return true; } int num = DroneUtil.CountLivingNonDronePlayers(); if (num > 0) { money = (uint)Mathf.CeilToInt((float)money / (float)num); } ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(teamIndex); for (int i = 0; i < teamMembers.Count; i++) { CharacterBody component = ((Component)teamMembers[i]).GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && component.isPlayerControlled && !component.isRemoteOp && Object.op_Implicit((Object)(object)component.master)) { component.master.GiveMoney(money); } } return false; } } [HarmonyPatch(typeof(OrbManager), "AddOrb")] internal static class AddOrbPatch { private static void Prefix(Orb orb) { if (CombatGold.InCombatContext) { GoldOrb val = (GoldOrb)(object)((orb is GoldOrb) ? orb : null); if (val != null) { CombatGold.MarkOrb(val); } } } } [HarmonyPatch(typeof(GoldOrb), "OnArrival")] internal static class GoldOrbArrivalPatch { private static bool Prefix(GoldOrb __instance) { if (!CombatGold.BlockOrbForDrone(__instance)) { return true; } HurtBox target = ((Orb)__instance).target; return !DroneUtil.IsDronePlayer((Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)target.healthComponent)) ? target.healthComponent.body : null); } } [HarmonyPatch(typeof(CharacterMaster), "GiveMoney")] internal static class GiveMoneyPatch { private static bool Prefix(CharacterMaster __instance) { if (CombatGold.BlocksAllGold) { return !DroneUtil.IsDronePlayer(__instance.GetBody()); } return true; } } internal static class GoldInteractables { public static bool BlockedFor(Interactor activator) { if (CombatGold.BlocksAllGold && Object.op_Implicit((Object)(object)activator)) { return DroneUtil.IsDronePlayer(((Component)activator).GetComponent<CharacterBody>()); } return false; } } [HarmonyPatch(typeof(BarrelInteraction), "GetInteractability")] internal static class BarrelInteractabilityPatch { private static void Postfix(Interactor activator, ref Interactability __result) { if (GoldInteractables.BlockedFor(activator)) { __result = (Interactability)0; } } } [HarmonyPatch(typeof(PurchaseInteraction), "GetInteractability")] internal static class BloodShrineInteractabilityPatch { private static void Postfix(PurchaseInteraction __instance, Interactor activator, ref Interactability __result) { if (__result && GoldInteractables.BlockedFor(activator) && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<ShrineBloodBehavior>())) { __result = (Interactability)0; } } } [HarmonyPatch(typeof(CharacterBody), "Start")] internal static class CharacterBodyStartPatch { private static void Postfix(CharacterBody __instance) { Interactor val = default(Interactor); if (__instance.isRemoteOp && HostSettings.SurvivorActions && ((Component)__instance).TryGetComponent<Interactor>(ref val)) { val.isRemoteOp = false; } } } [HarmonyPatch(typeof(GenericPickupController), "BodyHasPickupPermission")] internal static class PickupPermissionPatch { private static void Postfix(CharacterBody body, ref bool __result) { if (!__result && HostSettings.SurvivorActions && Object.op_Implicit((Object)(object)body) && body.isRemoteOp) { __result = Object.op_Implicit((Object)(object)body.masterObject) && Object.op_Implicit((Object)(object)body.masterObject.GetComponent<PlayerCharacterMasterController>()) && Object.op_Implicit((Object)(object)body.inventory); } } } [HarmonyPatch(typeof(HoldoutZoneController), "DoUpdate")] internal static class HoldoutZoneDoUpdatePatch { [ThreadStatic] internal static HoldoutZoneController currentZone; private static void Prefix(HoldoutZoneController __instance) { currentZone = __instance; } private static void Finalizer() { currentZone = null; } } [HarmonyPatch(typeof(HoldoutZoneController), "CountLivingPlayers")] internal static class HoldoutZoneCountLivingPlayersPatch { private static void Postfix(TeamIndex teamIndex, ref int __result) { //IL_002c: 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) HoldoutZoneController currentZone = HoldoutZoneDoUpdatePatch.currentZone; if (Object.op_Implicit((Object)(object)currentZone) && PluginConfig.DronesCanChargeHoldoutZones.Value) { float currentRadius = currentZone.currentRadius; __result += HoldoutZoneHelpers.CountDronesInRadius(currentZone, ((Component)currentZone).transform.position, currentRadius * currentRadius, teamIndex); } } } [HarmonyPatch(typeof(HoldoutZoneController), "CountPlayersInRadius")] internal static class HoldoutZoneCountPlayersInRadiusPatch { private static void Postfix(HoldoutZoneController holdoutZoneController, Vector3 origin, float chargingRadiusSqr, TeamIndex teamIndex, ref int __result) { //IL_0013: 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) if (PluginConfig.DronesCanChargeHoldoutZones.Value) { __result += HoldoutZoneHelpers.CountDronesInRadius(holdoutZoneController, origin, chargingRadiusSqr, teamIndex); } } } internal static class HoldoutZoneHelpers { private static readonly Func<HoldoutZoneController, Vector3, float, CharacterBody, bool> isBodyInChargingRadius = AccessTools.MethodDelegate<Func<HoldoutZoneController, Vector3, float, CharacterBody, bool>>(AccessTools.Method(typeof(HoldoutZoneController), "IsBodyInChargingRadius", new Type[4] { typeof(HoldoutZoneController), typeof(Vector3), typeof(float), typeof(CharacterBody) }, (Type[])null), (object)null, true); public static int CountDronesInRadius(HoldoutZoneController zone, Vector3 origin, float chargingRadiusSqr, TeamIndex teamIndex) { //IL_0002: 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) int num = 0; ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(teamIndex); for (int i = 0; i < teamMembers.Count; i++) { CharacterBody body = teamMembers[i].body; if (DroneUtil.IsDronePlayer(body) && isBodyInChargingRadius(zone, origin, chargingRadiusSqr, body)) { num++; } } return num; } } [HarmonyPatch(typeof(MultiBodyTrigger), "FixedUpdate")] internal static class MultiBodyTriggerFixedUpdatePatch { private static readonly Action<MultiBodyTrigger, List<CharacterBody>, int> setEncounteredBodies = AccessTools.MethodDelegate<Action<MultiBodyTrigger, List<CharacterBody>, int>>(AccessTools.Method(typeof(MultiBodyTrigger), "SetEncounteredBodies", (Type[])null, (Type[])null), (object)null, true); private static readonly List<CharacterBody> buffer = new List<CharacterBody>(); private static bool Prefix(MultiBodyTrigger __instance, Queue<Collider> ___collisionsQueue, List<CharacterBody> ___encounteredBodies) { if (!PluginConfig.IgnoreDronesForAllPlayerChecks.Value || !__instance.playerControlledOnly) { return true; } if (___collisionsQueue.Count == 0 && ___encounteredBodies.Count == 0) { return false; } buffer.Clear(); while (___collisionsQueue.Count > 0) { Collider val = ___collisionsQueue.Dequeue(); if (Object.op_Implicit((Object)(object)val)) { CharacterBody component = ((Component)val).GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && component.isPlayerControlled && !component.isRemoteOp && !buffer.Contains(component)) { buffer.Add(component); } } } int arg = (Object.op_Implicit((Object)(object)Run.instance) ? DroneUtil.CountLivingNonDronePlayers() : 0); setEncounteredBodies(__instance, buffer, arg); buffer.Clear(); return false; } } [HarmonyPatch(typeof(MultiBodyTrigger), "KillAllOutsideWithVoidDeath")] internal static class MultiBodyTriggerVoidKillPatch { private static bool Prefix(List<CharacterBody> ___encounteredBodies) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (!PluginConfig.SpareDronesFromArenaVoidKill.Value) { return true; } GameObject val = BodyCatalog.FindBodyPrefab("BrotherBody"); foreach (CharacterBody item in new List<CharacterBody>(CharacterBody.readOnlyInstancesList)) { if (!Object.op_Implicit((Object)(object)item) || ___encounteredBodies.Contains(item) || DroneUtil.IsDronePlayer(item)) { continue; } CharacterMaster master = item.master; if (Object.op_Implicit((Object)(object)master)) { try { master.TrueKill(val, (GameObject)null, DamageTypeCombo.op_Implicit((DamageType)65536)); } catch (Exception ex) { Debug.LogError((object)ex); } } } return false; } } [HarmonyPatch(typeof(AllPlayersTrigger), "FixedUpdate")] internal static class AllPlayersTriggerFixedUpdatePatch { private static readonly List<CharacterBody> buffer = new List<CharacterBody>(); private static bool Prefix(AllPlayersTrigger __instance, Queue<Collider> ___collisionQueueServer, ref bool ___triggerActiveServer) { if (!PluginConfig.IgnoreDronesForAllPlayerChecks.Value) { return true; } if (!Object.op_Implicit((Object)(object)Run.instance) || ___collisionQueueServer == null) { return false; } buffer.Clear(); while (___collisionQueueServer.Count > 0) { Collider val = ___collisionQueueServer.Dequeue(); if (Object.op_Implicit((Object)(object)val)) { CharacterBody component = ((Component)val).GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && component.isPlayerControlled && !component.isRemoteOp && !buffer.Contains(component)) { buffer.Add(component); } } } int count = buffer.Count; buffer.Clear(); bool flag = count != 0 && count >= DroneUtil.CountLivingNonDronePlayers(); if (___triggerActiveServer != flag) { ___triggerActiveServer = flag; UnityEvent obj = (flag ? __instance.onTriggerStart : __instance.onTriggerEnd); if (obj != null) { obj.Invoke(); } } return false; } } [HarmonyPatch(typeof(EscapeSequenceExtractionZone), "CountLivingPlayers")] internal static class EscapeZoneCountLivingPlayersPatch { private static bool Prefix(TeamIndex teamIndex, ref int __result) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!PluginConfig.IgnoreDronesForAllPlayerChecks.Value) { return true; } int num = 0; ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(teamIndex); for (int i = 0; i < teamMembers.Count; i++) { CharacterBody body = teamMembers[i].body; if (Object.op_Implicit((Object)(object)body) && body.isPlayerControlled && !body.isRemoteOp) { num++; } } __result = num; return false; } } [HarmonyPatch(typeof(EscapeSequenceExtractionZone), "GetPlayersInRadius")] internal static class EscapeZoneGetPlayersInRadiusPatch { private static void Postfix(List<CharacterBody> dest) { if (PluginConfig.IgnoreDronesForAllPlayerChecks.Value) { dest.RemoveAll(DroneUtil.IsDronePlayer); } } } [HarmonyPatch(typeof(EscapeSequenceExtractionZone), "CountPlayersInRadius")] internal static class EscapeZoneCountPlayersInRadiusPatch { private static void Postfix(Vector3 origin, float chargingRadiusSqr, TeamIndex teamIndex, ref int __result) { //IL_000d: 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_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) if (!PluginConfig.IgnoreDronesForAllPlayerChecks.Value) { return; } ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(teamIndex); for (int i = 0; i < teamMembers.Count; i++) { CharacterBody body = teamMembers[i].body; if (DroneUtil.IsDronePlayer(body)) { Vector3 val = body.corePosition - origin; if (((Vector3)(ref val)).sqrMagnitude <= chargingRadiusSqr) { __result--; } } } } } }