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 T4ylorItems v1.0.0
plugins/T4ylorItems.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using EntityStates; using EntityStates.GoldGat; using EntityStates.HallowedCauldron; using EntityStates.ScavMonster; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On.EntityStates.HallowedCauldron; using On.RoR2; using R2API; using RoR2; using RoR2.Items; using RoR2.Orbs; using RoR2.Projectile; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.SceneManagement; [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("T4ylor")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright T4ylor")] [assembly: AssemblyDescription("Configurable item balance changes with optional LookingGlass item stats for Risk of Rain 2.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("T4ylorItems")] [assembly: AssemblyTitle("T4ylorItems")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 T4ylorItems { [BepInPlugin("com.t4ylor.ror2.items", "T4ylorItems", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { private readonly ConditionalWeakTable<BlastAttack, object> behemothBlasts = new ConditionalWeakTable<BlastAttack, object>(); private BuffDef raincoatSpeed; private bool raincoatRegistered; private NetworkSoundEventDef shieldRechargeSound; private NetworkSoundEventDef shieldBoosterSound; private bool shieldSoundsRegistered; private GoldGatApproval? goldApproval; private LookingGlassRegistry? lookingGlass; public const string Guid = "com.t4ylor.ror2.items"; public const string Version = "1.0.0"; public const string Author = "T4ylor"; private Settings settings; private readonly List<IDisposable> hooks = new List<IDisposable>(); private readonly bool[] ready = new bool[21]; private string? networkKey; private GameObject? tornado; private GameObject? ghostPrefab; private Transform? hitbox; private Vector3 oldHitboxScale; private Vector3 oldGhostScale; private bool initialized; private bool languageHook; private void InstallBatch2() { Install(5, settings.Lenses, delegate { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00aa: Expected O, but got Unknown LensesFeature lenses = new LensesFeature(() => ready[5], settings.LensesDamage); hooks.Add(lenses); AddIL(5, typeof(HealthComponent), "TakeDamageProcess", (Manipulator)delegate(ILContext il) { Batch2Emitters.LensesGate<HealthComponent>(il, lenses.BossGate); }); string[] phaseTypes = EncounterBosses.PhaseTypes; Manipulator val = default(Manipulator); foreach (string name in phaseTypes) { Type type = typeof(Run).Assembly.GetType(name, throwOnError: true); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { Batch2Patterns.ValidatePhase(il.Method, "phaseScriptedCombatEncounter"); Batch2Emitters.AtReturn<EntityState>(il, lenses.Bosses.RegisterPhase); }; Manipulator val3 = val2; val = val2; obj = val3; } AddIL(5, type, "OnEnter", obj); } AddIL(5, typeof(SolusWebMissionController), "Awake", (Manipulator)delegate(ILContext il) { Batch2Patterns.ValidatePhase(il.Method, "combatSquad"); Batch2Emitters.AtReturn<SolusWebMissionController>(il, lenses.Bosses.RegisterSolus); }); lenses.Enable(); }); Install(6, settings.Behemoth, delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown AddIL(6, typeof(GlobalEventManager), "OnHitAllProcess", (Manipulator)delegate(ILContext il) { Batch2Emitters.BehemothMark(il, delegate(BlastAttack blast) { if (ready[6]) { behemothBlasts.GetValue(blast, (BlastAttack _) => new object()); } return blast; }); }); AddIL(6, typeof(BlastAttack), "HandleHits", (Manipulator)delegate(ILContext il) { Batch2Emitters.BehemothDamage(il, (float native, BlastAttack blast, float distance) => (!ready[6] || !behemothBlasts.TryGetValue(blast, out object _)) ? native : (native * Batch2Rules.BehemothCoefficient(distance, blast.radius, settings.BehemothEdge) / 0.6f)); }); }); Install(7, settings.Seed, delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown AddIL(7, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il) { Batch2Emitters.Seed(il, () => ready[7], settings.SeedHeal); }); }); Install(8, settings.Singularity, delegate { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown GameObject obj = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/ElementalRingVoidBlackHole"); ProjectileExplosion component = obj.GetComponent<ProjectileExplosion>(); ProjectileFuse component2 = obj.GetComponent<ProjectileFuse>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || component.blastDamageCoefficient != 1f || component.blastRadius != 15f || (int)component.falloffModel != 1 || component2.fuse != 5f) { throw new InvalidOperationException("Singularity native detonation/pull timing changed; refusing to multiply a modified prefab."); } AddIL(8, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il) { Batch2Emitters.Singularity(il, () => ready[8], settings.SingularityDamage, settings.SingularityCooldown); }); }); } private void RegisterDefensiveContent() { //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_0063: Unknown result type (might be due to invalid IL or missing references) try { raincoatSpeed = ScriptableObject.CreateInstance<BuffDef>(); ((Object)raincoatSpeed).name = "T4ylorItems_RaincoatSpeed"; raincoatSpeed.canStack = false; raincoatSpeed.isDebuff = false; raincoatSpeed.isHidden = false; raincoatSpeed.buffColor = Color32.op_Implicit(new Color32((byte)197, (byte)134, byte.MaxValue, byte.MaxValue)); raincoatRegistered = ContentAddition.AddBuffDef(raincoatSpeed); if (!raincoatRegistered) { throw new InvalidOperationException("ContentAddition rejected the Raincoat speed buff"); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("R01 Raincoat disabled; speed buff registration failed: " + ex)); raincoatRegistered = false; } try { shieldRechargeSound = ScriptableObject.CreateInstance<NetworkSoundEventDef>(); ((Object)shieldRechargeSound).name = "T4ylorItems_ShieldRecharge"; shieldRechargeSound.eventName = "Play_item_proc_personal_shield_recharge"; shieldBoosterSound = ScriptableObject.CreateInstance<NetworkSoundEventDef>(); ((Object)shieldBoosterSound).name = "T4ylorItems_ShieldBoosterRecharge"; shieldBoosterSound.eventName = "Play_item_use_shieldBooster_regen"; bool flag = ContentAddition.AddNetworkSoundEventDef(shieldRechargeSound); bool flag2 = ContentAddition.AddNetworkSoundEventDef(shieldBoosterSound); shieldSoundsRegistered = flag && flag2; if (!shieldSoundsRegistered) { throw new InvalidOperationException("ContentAddition rejected shield audio definitions"); } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("L02 Transcendence disabled; shield sound registration failed: " + ex2)); shieldSoundsRegistered = false; } } private void InstallBatch3() { if (raincoatRegistered) { raincoatSpeed.iconSprite = Buffs.ImmuneToDebuffReady.iconSprite; } DefensiveFeature defense = new DefensiveFeature(settings, ready, raincoatSpeed, shieldRechargeSound, shieldBoosterSound); Manipulator val = default(Manipulator); Manipulator val4 = default(Manipulator); Install(9, settings.Spaces, delegate { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0035: Expected O, but got Unknown //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_006c: Expected O, but got Unknown //IL_0071: Expected O, but got Unknown Plugin plugin = this; Type? typeFromHandle = typeof(HealthComponent); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { DefenseEmitters.ResourceWrites<HealthComponent>(il, defense.Resource); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(9, typeFromHandle, "TakeDamageProcess", obj); Plugin plugin2 = this; Type? typeFromHandle2 = typeof(CharacterBody); Manipulator obj2 = val4; if (obj2 == null) { Manipulator val5 = delegate(ILContext il) { DefenseEmitters.BuffDelta<CharacterBody, TimedBuff>(il, defense.BuffDelta); }; Manipulator val3 = val5; val4 = val5; obj2 = val3; } plugin2.AddIL(9, typeFromHandle2, "UpdateBuffs", obj2); }); Manipulator val6 = default(Manipulator); Manipulator val8 = default(Manipulator); Install(10, settings.Transcendence && shieldSoundsRegistered, delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //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_006c: Expected O, but got Unknown //IL_0071: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00ad: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00e9: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_0125: Expected O, but got Unknown if ((int)shieldRechargeSound.index < 0 || (int)shieldBoosterSound.index < 0) { throw new InvalidOperationException("Shield recharge sound catalog is unavailable"); } defense.ValidateShield(); Plugin plugin = this; Type? typeFromHandle = typeof(HealthComponent); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { DefenseEmitters.ShieldGate<HealthComponent>(il, defense.ShieldGate, defense.ForcedShieldGate); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(10, typeFromHandle, "ServerFixedUpdate", obj); Plugin plugin2 = this; Type? typeFromHandle2 = typeof(HealthComponent); Manipulator obj2 = val4; if (obj2 == null) { Manipulator val5 = delegate(ILContext il) { DefenseEmitters.ShieldRecharge<HealthComponent>(il, defense.ShieldRecharge); }; Manipulator val3 = val5; val4 = val5; obj2 = val3; } plugin2.AddIL(10, typeFromHandle2, "ServerFixedUpdate", obj2); Plugin plugin3 = this; Type? typeFromHandle3 = typeof(HealthComponent); Manipulator obj3 = val6; if (obj3 == null) { Manipulator val7 = delegate(ILContext il) { DefenseEmitters.ResourceWrites<HealthComponent>(il, defense.ShieldResource); }; Manipulator val3 = val7; val6 = val7; obj3 = val3; } plugin3.AddIL(10, typeFromHandle3, "TakeDamageProcess", obj3); Plugin plugin4 = this; Type? typeFromHandle4 = typeof(CharacterBody); Manipulator obj4 = val8; if (obj4 == null) { Manipulator val9 = delegate(ILContext il) { DefenseEmitters.ShieldSound<GameObject>(il, defense.EarlyShieldSound); }; Manipulator val3 = val9; val8 = val9; obj4 = val3; } plugin4.AddIL(10, typeFromHandle4, "OnOutOfDangerChanged", obj4); }); Install(11, settings.Raincoat && raincoatRegistered, delegate { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0035: Expected O, but got Unknown //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_006c: Expected O, but got Unknown //IL_0071: Expected O, but got Unknown Plugin plugin = this; Type? typeFromHandle = typeof(ImmuneToDebuffBehavior); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { DefenseEmitters.Raincoat<CharacterBody>(il, defense.Prevention); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(11, typeFromHandle, "TryApplyOverride", obj); Plugin plugin2 = this; Type? typeFromHandle2 = typeof(CharacterBody); Manipulator obj2 = val4; if (obj2 == null) { Manipulator val5 = delegate(ILContext il) { DefenseEmitters.Movement<CharacterBody>(il, defense.Speed); }; Manipulator val3 = val5; val4 = val5; obj2 = val3; } plugin2.AddIL(11, typeFromHandle2, "RecalculateStats", obj2); }); Install(12, settings.Aegis, delegate { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0035: Expected O, but got Unknown Plugin plugin = this; Type? typeFromHandle = typeof(HealthComponent); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { DefenseEmitters.Decay<HealthComponent>(il, defense.Decay); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(12, typeFromHandle, "GetBarrierDecayRate", obj); }); Manipulator val10 = default(Manipulator); Manipulator val12 = default(Manipulator); Manipulator val14 = default(Manipulator); Install(13, settings.Wake, delegate { //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_0040: Expected O, but got Unknown //IL_0045: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0081: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00bd: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00f9: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_0135: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_0171: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_01ad: Expected O, but got Unknown defense.Wake.ValidateBindings(); Plugin plugin = this; Type? typeFromHandle = typeof(GlobalEventManager); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { DefenseEmitters.WakeSteal<CharacterBody, BuffIndex>(il, defense.Wake.Grant); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(13, typeFromHandle, "OnCharacterDeath", obj); Plugin plugin2 = this; Type? typeFromHandle2 = typeof(HealthComponent); Manipulator obj2 = val4; if (obj2 == null) { Manipulator val5 = delegate(ILContext il) { DefenseEmitters.WakeDamage<HealthComponent, DamageInfo>(il, defense.Wake.Reduce); }; Manipulator val3 = val5; val4 = val5; obj2 = val3; } plugin2.AddIL(13, typeFromHandle2, "TakeDamageProcess", obj2); Plugin plugin3 = this; Type? typeFromHandle3 = typeof(ProjectileManager); Manipulator obj3 = val6; if (obj3 == null) { Manipulator val7 = delegate(ILContext il) { Batch2Emitters.AtReturn<ProjectileController>(il, defense.Wake.Projectile); }; Manipulator val3 = val7; val6 = val7; obj3 = val3; } plugin3.AddIL(13, typeFromHandle3, "InitializeProjectile", obj3); Plugin plugin4 = this; Type? typeFromHandle4 = typeof(ProjectileController); Manipulator obj4 = val8; if (obj4 == null) { Manipulator val9 = delegate(ILContext il) { Batch2Emitters.AtReturn<ProjectileController>(il, defense.Wake.Projectile); }; Manipulator val3 = val9; val8 = val9; obj4 = val3; } plugin4.AddIL(13, typeFromHandle4, "SetOwner", obj4); Plugin plugin5 = this; Type? typeFromHandle5 = typeof(ProjectileController); Manipulator obj5 = val10; if (obj5 == null) { Manipulator val11 = delegate(ILContext il) { Batch2Emitters.AtReturn<ProjectileController>(il, defense.Wake.ProjectileFallback); }; Manipulator val3 = val11; val10 = val11; obj5 = val3; } plugin5.AddIL(13, typeFromHandle5, "Start", obj5); Plugin plugin6 = this; Type? typeFromHandle6 = typeof(DotController); Manipulator obj6 = val12; if (obj6 == null) { Manipulator val13 = delegate(ILContext il) { DefenseEmitters.DotAdded<object>(il, defense.Wake.DotAdded); }; Manipulator val3 = val13; val12 = val13; obj6 = val3; } plugin6.AddIL(13, typeFromHandle6, "OnDotStackAddedServer", obj6); Plugin plugin7 = this; Type? typeFromHandle7 = typeof(DotController); Manipulator obj7 = val14; if (obj7 == null) { Manipulator val15 = delegate(ILContext il) { DefenseEmitters.DotDamage<DotController, object>(il, defense.Wake.DotAmount); DefenseEmitters.DotMark<DamageInfo>(il, defense.Wake.MarkDot); }; Manipulator val3 = val15; val14 = val15; obj7 = val3; } plugin7.AddIL(13, typeFromHandle7, "EvaluateDotStacksForType", obj7); }); hooks.Add(defense); defense.Enable(); } private void InstallBatch4() { KillFeature feature = new KillFeature(settings, ready); Manipulator val4 = default(Manipulator); Manipulator val = default(Manipulator); Install(14, settings.Berzerker, delegate { //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) //IL_003b: Expected O, but got Unknown //IL_0040: Expected O, but got Unknown //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: Expected O, but got Unknown //IL_007c: Expected O, but got Unknown feature.Validate(); Plugin plugin = this; Type? typeFromHandle = typeof(CharacterBody); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { KillEmitters.Frenzy<CharacterBody, BuffDef>(il, feature.Kill, feature.Grant); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(14, typeFromHandle, "AddMultiKill", obj); Plugin plugin2 = this; Type? typeFromHandle2 = typeof(CharacterBody); Manipulator obj2 = val4; if (obj2 == null) { Manipulator val5 = delegate(ILContext il) { KillEmitters.Expiry<CharacterBody, TimedBuff>(il, feature.Expire); }; Manipulator val3 = val5; val4 = val5; obj2 = val3; } plugin2.AddIL(14, typeFromHandle2, "UpdateBuffs", obj2); }); Install(15, settings.Harpoon, delegate { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0035: Expected O, but got Unknown //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_006c: Expected O, but got Unknown //IL_0071: Expected O, but got Unknown Plugin plugin = this; Type? typeFromHandle = typeof(GlobalEventManager); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { KillEmitters.Harpoon(il, () => ready[15], settings.HarpoonStacks, settings.HarpoonFirst, settings.HarpoonAdditional); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(15, typeFromHandle, "OnCharacterDeath", obj); Plugin plugin2 = this; Type? typeFromHandle2 = typeof(CharacterBody); Manipulator obj2 = val4; if (obj2 == null) { Manipulator val5 = delegate(ILContext il) { KillEmitters.HarpoonSpeed<CharacterBody>(il, feature.Speed); }; Manipulator val3 = val5; val4 = val5; obj2 = val3; } plugin2.AddIL(15, typeFromHandle2, "RecalculateStats", obj2); }); Install(16, settings.Nectar, delegate { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0035: Expected O, but got Unknown Plugin plugin = this; Type? typeFromHandle = typeof(CharacterBody); Manipulator obj = val; if (obj == null) { Manipulator val2 = delegate(ILContext il) { KillEmitters.Nectar<CharacterBody>(il, feature.Nectar); }; Manipulator val3 = val2; val = val2; obj = val3; } plugin.AddIL(16, typeFromHandle, "RecalculateStats", obj); }); hooks.Add(feature); feature.Enable(); } private void InstallBatch5() { Install(17, settings.Gesture, delegate { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown ((BaseUnityPlugin)this).Logger.LogInfo((object)"Gesture: validating native bindings and installing equipped-action/Gateway/Crowdfunder hooks."); GestureFeature gesture = new GestureFeature(settings, () => ready[17]); gesture.Validate(); goldApproval = new GoldGatApproval(gesture, () => ready[17], delegate(Exception e) { ready[17] = false; ((BaseUnityPlugin)this).Logger.LogError((object)("Gesture disabled: Crowdfunder approval transport unavailable: " + e)); if (networkKey != null) { RefreshNetworkKey(); } }); hooks.Add(goldApproval); AddIL(17, typeof(EquipmentSlot), "Execute", (Manipulator)delegate(ILContext il) { GenerationEmitters.Equipment<EquipmentSlot, EquipmentDef, EquipmentLocation>(il, gesture.Action, all: false); }); AddIL(17, typeof(EquipmentSlot), "ExecuteAllIfReady", (Manipulator)delegate(ILContext il) { GenerationEmitters.Equipment<EquipmentSlot, EquipmentDef, EquipmentLocation>(il, gesture.Action, all: true); }); AddIL(17, typeof(EquipmentSlot), "FireGateway", (Manipulator)delegate(ILContext il) { GenerationEmitters.Gateway<EquipmentSlot>(il, gesture.Gateway); }); AddIL(17, typeof(GoldGatIdle), "Update", (Manipulator)delegate(ILContext il) { GenerationEmitters.GoldGate<GoldGatIdle>(il, goldApproval.Allow); }); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Gesture hooks installed. Enabled description/misfire will be active; Crowdfunder transport is checked when networking starts."); }); Install(18, settings.SaleStar, delegate { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Expected O, but got Unknown //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Expected O, but got Unknown //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Expected O, but got Unknown SaleStarFeature star = new SaleStarFeature(() => ready[18]); star.Validate(); AddIL(18, typeof(PickupDropTable), "GeneratePickup", (Manipulator)delegate(ILContext il) { GenerationEmitters.AtReturns<UniquePickup>(il, star.Map); }); AddIL(18, typeof(PickupDropTable), "GenerateDrop", (Manipulator)delegate(ILContext il) { GenerationEmitters.AtReturns<PickupIndex>(il, star.MapIndex); }); AddIL(18, typeof(PickupDropTable), "GenerateUniqueDrops", (Manipulator)delegate(ILContext il) { GenerationEmitters.AtReturns<PickupIndex[]>(il, star.MapArray); }); AddIL(18, typeof(PickupDropTable), "GenerateDistinctPickups", (Manipulator)delegate(ILContext il) { GenerationEmitters.GeneratedList<List<UniquePickup>>(il, star.MapList); }); AddIL(18, typeof(ShopTerminalBehavior), "GenerateNewPickupServer", (Manipulator)delegate(ILContext il) { GenerationEmitters.ShopFallback<UniquePickup>(il, star.Map); }, new Type[1] { typeof(bool) }); AddIL(18, typeof(MultiShopController), "CreateTerminals", (Manipulator)delegate(ILContext il) { GenerationEmitters.PreserveTransfer<UniquePickup>(il, star.Map); }); AddIL(18, typeof(ChestBehavior), "PickFromList", (Manipulator)delegate(ILContext il) { GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "NextElementUniform"); }); AddIL(18, typeof(ScavBackpackBehavior), "PickFromList", (Manipulator)delegate(ILContext il) { GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "NextElementUniform"); }); AddIL(18, typeof(BossGroup), "DropRewards", (Manipulator)delegate(ILContext il) { GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "NextElementUniform"); }); AddIL(18, typeof(ShrineChanceBehavior), "AddShrineStack", (Manipulator)delegate(ILContext il) { GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "Evaluate"); }); AddIL(18, typeof(EquipmentSlot), "FireRecycle", (Manipulator)delegate(ILContext il) { GenerationEmitters.Recycle<PickupIndex>(il, star.MapIndex); }); AddIL(18, typeof(CharacterMaster), "TryCloverVoidUpgrades", (Manipulator)delegate(ILContext il) { GenerationEmitters.NewItemTargets<ItemIndex>(il, star.MapItem, clover: true); }); AddIL(18, typeof(Inventory), "GiveRandomItems", (Manipulator)delegate(ILContext il) { GenerationEmitters.NewItemTargets<ItemIndex>(il, star.MapItem, clover: false); }, new Type[1] { typeof(GiveRandomItemsArgs) }); AddIL(18, typeof(FindItem), "OnEnter", (Manipulator)delegate(ILContext il) { GenerationEmitters.ScavSelection<PickupIndex>(il, star.MapIndex); }); AddIL(18, typeof(ItemTransformation), "CanTake", (Manipulator)delegate(ILContext il) { GenerationEmitters.GuardTake<Inventory, CanTakeResult>(il, star.GuardTake, star.AllowTake); }, new Type[2] { typeof(Inventory), typeof(CanTakeResult).MakeByRefType() }); AddIL(18, typeof(ItemTransferOrbDroppable), "OnArrival", (Manipulator)delegate(ILContext il) { GenerationEmitters.PreserveTransfer<UniquePickup>(il, star.Preserve); }); AddIL(18, typeof(ProjectileTransferItem), "DropItem", (Manipulator)delegate(ILContext il) { GenerationEmitters.PreserveTransfer<UniquePickup>(il, star.Preserve); }); hooks.Add(star); star.Enable(); }); } private void Update() { if (initialized && ready[17]) { goldApproval?.Tick(); } } private void InstallAuditFeatures() { Install(19, settings.LaserScope, delegate { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown AddIL(19, typeof(CharacterBody), "RecalculateStats", (Manipulator)delegate(ILContext il) { IntegrationEmitters.Scope(il, (float ordinary, CharacterBody body) => (!ready[19] || !Object.op_Implicit((Object)(object)body.inventory)) ? ordinary : IntegrationRules.Crit(ordinary, body.inventory.GetItemCountEffective(Items.CritDamage), settings.CritFloor)); }); }); Install(20, settings.Suffering, delegate { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown MethodInfo clone = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new MissingMethodException("object.MemberwiseClone"); FieldInfo owner = typeof(SharedSufferingBuffController).GetField("attacker", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (owner == null || owner.FieldType != typeof(CharacterBody)) { throw new MissingFieldException("SharedSufferingBuffController.attacker"); } AddIL(20, typeof(SharedSufferingManager), "DealDamage", (Manipulator)delegate(ILContext il) { IntegrationEmitters.Suffering(il, delegate(HealthComponent victim, DamageInfo info) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown if (ready[20] && NetworkServer.active && Object.op_Implicit((Object)(object)victim) && Object.op_Implicit((Object)(object)victim.body)) { SharedSufferingBuffController component = ((Component)victim.body).GetComponent<SharedSufferingBuffController>(); CharacterBody val = ((!Object.op_Implicit((Object)(object)component)) ? ((CharacterBody)null) : ((CharacterBody)owner.GetValue(component))); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.healthComponent) && val.healthComponent.alive && Object.op_Implicit((Object)(object)val.inventory) && val.inventory.GetItemCountEffective(Items.SharedSuffering) > 0 && victim.body.HasBuff(Buffs.SharedSuffering)) { Vector3 corePosition = val.corePosition; Vector3 corePosition2 = victim.body.corePosition; LayerIndex world = LayerIndex.world; if (Physics.Linecast(corePosition, corePosition2, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { DamageInfo val2 = (DamageInfo)clone.Invoke(info, null); val2.damage = IntegrationRules.Payout(info.damage, obstructed: true, settings.OccludedDamage); victim.TakeDamage(val2); return; } } } victim.TakeDamage(info); }); }); }); } private ItemStatContext StatContext(object? source) { CharacterBody val = (CharacterBody)((source is CharacterBody) ? source : null); if (!Object.op_Implicit((Object)(object)val)) { return new ItemStatContext(); } Inventory inventory = val.inventory; HealthComponent healthComponent = val.healthComponent; return new ItemStatContext { HasBody = true, Damage = val.damage, Crit = val.crit, MoveSpeed = val.moveSpeed, Barrier = (Object.op_Implicit((Object)(object)healthComponent) ? healthComponent.barrier : 0f), BarrierCapacity = (Object.op_Implicit((Object)(object)healthComponent) ? healthComponent.fullBarrier : 0f), SpurCharge = val.GetBuffCount(Buffs.JumpDamageStrikeCharge), HarpoonBuffs = val.GetBuffCount(Buffs.KillMoveSpeed), NectarBuffs = val.GetBuffCount(Buffs.BoostAllStatsBuff), HarpoonOwned = (Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCountEffective(Items.MoveSpeedOnKill) > 0), NectarOwned = (Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCountEffective(Items.BoostAllStats) > 0), RaincoatSpeed = (Object.op_Implicit((Object)(object)raincoatSpeed) && val.HasBuff(raincoatSpeed) && Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCountEffective(Items.ImmuneToDebuff) > 0), ActiveStars = (Object.op_Implicit((Object)(object)inventory) ? inventory.GetItemCountEffective(Items.LowerPricedChests) : 0), ConsumedStars = (Object.op_Implicit((Object)(object)inventory) ? inventory.GetItemCountEffective(Items.LowerPricedChestsConsumed) : 0) }; } private void InitializeLookingGlass() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Expected I4, but got Unknown //IL_021a: Expected I4, but got Unknown if (!Chainloader.PluginInfos.TryGetValue("droppod.lookingglass", out var value)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"LookingGlass not installed; optional item stats skipped."); return; } int count = hooks.Count; try { Assembly assembly = ((object)value.Instance).GetType().Assembly; lookingGlass = new LookingGlassRegistry(assembly); hooks.Add(lookingGlass); LookingGlassRegistry registry = lookingGlass; Type type = assembly.GetType("LookingGlass.ItemStatsNameSpace.ItemStats", throwOnError: true); ILHook item = new ILHook((MethodBase)type.GetMethod("GetItemDescription", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), (Manipulator)delegate(ILContext il) { Patch(il, delegate(ILContext context) { LookingGlassEmitters.Item(context, registry.ItemCalculator); }); }); hooks.Add((IDisposable)item); hooks.Add((IDisposable)new ILHook((MethodBase)type.GetMethod("SkillIcon_SkillInfoCDProc", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), (Manipulator)delegate(ILContext il) { Patch(il, delegate(ILContext context) { LookingGlassEmitters.Skill(context, registry.SkillMarkup); }); })); ItemDef[] array = (ItemDef[])(object)new ItemDef[21] { Items.ChainLightningVoid, Items.HalfAttackSpeedHalfCooldowns, Items.FireRing, Items.IceRing, Items.JumpDamageStrike, Items.CritGlassesVoid, Items.Behemoth, Items.Seed, Items.ElementalRingVoid, Items.BearVoid, Items.ShieldOnly, Items.ImmuneToDebuff, Items.BarrierOnOverHeal, Items.HeadHunter, Items.WarCryOnMultiKill, Items.MoveSpeedOnKill, Items.BoostAllStats, Items.AutoCastEquipment, Items.LowerPricedChests, Items.CritDamage, Items.SharedSuffering }; int num = 0; for (int num2 = 0; num2 < array.Length; num2++) { int id = num2; if (ready[id]) { lookingGlass.Install((int)array[id].itemIndex, () => ready[id], (object? body, int n) => ItemStatRows.Build(id, n, settings, StatContext(body)), (id == 7) ? ((Func<float, int, float, List<float>>)((float _, int n, float proc) => new List<float> { (proc > 0f) ? (settings.SeedHeal * (float)Math.Max(0, n)) : 0f })) : null); num++; } } if (ready[18]) { lookingGlass.Install((int)Items.LowerPricedChestsConsumed.itemIndex, () => ready[18], (object? body, int n) => ItemStatRows.Build(18, n, settings, StatContext(body), consumedStar: true)); num++; } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"LookingGlass {value.Metadata.Version}: {num} item stat definitions installed (includes consumed Sale Star). Gameplay unchanged."); void Patch(ILContext il, Action<ILContext> apply) { try { apply(il); } catch (Exception ex2) { registry.Dispose(); ((BaseUnityPlugin)this).Logger.LogWarning((object)("LookingGlass UI hook unavailable; original definitions restored. " + ex2)); throw; } } } catch (Exception ex) { for (int num3 = hooks.Count - 1; num3 >= count; num3--) { hooks[num3].Dispose(); hooks.RemoveAt(num3); } lookingGlass = null; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Optional LookingGlass stats unavailable; original definitions retained. " + ex)); } } private void Awake() { settings = new Settings(((BaseUnityPlugin)this).Config); RegisterDefensiveContent(); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(Initialize)); } private static MethodInfo Method(Type type, string name) { return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMethodException(type.FullName, name); } private void Initialize() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown if (initialized) { return; } initialized = true; Install(0, settings.Polylute, delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown AddIL(0, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il) { Emitters.Constant(il, Patterns.Polylute((IList<Instruction>)il.Body.Instructions), () => ready[0], settings.PolyluteDamage); }); }); Install(1, settings.LightFlux, delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown AddIL(1, typeof(CharacterBody), "RecalculateStats", (Manipulator)delegate(ILContext il) { Emitters.LightFlux(il, () => ready[1], settings.AttackPenalty, settings.ArmorPenalty); }); }); Install(2, settings.Kjaro, delegate { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown PrepareTornado(); AddIL(2, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il) { Emitters.Constant(il, Patterns.BandDamage((IList<Instruction>)il.Body.Instructions, fire: true), () => ready[2], settings.KjaroDamage); }); AddIL(2, typeof(OverlapAttack), "Fire", (Manipulator)delegate(ILContext il) { Emitters.Filter<OverlapAttack, HurtBox>(il, WithinTornado); }); }); Install(3, settings.Runald, delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown AddIL(3, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il) { int index = Patterns.BandDamage((IList<Instruction>)il.Body.Instructions, fire: false); int index2 = Patterns.Slow((IList<Instruction>)il.Body.Instructions); Emitters.Constant(il, index2, () => ready[3], settings.SlowSeconds); Emitters.Constant(il, index, () => ready[3], settings.RunaldDamage); }); }); Install(4, settings.Faraday, delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown AddIL(4, typeof(CharacterBody), "RecalculateStats", (Manipulator)delegate(ILContext il) { int index = Patterns.Faraday((IList<Instruction>)il.Body.Instructions); Emitters.Constant(il, index, () => ready[4], settings.FaradaySpeed / 100f); }); }); InstallBatch2(); InstallBatch3(); InstallBatch4(); InstallBatch5(); InstallAuditFeatures(); Language.GetLocalizedStringByToken += new hook_GetLocalizedStringByToken(Language); languageHook = true; InitializeLookingGlass(); RefreshNetworkKey(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("T4ylorItems 1.0.0: V01/L03/G05/G06/G08/V02/R06/G03/V04/V03/L02/R01/R04/R03/G01/G02/R05/L01/G07/R02/R07 ready = " + string.Join(",", ready) + ". Restart after settings changes. Identical version, settings and hook readiness required on every peer.")); } private void Install(int id, bool enabled, Action action) { if (!enabled) { return; } int count = hooks.Count; try { ready[id] = true; action(); if (!ready[id]) { throw new InvalidOperationException("IL validation failed"); } } catch (Exception arg) { ready[id] = false; for (int num = hooks.Count - 1; num >= count; num--) { hooks[num].Dispose(); hooks.RemoveAt(num); } if (id == 2) { RestoreTornado(); } ((BaseUnityPlugin)this).Logger.LogError((object)$"Item module {id} disabled; vanilla mechanics and descriptions retained: {arg}"); } } private void AddIL(int id, Type type, string name, Manipulator patch, Type[]? parameters = null) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown MethodInfo methodInfo = ((parameters == null) ? Method(type, name) : (type.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null) ?? throw new MissingMethodException(type.FullName, name))); hooks.Add((IDisposable)new ILHook((MethodBase)methodInfo, (Manipulator)delegate(ILContext il) { try { patch.Invoke(il); } catch (Exception ex) { ready[id] = false; if (id == 2) { RestoreTornado(); } ((BaseUnityPlugin)this).Logger.LogError((object)$"Item module {id} IL unavailable in {type.Name}.{name}; active description suppressed. Restart required: {ex}"); if (networkKey != null) { RefreshNetworkKey(); } throw; } })); } private void PrepareTornado() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) tornado = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/FireTornado"); HitBoxGroup component = tornado.GetComponent<HitBoxGroup>(); ProjectileOverlapAttack component2 = tornado.GetComponent<ProjectileOverlapAttack>(); ProjectileSimple component3 = tornado.GetComponent<ProjectileSimple>(); ProjectileController component4 = tornado.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component) || component.hitBoxes.Length != 1 || !Object.op_Implicit((Object)(object)component2) || component2.isSphereOverlap || !Object.op_Implicit((Object)(object)component3) || Mathf.Abs(component3.lifetime - 3.3f) > 0.001f || Mathf.Abs(component2.resetInterval - 0.3f) > 0.001f) { throw new InvalidOperationException("FireTornado components/timing changed."); } hitbox = ((Component)component.hitBoxes[0]).transform; oldHitboxScale = hitbox.localScale; if (Mathf.Abs(oldHitboxScale.x - 13.09843f) > 0.001f || Mathf.Abs(oldHitboxScale.z - 13.09843f) > 0.001f || (Object)(object)hitbox.parent != (Object)(object)tornado.transform) { throw new InvalidOperationException("FireTornado hitbox changed or another mod resized it."); } ghostPrefab = Addressables.LoadAssetAsync<GameObject>((object)component4.ghostPrefabAddress).WaitForCompletion(); if (!Object.op_Implicit((Object)(object)ghostPrefab)) { throw new InvalidOperationException("FireTornado ghost unavailable."); } oldGhostScale = ghostPrefab.transform.localScale; hitbox.localScale = new Vector3(settings.KjaroRadius * 2f, oldHitboxScale.y, settings.KjaroRadius * 2f); ghostPrefab.transform.localScale = new Vector3(oldGhostScale.x * settings.KjaroRadius / 5f, oldGhostScale.y, oldGhostScale.z * settings.KjaroRadius / 5f); } private bool WithinTornado(bool vanilla, OverlapAttack attack, HurtBox target) { //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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_0098: 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) if (!vanilla || !ready[2] || !Object.op_Implicit((Object)(object)attack.inflictor) || !Object.op_Implicit((Object)(object)tornado)) { return vanilla; } ProjectileController component = attack.inflictor.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component) || component.catalogIndex != tornado.GetComponent<ProjectileController>().catalogIndex) { return vanilla; } Collider component2 = ((Component)target).GetComponent<Collider>(); Vector3 position = ((Component)attack.hitBoxGroup.hitBoxes[0]).transform.position; Vector3 val = (Object.op_Implicit((Object)(object)component2) ? component2.ClosestPoint(position) : ((Component)target).transform.position); float num = val.x - position.x; float num2 = val.z - position.z; return num * num + num2 * num2 <= settings.KjaroRadius * settings.KjaroRadius; } private void RestoreTornado() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)hitbox)) { hitbox.localScale = oldHitboxScale; } if (Object.op_Implicit((Object)(object)ghostPrefab)) { ghostPrefab.transform.localScale = oldGhostScale; } hitbox = null; ghostPrefab = null; } private string Language(orig_GetLocalizedStringByToken orig, Language language, string token) { string original = orig.Invoke(language, token); return Text.Override(token, original, settings, ready); } private void RefreshNetworkKey() { lookingGlass?.RestoreInactive(); if (networkKey != null) { NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Where((string k) => k != networkKey).ToArray(); } networkKey = "com.t4ylor.ror2.items;1.0.0;" + settings.Fingerprint(string.Join(",", ready)); NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Append<string>(networkKey).ToArray(); } private void OnDestroy() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(Initialize)); if (languageHook) { Language.GetLocalizedStringByToken -= new hook_GetLocalizedStringByToken(Language); } Array.Clear(ready, 0, ready.Length); for (int num = hooks.Count - 1; num >= 0; num--) { hooks[num].Dispose(); } hooks.Clear(); RestoreTornado(); if (networkKey != null) { NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Where((string k) => k != networkKey).ToArray(); } } } public static class Batch2Patterns { private static bool Field(Instruction i, string name) { object operand = i.Operand; FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null); if (val != null) { return ((MemberReference)val).Name == name; } return false; } private static bool Call(Instruction i, string name) { object operand = i.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null) { return ((MemberReference)val).Name == name; } return false; } private static int Local(Instruction i) { object operand = i.Operand; VariableDefinition val = (VariableDefinition)((operand is VariableDefinition) ? operand : null); if (val == null) { return -1; } return ((VariableReference)val).Index; } private static int One(IList<Instruction> ins, Func<int, bool> predicate, string label) { int[] array = Enumerable.Range(0, ins.Count).Where(predicate).ToArray(); if (array.Length != 1) { throw new InvalidOperationException(label + ": expected one match, got " + array.Length); } return array[0]; } public static int Seed(IList<Instruction> ins) { int n = Patterns.ItemLocal(ins, "Seed"); return One(ins, delegate(int i) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (i + 7 < ins.Count && Local(ins[i]) == n) { OpCode opCode = ins[i].OpCode; if (((object)((OpCode)(ref opCode)).Code/*cast due to .constrained prefix*/).ToString().StartsWith("Ldloc") && ins[i + 1].OpCode == OpCodes.Conv_R4 && ins[i + 2].OpCode == OpCodes.Ldarg_1 && Field(ins[i + 3], "procCoefficient") && ins[i + 4].OpCode == OpCodes.Mul && ins[i + 6].OpCode == OpCodes.Ldc_I4_1) { return Call(ins[i + 7], "Heal"); } } return false; }, "Seed heal amount") + 3; } public static int SingularityDamage(IList<Instruction> ins) { int n = Patterns.ItemLocal(ins, "ElementalRingVoid"); return One(ins, (int i) => i + 3 < ins.Count && Patterns.Float(ins[i], 1f) && Local(ins[i + 1]) == n && ins[i + 2].OpCode == OpCodes.Conv_R4 && ins[i + 3].OpCode == OpCodes.Mul && ins.Skip(i).Take(13).Any((Instruction x) => Call(x, "OnHitProcDamage")), "Singularity aggregate coefficient"); } public static int SingularityCooldown(IList<Instruction> ins) { return One(ins, delegate(int i) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 if (i + 1 < ins.Count && Patterns.Float(ins[i], 20f)) { OpCode opCode = ins[i + 1].OpCode; if ((int)((OpCode)(ref opCode)).Code == 48) { return ins.Skip(Math.Max(0, i - 20)).Take(20).Any((Instruction x) => Field(x, "ElementalRingVoidCooldown")); } } return false; }, "Singularity cooldown loop bound"); } public static int LensesBossGate(IList<Instruction> ins) { int item = One(ins, (int i) => Field(ins[i], "CritGlassesVoid"), "Lenses item"); if (!ins.Skip(item).Take(24).Any((Instruction x) => Patterns.Float(x, 0.5f)) || !ins.Skip(item).Take(28).Any(delegate(Instruction x) { object operand = x.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); return val != null && ((MemberReference)val).Name.Contains("LocalCheckRoll"); })) { throw new InvalidOperationException("Native Lenses chance/roll changed"); } return One(ins, delegate(int i) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 if (i < item && i > item - 20 && Call(ins[i], "get_isBoss")) { OpCode opCode = ins[i + 1].OpCode; return (int)((OpCode)(ref opCode)).Code == 44; } return false; }, "Lenses native boss gate"); } public static int BehemothFire(IList<Instruction> ins) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) int item = One(ins, (int i) => Field(ins[i], "Behemoth"), "Behemoth item"); int num = One(ins, (int i) => i > item && i < item + 130 && Field(ins[i], "falloffModel"), "Behemoth native falloff"); if (ins[num - 1].OpCode != OpCodes.Ldc_I4_0) { throw new InvalidOperationException("Behemoth native falloff is no longer None"); } return One(ins, delegate(int i) { if (i > item && i < item + 130) { object operand = ins[i].Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && ((MemberReference)((MemberReference)val).DeclaringType).FullName == "RoR2.BlastAttack" && ((MemberReference)val).Name == "Fire" && ins.Skip(item).Take(i - item).Any((Instruction x) => Patterns.Float(x, 0.6f))) { return Field(ins[i - 1], "damageType"); } } return false; }, "Native Behemoth blast call"); } public static int BlastBaseDamage(IList<Instruction> ins) { return One(ins, (int i) => i + 3 < ins.Count && Field(ins[i], "baseDamage") && ins[i + 2].OpCode == OpCodes.Mul && Field(ins[i + 3], "damage"), "Blast per-hit damage"); } public static void BlastDistance(IList<Instruction> ins) { One(ins, (int i) => i + 2 < ins.Count && Field(ins[i], "distanceSqr") && Call(ins[i + 1], "Sqrt") && ins[i + 2].OpCode == OpCodes.Stloc_3, "Native blast distance"); } public static void ValidatePhase(MethodDefinition method, string field) { if (!((IEnumerable<Instruction>)method.Body.Instructions).Any((Instruction i) => Field(i, field)) || ((IEnumerable<Instruction>)method.Body.Instructions).Count((Instruction i) => i.OpCode == OpCodes.Ret) != 1) { throw new InvalidOperationException("Encounter phase ownership changed: " + ((MemberReference)method).FullName); } } } public static class Batch2Emitters { public static void Seed(ILContext il, Func<bool> active, float heal) { //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) new ILCursor(il) { Index = Batch2Patterns.Seed((IList<Instruction>)il.Body.Instructions) + 1 }.EmitDelegate<Func<float, float>>((Func<float, float>)((float native) => Batch2Rules.SeedScale(native, active(), heal))); } public static void Singularity(ILContext il, Func<bool> active, float damage, int cooldown) { int item = Batch2Patterns.SingularityDamage((IList<Instruction>)il.Body.Instructions); int item2 = Batch2Patterns.SingularityCooldown((IList<Instruction>)il.Body.Instructions); foreach (var item3 in new(int, float)[2] { (item, damage), (item2, cooldown) }.OrderByDescending(((int, float) x) => x.Item1)) { Emitters.Constant(il, item3.Item1, active, item3.Item2); } } public static void LensesGate<TVictim>(ILContext il, Func<bool, TVictim, bool> gate) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) int num = Batch2Patterns.LensesBossGate((IList<Instruction>)il.Body.Instructions); ILCursor val = new ILCursor(il) { Index = num + 1 }; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<bool, TVictim, bool>>(gate); } public static void BehemothMark<TBlast>(ILContext il, Func<TBlast, TBlast> mark) { //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) new ILCursor(il) { Index = Batch2Patterns.BehemothFire((IList<Instruction>)il.Body.Instructions) }.EmitDelegate<Func<TBlast, TBlast>>(mark); } public static void BehemothDamage<TBlast>(ILContext il, Func<float, TBlast, float, float> damage) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) int num = Batch2Patterns.BlastBaseDamage((IList<Instruction>)il.Body.Instructions); Batch2Patterns.BlastDistance((IList<Instruction>)il.Body.Instructions); ILCursor val = new ILCursor(il) { Index = num + 1 }; val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc_3); val.EmitDelegate<Func<float, TBlast, float, float>>(damage); } public static void AtReturn<T>(ILContext il, Action<T> callback) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where((Instruction i) => i.OpCode == OpCodes.Ret).ToArray(); if (array.Length != 1) { throw new InvalidOperationException("Expected one lifecycle return"); } ILCursor val = new ILCursor(il); val.Goto(array[0], (MoveType)0, false); val.MoveAfterLabels(); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Action<T>>(callback); } } public enum FinalEncounter { Mithrix, FalseSon, Providence, Voidling, SolusHeart, Reaper, LunarScavenger } public static class Batch2Rules { public static readonly IReadOnlyDictionary<FinalEncounter, string[]> Bodies = new Dictionary<FinalEncounter, string[]> { { FinalEncounter.Mithrix, new string[3] { "BrotherBody", "BrotherHurtBody", "BrotherThroneBody" } }, { FinalEncounter.FalseSon, new string[3] { "FalseSonBossBody", "FalseSonBossBodyLunarShard", "FalseSonBossBodyBrokenLunarShard" } }, { FinalEncounter.Providence, new string[1] { "BrotherHauntBody" } }, { FinalEncounter.Voidling, new string[5] { "MiniVoidRaidCrabBodyPhase1", "MiniVoidRaidCrabBodyPhase2", "MiniVoidRaidCrabBodyPhase3", "MiniVoidRaidCrabBodyBase", "VoidRaidCrabBody" } }, { FinalEncounter.SolusHeart, new string[2] { "SolusHeartBody", "SolusHeartBody_Offering" } }, { FinalEncounter.Reaper, new string[1] { "ReaperBossBody" } }, { FinalEncounter.LunarScavenger, new string[4] { "ScavLunar1Body", "ScavLunar2Body", "ScavLunar3Body", "ScavLunar4Body" } } }; public static bool FinalBoss(FinalEncounter encounter, string bodyName, bool member, bool summon) { if (member && !summon) { return Array.IndexOf(Bodies[encounter], bodyName) >= 0; } return false; } public static bool TeleporterBoss(bool member, bool summonedByMember) { if (member) { return !summonedByMember; } return false; } public static float BossDamage(float holderDamage, float coefficient) { return holderDamage * coefficient; } public static float SeedScale(float nativeProc, bool active, float heal) { if (!active) { return nativeProc; } return heal; } public static float LensesChance(int items, float procCoefficient) { return 0.5f * (float)items * procCoefficient; } public static float BehemothCoefficient(float distance, float radius, float edge) { float num = ((radius > 0f) ? Math.Min(1f, Math.Max(0f, distance / radius)) : 0f); return 0.6f + (edge - 0.6f) * num; } } internal sealed class KillFeature : IDisposable { private sealed class Activation { internal TimedBuff entry; internal float spent; internal float allowance; } private readonly Settings s; private readonly bool[] ready; private readonly ConditionalWeakTable<CharacterBody, Activation> activations = new ConditionalWeakTable<CharacterBody, Activation>(); private FieldInfo timers; internal KillFeature(Settings s, bool[] ready) { this.s = s; this.ready = ready; } internal void Validate() { timers = typeof(CharacterBody).GetField("timedBuffs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingFieldException("CharacterBody.timedBuffs"); if (timers.FieldType != typeof(List<TimedBuff>)) { throw new InvalidOperationException("Native timed buff list changed"); } } private List<TimedBuff> Timers(CharacterBody body) { return (List<TimedBuff>)timers.GetValue(body); } private static int Count(CharacterBody b, ItemDef item) { if (!Object.op_Implicit((Object)(object)b) || !Object.op_Implicit((Object)(object)b.inventory)) { return 0; } return b.inventory.GetItemCountEffective(item); } private static bool Alive(CharacterBody b) { if (Object.op_Implicit((Object)(object)b) && Object.op_Implicit((Object)(object)b.healthComponent)) { return b.healthComponent.alive; } return false; } private Activation? Current(CharacterBody body) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (activations.TryGetValue(body, out Activation value) && value.entry.buffIndex == Buffs.WarCryBuff.buffIndex && value.entry.timer > 0f && Timers(body).Contains(value.entry) && body.HasBuff(Buffs.WarCryBuff)) { return value; } activations.Remove(body); return null; } private void Extend(Activation a, int kills) { TimedBuff entry = a.entry; entry.timer += KillRules.Earn(ref a.spent, kills, s.FrenzyBonus, a.allowance); } internal void Kill(CharacterBody body, int kills) { if (!ready[14] || !NetworkServer.active) { return; } if (!Alive(body) || Count(body, Items.WarCryOnMultiKill) <= 0) { activations.Remove(body); return; } Activation activation = Current(body); if (activation != null) { Extend(activation, kills); } } internal void Grant(CharacterBody body, BuffDef buff, float native, int kills) { if (!ready[14]) { body.AddTimedBuff(buff, native); } else if (NetworkServer.active && Alive(body) && Count(body, Items.WarCryOnMultiKill) > 0 && !body.HasBuff(buff)) { activations.Remove(body); int items = Count(body, Items.WarCryOnMultiKill); body.AddTimedBuff(buff, KillRules.FrenzyBase(items, s.FrenzyFirst, s.FrenzyAdditional)); TimedBuff val = ((IEnumerable<TimedBuff>)Timers(body)).LastOrDefault((Func<TimedBuff, bool>)((TimedBuff t) => t.buffIndex == buff.buffIndex && t.timer > 0f)); if (val != null) { Activation activation = new Activation { entry = val, allowance = KillRules.FrenzyBase(items, s.FrenzyAllowance, s.FrenzyAllowanceAdditional) }; activations.Add(body, activation); Extend(activation, KillRules.SubsequentKills(kills, body.multiKillCount - kills)); } } } internal void Expire(CharacterBody body, TimedBuff entry) { if (activations.TryGetValue(body, out Activation value) && value.entry == entry) { activations.Remove(body); } } internal float Speed(float native, CharacterBody body) { if (!ready[15] || Count(body, Items.MoveSpeedOnKill) <= 0) { return native; } return s.HarpoonSpeed; } internal float Nectar(float native, float bonus, CharacterBody body) { if (!ready[16] || Count(body, Items.BoostAllStats) <= 0) { return native; } return KillRules.NectarAcceleration(native, bonus, body.moveSpeed); } internal void Enable() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown CharacterBody.onBodyInventoryChangedGlobal += Inventory; CharacterBody.onBodyDestroyGlobal += Destroyed; GlobalEventManager.OnCharacterDeath += new hook_OnCharacterDeath(Death); } private void ClearFrenzy(CharacterBody body) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (activations.TryGetValue(body, out Activation value) && value.entry.buffIndex == Buffs.WarCryBuff.buffIndex && Timers(body).Remove(value.entry)) { body.RemoveBuff(value.entry.buffIndex); } activations.Remove(body); } private void Inventory(CharacterBody body) { if (NetworkServer.active) { if (ready[14] && Count(body, Items.WarCryOnMultiKill) <= 0) { ClearFrenzy(body); } if (ready[15] && Count(body, Items.MoveSpeedOnKill) <= 0) { body.ClearTimedBuffs(Buffs.KillMoveSpeed); } } } private void Destroyed(CharacterBody body) { activations.Remove(body); } private void Death(orig_OnCharacterDeath orig, GlobalEventManager manager, DamageReport report) { orig.Invoke(manager, report); CharacterBody victimBody = report.victimBody; if (Object.op_Implicit((Object)(object)victimBody) && !Alive(victimBody) && NetworkServer.active) { if (ready[14]) { ClearFrenzy(victimBody); } if (ready[15]) { victimBody.ClearTimedBuffs(Buffs.KillMoveSpeed); } } } public void Dispose() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown CharacterBody.onBodyInventoryChangedGlobal -= Inventory; CharacterBody.onBodyDestroyGlobal -= Destroyed; GlobalEventManager.OnCharacterDeath -= new hook_OnCharacterDeath(Death); } } public static class DefensePatterns { public static bool Field(Instruction i, string name) { object operand = i.Operand; FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null); if (val != null) { return ((MemberReference)val).Name == name; } return false; } public static bool Call(Instruction i, string name) { object operand = i.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null) { return ((MemberReference)val).Name == name; } return false; } private static int Local(Instruction i) { object operand = i.Operand; VariableDefinition val = (VariableDefinition)((operand is VariableDefinition) ? operand : null); if (val == null) { return -1; } return ((VariableReference)val).Index; } private static int One(IList<Instruction> a, Func<int, bool> match, string label) { int[] array = Enumerable.Range(0, a.Count).Where(match).ToArray(); if (array.Length != 1) { throw new InvalidOperationException(label + ": expected one match, got " + array.Length); } return array[0]; } public static (int index, int kind)[] ResourceWrites(IList<Instruction> a) { int count = One(a, (int i) => Field(a[i], "CritGlassesVoid"), "Damage resolution bound"); List<(int, int)> list = new List<(int, int)>(); string[] setters = new string[3] { "set_Networkhealth", "set_Networkshield", "set_Networkbarrier" }; int kind; for (kind = 0; kind < 3; kind++) { int[] array = (from i in Enumerable.Range(0, count) where Call(a[i], setters[kind]) select i).ToArray(); if (array.Length != ((kind == 0) ? 1 : 2)) { throw new InvalidOperationException("Resource damage writes changed: " + setters[kind]); } int[] array2 = array; foreach (int item in array2) { list.Add((item, kind)); } } return list.OrderByDescending(((int, int) x) => x.Item1).ToArray(); } public static int BuffDelta(IList<Instruction> a) { return One(a, (int i) => i + 3 < a.Count && Field(a[i], "timer") && a[i + 1].OpCode == OpCodes.Ldarg_1 && a[i + 2].OpCode == OpCodes.Sub && Field(a[i + 3], "timer"), "Timed-buff countdown delta") + 1; } public static int ShieldGate(IList<Instruction> a) { return One(a, (int i) => Call(a[i], "get_outOfDanger") && a.Skip(i).Take(5).Any((Instruction x) => Field(x, "isShieldRegenForced")), "Shield recharge guard"); } public static int RaincoatBarrier(IList<Instruction> a) { return One(a, (int i) => Call(a[i], "AddBarrier") && a.Take(i).Any((Instruction x) => Field(x, "ImmuneToDebuffReady")), "Raincoat charge consumption barrier"); } public static int MovementBonus(IList<Instruction> a) { return One(a, (int i) => i + 5 < a.Count && Local(a[i]) >= 0 && a[i].OpCode == OpCodes.Ldloc_S && a[i + 1].OpCode == OpCodes.Ldloc_S && a[i + 2].OpCode == OpCodes.Ldloc_S && a[i + 3].OpCode == OpCodes.Div && a[i + 4].OpCode == OpCodes.Mul && Local(a[i + 5]) == Local(a[i]) && a.Skip(i).Take(45).Any((Instruction x) => Call(x, "set_moveSpeed")), "Movement bonus numerator") + 1; } public static int WakeSteal(IList<Instruction> a) { int h = One(a, (int i) => Field(a[i], "HeadHunter"), "Wake item"); return One(a, delegate(int i) { if (i > h && i < h + 60 && Call(a[i], "AddTimedBuff")) { object operand = a[i].Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null) { return ((MemberReference)((ParameterReference)val.Parameters[0]).ParameterType).FullName == "RoR2.BuffIndex"; } } return false; }, "Wake-owned stolen buff grant"); } public static int WakeDamage(IList<Instruction> a) { return One(a, (int i) => i + 3 < a.Count && Field(a[i], "damageCalculation") && a[i + 1].OpCode == OpCodes.Stloc_S && a[i + 2].OpCode == OpCodes.Ldloc_S && Local(a[i + 1]) == Local(a[i + 2]) && a[i + 3].OpCode == OpCodes.Stloc_S, "Final incoming damage calculation"); } public static int DotDamage(IList<Instruction> a) { return One(a, delegate(int i) { if (Field(a[i], "damage")) { object operand = a[i].Operand; FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null); if (val != null && ((MemberReference)((MemberReference)val).DeclaringType).FullName == "RoR2.DotController/DotStack") { return Field(a[i + 1], "damage"); } } return false; }, "Per-stack DOT amount"); } public static int DotTakeDamage(IList<Instruction> a) { return One(a, (int i) => Call(a[i], "TakeDamage"), "DOT damage dispatch"); } } public static class DefenseEmitters { public static void ShieldSound<T>(ILContext il, Func<string, T, uint> sound) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where((Instruction i) => DefensePatterns.Call(i, "PlaySound")).ToArray(); if (array.Length != 2 || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Ldstr && (string)i.Operand == "Play_item_proc_personal_shield_recharge") || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Ldstr && (string)i.Operand == "Play_item_use_shieldBooster_regen")) { throw new InvalidOperationException("Shield start sound paths changed"); } Instruction[] array2 = array; foreach (Instruction val in array2) { ILCursor val2 = new ILCursor(il); val2.Goto(val, (MoveType)0, false); val2.MoveAfterLabels(); val2.Remove(); val2.EmitDelegate<Func<string, T, uint>>(sound); } } public static void ShieldRecharge<T>(ILContext il, Func<float, T, float> recharge) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where((Instruction i) => DefensePatterns.Call(i, "set_Networkshield")).ToArray(); if (array.Length != 1 || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => DefensePatterns.Field(i, "isShieldRegenForced"))) { throw new InvalidOperationException("Actual shield regeneration write changed"); } ILCursor val = new ILCursor(il); val.Goto(array[0], (MoveType)0, false); val.MoveAfterLabels(); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<float, T, float>>(recharge); } public static void ResourceWrites<T>(ILContext il, Func<float, T, int, float> record) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) (int, int)[] array = DefensePatterns.ResourceWrites((IList<Instruction>)il.Body.Instructions); for (int i = 0; i < array.Length; i++) { (int, int) tuple = array[i]; ILCursor val = new ILCursor(il); (val.Index, _) = tuple; val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldc_I4, tuple.Item2); val.EmitDelegate<Func<float, T, int, float>>(record); } } public static void BuffDelta<TBody, TBuff>(ILContext il, Func<float, TBody, TBuff, float> delta) { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il) { Index = DefensePatterns.BuffDelta((IList<Instruction>)il.Body.Instructions) + 1 }; val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc_1); val.EmitDelegate<Func<float, TBody, TBuff, float>>(delta); } public static void ShieldGate<T>(ILContext il, Func<bool, T, bool> gate, Func<bool, T, bool> forcedGate) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) int num = DefensePatterns.ShieldGate((IList<Instruction>)il.Body.Instructions); int item = ((IEnumerable<Instruction>)il.Body.Instructions).Select((Instruction instruction, int index) => (instruction: instruction, index: index)).Single(((Instruction instruction, int index) x) => DefensePatterns.Field(x.instruction, "isShieldRegenForced")).index; ILCursor val = new ILCursor(il) { Index = item + 1 }; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<bool, T, bool>>(forcedGate); val.Index = num + 1; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<bool, T, bool>>(gate); } public static void Raincoat<T>(ILContext il, Action<T> prevention) { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il) { Index = DefensePatterns.RaincoatBarrier((IList<Instruction>)il.Body.Instructions) + 1 }; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Action<T>>(prevention); } public static void Movement<T>(ILContext il, Func<float, T, float> bonus) { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il) { Index = DefensePatterns.MovementBonus((IList<Instruction>)il.Body.Instructions) + 1 }; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<float, T, float>>(bonus); } public static void Decay<T>(ILContext il, Func<float, T, float> decay) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0095: Unknown result type (might be due to invalid IL or missing references) if (((IEnumerable<Instruction>)il.Body.Instructions).Count((Instruction i) => i.OpCode == OpCodes.Ret) != 1 || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => DefensePatterns.Call(i, "get_fullBarrier"))) { throw new InvalidOperationException("Barrier decay method changed"); } ILCursor val = new ILCursor(il); val.Goto(((IEnumerable<Instruction>)il.Body.Instructions).Last(), (MoveType)0, false); val.MoveAfterLabels(); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<float, T, float>>(decay); } public static void WakeSteal<TBody, TBuff>(ILContext il, Action<TBody, TBuff, float> grant) { //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_001c: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il) { Index = DefensePatterns.WakeSteal((IList<Instruction>)il.Body.Instructions) }; val.Remove(); val.EmitDelegate<Action<TBody, TBuff, float>>(grant); } public static void WakeDamage<THealth, TInfo>(ILContext il, Func<float, THealth, TInfo, float> reduce) { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il) { Index = DefensePatterns.WakeDamage((IList<Instruction>)il.Body.Instructions) + 1 }; val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldarg_1); val.EmitDelegate<Func<float, THealth, TInfo, float>>(reduce); } public static void DotDamage<TDot, TStack>(ILContext il, Func<float, TDot, TStack, float> reduce) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_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_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) int num = DefensePatterns.DotDamage((IList<Instruction>)il.Body.Instructions); DefensePatterns.DotTakeDamage((IList<Instruction>)il.Body.Instructions); ILCursor val = new ILCursor(il) { Index = num + 1 }; val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc_3); val.EmitDelegate<Func<float, TDot, TStack, float>>(reduce); } public static void DotMark<TInfo>(ILContext il, Func<TInfo, TInfo> mark) { //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) new ILCursor(il) { Index = DefensePatterns.DotTakeDamage((IList<Instruction>)il.Body.Instructions) }.EmitDelegate<Func<TInfo, TInfo>>(mark); } public static void DotAdded<TStack>(ILContext il, Action<TStack> add) { //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) if (!((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => DefensePatterns.Field(i, "dotDef"))) { throw new InvalidOperationException("DOT stack lifecycle changed"); } ILCursor val = new ILCursor(il); val.Emit(OpCodes.Ldarg_1); val.EmitDelegate<Action<TStack>>(add); } } public static class DefenseRules { public static float ExtraShieldDelay(int stacks, float first, float additional) { if (stacks <= 0) { return 0f; } return first + additional * (float)(stacks - 1); } public static bool ShieldReady(bool native, int stacks, float stopwatch, float nativeDelay, float first, float additional) { if (stacks > 0) { if (native) { return stopwatch >= nativeDelay + ExtraShieldDelay(stacks, first, additional); } return false; } return native; } public static float RaincoatBonus(int stacks, bool buff, float bonus) { if (!(stacks > 0 && buff)) { return 0f; } return bonus; } public static float BarrierMultiplier(float barrier, float capacity, float threshold, float minimum, int items) { if (items > 0 && !(capacity <= 0f) && !float.IsNaN(capacity) && !float.IsInfinity(capacity)) { return Math.Min(1f, Math.Max(minimum, barrier / capacity / threshold)); } return 1f; } public static bool WakeProtected(int items, bool matchingSource, bool stolenActive, bool activeSlotAspect, bool aspectBuffActive) { if (items > 0 && matchingSource) { if (!stolenActive) { return activeSlotAspect && aspectBuffActive; } return true; } return false; } public static float LeaseUntil(float previous, float now, float granted, float nativeRemaining) { return Math.Max(previous, now + Math.Min(granted, nativeRemaining)); } public static float PausedDelta(float delta, float now, float pauseUntil) { return Math.Max(0f, Math.Min(delta, now - pauseUntil)); } } public sealed class QuietPeriod { public float Until { get; private set; } = float.NegativeInfinity; public void ResourceWrite(float previous, float next, float now, float quiet) { if (next < previous) { Until = now + quiet; } } public float Delta(float delta, float now) { return DefenseRules.PausedDelta(delta, now, Until); } } public sealed class ShieldRechargeCue { public bool Pending { get; private set; } public bool Played { get; private set; } public void SuppressEarly() { if (!Played) { Pending = true; } } public void Reset() { Pending = false; Played = false; } public bool Start(bool alive, bool holder, float before, float after) { if (!alive || (!holder && !Pending) || Played || after <= before) { return false; } Played = true; Pending = false; return true; } } internal sealed class DefensiveFeature : IDisposable { private readonly Settings s; private readonly bool[] ready; private readonly BuffDef speed; private readonly ConditionalWeakTable<CharacterBody, QuietPeriod> quiet = new ConditionalWeakTable<CharacterBody, QuietPeriod>(); private readonly ConditionalWeakTable<CharacterBody, ShieldRechargeCue> cues = new ConditionalWeakTable<CharacterBody, ShieldRechargeCue>(); private readonly NetworkSoundEventDef shieldSound; private readonly NetworkSoundEventDef boosterSound; internal readonly WakeFeature Wake; private FieldInfo? dangerWatch; private static float Now => FixedTimeStamp.now.t; internal DefensiveFeature(Settings s, bool[] ready, BuffDef speed, NetworkSoundEventDef shieldSound, NetworkSoundEventDef boosterSound) { this.s = s; this.ready = ready; this.speed = speed; this.shieldSound = shieldSound; this.boosterSound = boosterSound; Wake = new WakeFeature(s, () => ready[13]); } internal uint EarlyShieldSound(string name, GameObject target) { CharacterBody val = (Object.op_Implicit((Object)(object)target) ? target.GetComponent<CharacterBody>() : null); if (!ready[10] || !Object.op_Implicit((Object)(object)val) || !val.healthComponent.alive || Count(val, Items.ShieldOnly) <= 0) { return Util.PlaySound(name, target); } if (NetworkServer.active) { cues.GetValue(val, (CharacterBody _) => new ShieldRechargeCue()).SuppressEarly(); } return 0u; } internal float ShieldResource(float next, HealthComponent health, int kind) { float num = kind switch { 1 => health.shield, 0 => health.health, _ => health.barrier, }; if (ready[10] && NetworkServer.active && Object.op_Implicit((Object)(object)health.body) && next < num) { cues.Remove(health.body); } return next; } internal float ShieldRecharge(float next, HealthComponent health) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) if (!ready[10] || !NetworkServer.active || !Object.op_Implicit((Object)(object)health.body)) { return next; } CharacterBody body = health.body; bool flag = Count(body, Items.ShieldOnly) > 0; if (!cues.TryGetValue(body, out ShieldRechargeCue value)) { if (!flag) { return next; } value = cues.GetValue(body, (CharacterBody _) => new ShieldRechargeCue()); } if (value.Start(health.alive, flag, health.shield, next)) { if (Count(body, Items.ShieldBooster) > 0) { EffectManager.SimpleSoundEffect(boosterSound.index, body.corePosition, true); } EffectManager.SimpleSoundEffect(shieldSound.index, body.corePosition, true); } return next; } private static int Count(CharacterBody body, ItemDef item) { if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.inventory)) { return 0; } return body.inventory.GetItemCountEffective(item); } internal float Resource(float next, HealthComponent health, int kind) { if (ready[9] && NetworkServer.active && health.alive && Count(health.body, Items.BearVoid) > 0) { float num = kind switch { 1 => health.shield, 0 => health.health, _ => health.barrier, }; if (next < num) { quiet.GetValue(health.body, (CharacterBody _) => new QuietPeriod()).ResourceWrite(num, next, Now, s.SpacesPause); } } return next; } internal float BuffDelta(float native, CharacterBody body, TimedBuff buff) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!ready[9] || buff.buffIndex != Buffs.BearVoidCooldown.buffIndex || !body.healthComponent.alive || Count(body, Items.BearVoid) <= 0) { return native; } if (!quiet.TryGetValue(body, out QuietPeriod value)) { return native; } return value.Delta(native, Now); } internal void ValidateShield() { dangerWatch = typeof(CharacterBody).GetField("outOfDangerStopwatch", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingFieldException("CharacterBody.outOfDangerStopwatch"); if (dangerWatch.FieldType != typeof(float)) { throw new InvalidOperationException("Shield danger stopwatch changed"); } } private float DangerTime(CharacterBody body) { return (float)dangerWatch.GetValue(body); } internal bool ShieldGate(bool native, HealthComponent health) { int num = Count(health.body, Items.ShieldOnly); if (ready[10] && num > 0) { return DefenseRules.ShieldReady(native, num, DangerTime(health.body), 7f, s.ShieldDelayFirst, s.ShieldDelayAdditional); } return native; } internal bool ForcedShieldGate(bool native, HealthComponent health) { int num = Count(health.body, Items.ShieldOnly); if (ready[10] && num > 0) { return DefenseRules.ShieldReady(native, num, DangerTime(health.body), 0f, s.ShieldDelayFirst, s.ShieldDelayAdditional); } return native; } internal void Prevention(CharacterBody body) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (ready[11] && NetworkServer.active && body.healthComponent.alive && Count(body, Items.ImmuneToDebuff) > 0) { body.ClearTimedBuffs(speed.buffIndex); body.AddTimedBuff(speed, s.RaincoatSeconds); } } internal float Speed(float native, CharacterBody body) { if (!ready[11]) { return native; } return native + DefenseRules.RaincoatBonus(Count(body, Items.ImmuneToDebuff), body.HasBuff(speed), s.RaincoatSpeed); } internal float Decay(float native, HealthComponent health) { if (!ready[12] || !NetworkServer.active) { return native; } return native * DefenseRules.BarrierMultiplier(health.barrier, health.fullBarrier, s.AegisThreshold, s.AegisMinimum, Count(health.body, Items.BarrierOnOverHeal)); } internal void Enable() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown CharacterBody.onBodyInventoryChangedGlobal += Inventory; CharacterBody.onBodyDestroyGlobal += Destroyed; GlobalEventManager.OnCharacterDeath += new hook_OnCharacterDeath(Death); Wake.Enable(); } private void Inventory(CharacterBody body) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (Count(body, Items.BearVoid) <= 0) { quiet.Remove(body); } if (NetworkServer.active && Object.op_Implicit((Object)(object)speed) && Count(body, Items.ImmuneToDebuff) <= 0 && body.HasBuff(speed)) { body.ClearTimedBuffs(speed.buffIndex); } if (Count(body, Items.ShieldOnly) <= 0 && cues.TryGetValue(body, out ShieldRechargeCue value) && (!value.Pending || (Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.shield >= body.healthComponent.fullShield))) { cues.Remove(body); } } private void Destroyed(CharacterBody body) { quiet.Remove(body); cues.Remove(body); Wake.Cleanup(body); } private void Death(orig_OnCharacterDeath orig, GlobalEventManager manager, DamageReport report) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) Wake.SnapshotDeath(report.victimBody); orig.Invoke(manager, report); if (Object.op_Implicit((Object)(object)report.victimBody) && !report.victimBody.healthComponent.alive) { quiet.Remove(report.victimBody); Wake.Cleanup(report.victimBody); cues.Remove(report.victimBody); if (NetworkServer.active && Object.op_Implicit((Object)(object)speed) && report.victimBody.HasBuff(speed)) { report.victimBody.ClearTimedBuffs(speed.buffIndex); } } } public void Dispose() { //IL_0029: Unknown result type (might be due to invalid IL or m