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 OG Bands v1.0.1
OGBands.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using RoR2; using RoR2.Projectile; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace OGBands; [BepInPlugin("local.ogbands", "OG Bands", "1.0.1")] public sealed class Plugin : BaseUnityPlugin { private void Awake() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (Chainloader.PluginInfos.ContainsKey("local.classicroute")) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Classic Route already implements these bands; OG Bands stays inactive to avoid duplicate procs."); return; } ProcItems.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); new Harmony("local.ogbands").PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"OG Bands loaded: original shared 8% roll, no cooldown/threshold, original damage stacking and moving tornado."); } } internal static class BandDamage { private sealed class Hit { public float damage; } [HarmonyPatch(typeof(GlobalEventManager), "ServerDamageDealt")] private static class Capture { private static void Prefix(DamageReport __0) { if (__0 != null && __0.damageInfo != null && !__0.damageInfo.rejected) { hits.GetOrCreateValue(__0.damageInfo).damage = __0.damageDealt; } } } private static readonly ConditionalWeakTable<DamageInfo, Hit> hits = new ConditionalWeakTable<DamageInfo, Hit>(); internal static float Read(DamageInfo info) { Hit value; return hits.TryGetValue(info, out value) ? value.damage : info.damage; } internal static float Proc(float hit, float basic, float coefficient) { return Math.Max(1f, Math.Min(hit + (coefficient - 1f) * basic, hit * coefficient)); } } internal static class ProcItems { [HarmonyPatch(typeof(Language), "GetLocalizedStringByToken")] private static class Descriptions { private static bool Prefix(string __0, ref string __result) { if (!Enabled.Value) { return true; } switch (__0) { case "ITEM_ICERING_DESC": __result = "8% chance on hit to blast an enemy with ice for 250% (+125% per stack) damage and slow by 80% for 3 seconds. No cooldown or damage threshold. Shares its roll with Runald's and Kjaro's Bands."; return false; case "ITEM_FIRERING_DESC": __result = "8% chance on hit to create a moving flame tornado for 500% (+250% per stack) damage. No cooldown or damage threshold. Shares its roll with Runald's and Kjaro's Bands."; return false; case "ITEM_ICERING_PICKUP": __result = "Chance on hit to blast enemies with ice. No cooldown."; return false; case "ITEM_FIRERING_PICKUP": __result = "Chance on hit to create a moving flame tornado. No cooldown."; return false; default: return true; } } } [HarmonyPatch] private static class ReplaceVanilla { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(GlobalEventManager), "ProcessHitEnemy", (Type[])null, (Type[])null); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod) { List<CodeInstruction> list = instructions.ToList(); int num = 0; int num2 = 0; for (int i = 0; i < list.Count - 1; i++) { if (!(list[i].opcode != OpCodes.Ldsfld)) { FieldInfo fieldInfo = list[i].operand as FieldInfo; MethodInfo methodInfo = list[i + 1].operand as MethodInfo; if (Family(fieldInfo) && methodInfo != null && methodInfo.Name == "GetItemCountEffective" && methodInfo.GetParameters()[0].ParameterType == typeof(ItemDef)) { list[i + 1].opcode = OpCodes.Call; list[i + 1].operand = AccessTools.Method(typeof(ProcItems), "VanillaCount", (Type[])null, (Type[])null); num++; } if (fieldInfo == AccessTools.Field(typeof(Buffs), "ElementalRingsReady") && methodInfo != null && methodInfo.Name == "HasBuff") { list[i + 1].opcode = OpCodes.Call; list[i + 1].operand = AccessTools.Method(typeof(ProcItems), "VanillaBandsReady", (Type[])null, (Type[])null); num2++; } } } int num3 = 2; if (num != num3 || (__originalMethod.Name == "ProcessHitEnemy" && num2 != 1)) { throw new InvalidOperationException("Proc item targets changed in " + __originalMethod.Name + ": counts=" + num + " ready=" + num2); } log.LogInfo((object)("Classic item handlers replaced in " + __originalMethod.Name + ": " + num)); return list; } } [HarmonyPatch(typeof(GlobalEventManager), "ProcessHitEnemy")] private static class HitItems { private static void Postfix(DamageInfo __0, GameObject __1) { //IL_00a8: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01c2: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) if (!Active || !NetworkServer.active || __0.rejected || __0.procCoefficient <= 0f || !Object.op_Implicit((Object)(object)__0.attacker) || !Object.op_Implicit((Object)(object)__1)) { return; } CharacterBody component = __0.attacker.GetComponent<CharacterBody>(); CharacterBody component2 = __1.GetComponent<CharacterBody>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.inventory) || !Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)component2.healthComponent) || component2.HasBuff(Buffs.HiddenRejectAllDamage) || ((__0.damageType.damageTypeExtended & 0x400000) != 0 && !FriendlyFireManager.ShouldDirectHitProceed(component2.healthComponent, component.teamComponent.teamIndex))) { return; } Inventory inventory = component.inventory; TeamIndex teamIndex = component.teamComponent.teamIndex; float hit = BandDamage.Read(__0); int itemCountEffective = inventory.GetItemCountEffective(Items.IceRing); int itemCountEffective2 = inventory.GetItemCountEffective(Items.FireRing); if ((itemCountEffective | itemCountEffective2) > 0 && Util.CheckRoll(8f * __0.procCoefficient, component.master)) { ProcChainMask procChainMask = __0.procChainMask; ((ProcChainMask)(ref procChainMask)).AddProc((ProcType)12); if (itemCountEffective > 0) { EffectManager.SimpleImpactEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/IceRingExplosion"), __0.position, Vector3.up, true); component2.AddTimedBuff(Buffs.Slow80, 3f); HealthComponent healthComponent = component2.healthComponent; DamageInfo val = new DamageInfo(); val.damage = BandDamage.Proc(hit, component.damage, 1.25f + 1.25f * (float)itemCountEffective); val.damageColorIndex = (DamageColorIndex)3; val.damageType = DamageTypeCombo.op_Implicit((DamageType)0); val.attacker = __0.attacker; val.crit = __0.crit; val.force = Vector3.zero; val.position = __0.position; val.procChainMask = procChainMask; val.procCoefficient = 1f; val.inflictedHurtbox = __0.inflictedHurtbox; healthComponent.TakeDamage(val); } if (itemCountEffective2 > 0) { GameObject projectilePrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/FireTornado"); Vector3 val2 = __0.position - component.aimOrigin; val2.y = 0f; ProjectileManager instance = ProjectileManager.instance; FireProjectileInfo val3 = new FireProjectileInfo { projectilePrefab = projectilePrefab, position = __0.position, rotation = ((val2 != Vector3.zero) ? Util.QuaternionSafeLookRotation(val2, Vector3.up) : Quaternion.identity), owner = __0.attacker, damage = BandDamage.Proc(hit, component.damage, 2.5f + 2.5f * (float)itemCountEffective2) / 3.3f * 0.3f, crit = __0.crit, procChainMask = procChainMask, damageColorIndex = (DamageColorIndex)3 }; ((FireProjectileInfo)(ref val3)).speedOverride = ((val2 != Vector3.zero) ? 5f : 0f); instance.FireProjectile(val3); } } } } [HarmonyPatch(typeof(ProjectileController), "Awake")] private static class TornadoMovement { private static void Postfix(ProjectileController __instance) { //IL_00b9: 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) if (Active && ((Object)((Component)__instance).gameObject).name.StartsWith("FireTornado", StringComparison.Ordinal)) { ProjectileSimple component = ((Component)__instance).GetComponent<ProjectileSimple>(); if (Object.op_Implicit((Object)(object)component)) { component.desiredForwardSpeed = 5f; component.enableVelocityOverLifetime = true; component.lifetime = 3.3f; } ProjectileOverlapAttack component2 = ((Component)__instance).GetComponent<ProjectileOverlapAttack>(); if (Object.op_Implicit((Object)(object)component2)) { component2.resetInterval = 0.3f; component2.overlapProcCoefficient = 0f; } Transform val = ((Component)__instance).transform.Find("HitBox"); if (Object.op_Implicit((Object)(object)val)) { val.localScale = new Vector3(4.8f, 7.2f, 4.8f); val.localPosition = new Vector3(0f, 2.07f, 0f); } } } } internal static ConfigEntry<bool> Enabled; private static ManualLogSource log; internal static bool Active => Enabled.Value && Object.op_Implicit((Object)(object)Run.instance) && !(Run.instance is InfiniteTowerRun); internal static void Initialize(ConfigFile config, ManualLogSource logger) { log = logger; Enabled = config.Bind<bool>("Mechanics", "Enabled", true, "Restore original bands: shared chance, damage stacking, ice slow and moving fire tornado."); } internal static int VanillaCount(Inventory inventory, ItemDef item) { return (!Active) ? inventory.GetItemCountEffective(item) : 0; } internal static bool VanillaBandsReady(CharacterBody body, BuffDef buff) { return !Active && body.HasBuff(buff); } private static bool Family(FieldInfo field) { return field != null && field.DeclaringType == typeof(Items) && new string[2] { "IceRing", "FireRing" }.Contains(field.Name); } }