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 EngineerWithFourTurrets v1.1.1
plugins/EngineerFourTurrets.dll
Decompiled 4 hours agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using RoR2.Skills; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyVersion("0.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 NormalAIPeople.EngineerFourTurrets { [BepInPlugin("normalAIPeople.EngineerFourTurrets", "Engineer Four Turrets", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerFourTurretsPlugin : BaseUnityPlugin { public const string PluginGuid = "normalAIPeople.EngineerFourTurrets"; public const string PluginName = "Engineer Four Turrets"; public const string PluginVersion = "1.1.1"; private static ConfigEntry<int> turretLimit; private static ConfigEntry<int> tr90InitialStocks; private static ConfigEntry<float> tr90PlacementRecharge; private static ConfigEntry<float> tr90AttackInterval; private static ManualLogSource log; private static DeployableSlot aerosBigTurretSlot; private static bool hasAerosBigTurretSlot; private void Awake() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown log = ((BaseUnityPlugin)this).Logger; turretLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Engineer", "Turret Limit", 4, "Maximum simultaneous turrets for the vanilla Engineer turret slot and AerosSkills TR90 Railgun Turret slot."); tr90InitialStocks = ((BaseUnityPlugin)this).Config.Bind<int>("TR90 Railgun Turret", "Initial Placement Stocks", 1, "TR90 placement charges available when entering a run. The skill starts full, so this also sets its maximum stock."); tr90PlacementRecharge = ((BaseUnityPlugin)this).Config.Bind<float>("TR90 Railgun Turret", "Placement Recharge Time", 25f, "Seconds required to recharge one TR90 placement stock."); tr90AttackInterval = ((BaseUnityPlugin)this).Config.Bind<float>("TR90 Railgun Turret", "Base Attack Interval", 8f, "Base seconds between TR90 shots before the turret's attack-speed multiplier is applied."); Harmony val = new Harmony("normalAIPeople.EngineerFourTurrets"); MethodInfo methodInfo = AccessTools.Method(typeof(CharacterMaster), "GetDeployableSameSlotLimit", (Type[])null, (Type[])null); if (methodInfo != null) { val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(EngineerFourTurretsPlugin), "DeployableLimitPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } InstallAerosCompatibility(val); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(ApplyTR90SkillConfig)); } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(ApplyTR90SkillConfig)); } private static void ApplyTR90SkillConfig() { Type type = AccessTools.TypeByName("AerosSkills.EngiSpecial"); Type type2 = AccessTools.TypeByName("AerosSkills.EngiTurretPrimary"); int num = 0; int num2 = 0; foreach (SkillDef allSkillDef in SkillCatalog.allSkillDefs) { Type type3 = (((Object)(object)allSkillDef != (Object)null) ? ((SerializableEntityStateType)(ref allSkillDef.activationState)).stateType : null); if (type3 == type) { allSkillDef.baseMaxStock = Math.Max(1, tr90InitialStocks.Value); allSkillDef.baseRechargeInterval = Math.Max(0.05f, tr90PlacementRecharge.Value); allSkillDef.rechargeStock = 1; num++; } else if (type3 == type2) { allSkillDef.baseRechargeInterval = Math.Max(0.05f, tr90AttackInterval.Value); num2++; } } log.LogInfo((object)("Configured " + num + " TR90 placement skill(s) and " + num2 + " attack skill(s).")); } private static void InstallAerosCompatibility(Harmony harmony) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown Type type = AccessTools.TypeByName("AerosSkills.Prefabs"); if (type == null) { log.LogInfo((object)"AerosSkills is not loaded; vanilla Engineer turret support remains active."); return; } FieldInfo fieldInfo = AccessTools.Field(type, "bigTurret"); if (fieldInfo != null) { object value = fieldInfo.GetValue(null); if (value is DeployableSlot) { aerosBigTurretSlot = (DeployableSlot)value; hasAerosBigTurretSlot = true; } } FieldInfo fieldInfo2 = AccessTools.Field(type, "turret"); GameObject val = (GameObject)((fieldInfo2 != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { NormalizeNetworkIdentities(val); } Type type2 = AccessTools.TypeByName("AerosSkills.EngiSpecial"); MethodInfo methodInfo = ((type2 != null) ? AccessTools.Method(type2, "OnEnter", (Type[])null, (Type[])null) : null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(EngineerFourTurretsPlugin), "AerosOnEnterPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo2 = ((type2 != null) ? AccessTools.Method(type2, "Summon", (Type[])null, (Type[])null) : null); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(EngineerFourTurretsPlugin), "AerosSummonPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); log.LogInfo((object)"Installed AerosSkills TR90 host/client placement compatibility."); } } private static void AerosOnEnterPostfix(object __instance) { try { GameObject value = Traverse.Create(__instance).Property("gameObject", (object[])null).GetValue<GameObject>(); EntityStateMachine value2 = Traverse.Create(__instance).Field("outer").GetValue<EntityStateMachine>(); CharacterBody val = (((Object)(object)value != (Object)null) ? value.GetComponent<CharacterBody>() : null); if ((Object)(object)value2 != (Object)null && (Object)(object)val != (Object)null) { FieldInfo fieldInfo = AccessTools.Field(typeof(EntityStateMachine), "commonComponents"); object obj = ((fieldInfo != null) ? fieldInfo.GetValue(value2) : null); FieldInfo fieldInfo2 = ((obj != null) ? AccessTools.Field(obj.GetType(), "characterBody") : null); if (fieldInfo != null && fieldInfo2 != null) { fieldInfo2.SetValue(obj, val); fieldInfo.SetValue(value2, obj); } } Type type = AccessTools.TypeByName("AerosSkills.Prefabs"); FieldInfo fieldInfo3 = ((type != null) ? AccessTools.Field(type, "turretMaster") : null); GameObject val2 = (GameObject)((fieldInfo3 != null) ? /*isinst with value type is only supported in some contexts*/: null); Type type2 = AccessTools.TypeByName("EntityStates.Engi.EngiWeapon.PlaceTurret"); FieldInfo fieldInfo4 = ((type2 != null) ? AccessTools.Field(type2, "turretMasterPrefab") : null); if ((Object)(object)val2 != (Object)null && fieldInfo4 != null) { fieldInfo4.SetValue(__instance, val2); } } catch (Exception ex) { log.LogWarning((object)("Could not initialize TR90 placement compatibility: " + ex.Message)); } } private static void NormalizeNetworkIdentities(GameObject turretBody) { NetworkIdentity[] components = turretBody.GetComponents<NetworkIdentity>(); NetworkIdentity val = ((components.Length != 0) ? components[0] : null); int num = 0; for (int i = 1; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); num++; } NetworkIdentity[] componentsInChildren = turretBody.GetComponentsInChildren<NetworkIdentity>(true); NetworkIdentity[] array = componentsInChildren; foreach (NetworkIdentity val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)val && (Object)(object)((Component)val2).gameObject != (Object)(object)turretBody) { Object.DestroyImmediate((Object)(object)val2); num++; } } if (num > 0) { log.LogInfo((object)"Removed duplicate NetworkIdentity components from AerosBigTurretBody."); } } private static void DeployableLimitPostfix(DeployableSlot slot, ref int __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //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) bool flag = (int)slot == 1; bool flag2 = hasAerosBigTurretSlot && slot == aerosBigTurretSlot; if (flag || flag2) { __result = Math.Max(__result, Math.Max(1, turretLimit.Value)); } } private static bool AerosSummonPrefix(object __instance) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) try { Type type = AccessTools.TypeByName("EntityStates.Engi.EngiWeapon.PlaceTurret"); FieldInfo fieldInfo = ((type != null) ? AccessTools.Field(type, "currentPlacementInfo") : null); object obj = ((fieldInfo != null) ? fieldInfo.GetValue(__instance) : null); if (obj == null) { return true; } Type type2 = obj.GetType(); FieldInfo fieldInfo2 = AccessTools.Field(type2, "position"); FieldInfo fieldInfo3 = AccessTools.Field(type2, "rotation"); if (fieldInfo2 == null || fieldInfo3 == null) { return true; } Vector3 val = (Vector3)fieldInfo2.GetValue(obj); Quaternion val2 = (Quaternion)fieldInfo3.GetValue(obj); GameObject value = Traverse.Create(__instance).Property("gameObject", (object[])null).GetValue<GameObject>(); Type type3 = AccessTools.TypeByName("AerosSkills.TurretSpawner"); Component val3 = (((Object)(object)value != (Object)null && type3 != null) ? value.GetComponent(type3) : null); string text = (NetworkServer.active ? "CmdSpawn" : "CallCmdSpawn"); MethodInfo methodInfo = ((type3 != null) ? AccessTools.Method(type3, text, (Type[])null, (Type[])null) : null); if ((Object)(object)val3 == (Object)null || methodInfo == null) { return true; } methodInfo.Invoke(val3, new object[2] { val, val2 }); return false; } catch (Exception ex) { log.LogWarning((object)("TR90 placement compatibility fell back to AerosSkills: " + ex.Message)); return true; } } } }