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 MoreStats v1.3.1
MoreStats.dll
Decompiled 4 months agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using IL.RoR2; using Mono.Cecil.Cil; using MonoMod.Cil; using On.EntityStates; using On.RoR2; using RoR2; using RoR2.Projectile; using RoR2BepInExPack.Utilities; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("MoreStats")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MoreStats")] [assembly: AssemblyTitle("MoreStats")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: UnverifiableCode] namespace MoreStats; public static class BaseStats { public static float TranscendenceShieldConversionFraction = 1f; public static float PerfectedShieldConversionFraction = 1f; public static float OverloadingShieldConversionFraction = 0.5f; public static float BaseShieldDelaySeconds = 7f; public static float MinShieldDelaySeconds = 1f; public static float BarrierLowDecayFactor = 0.5f; public static float BarrierHighDecayFactor = 3f; public static float BarrierDecayStaticMaxHealthTime = 30f; public static int FeatherJumpCountBase = 1; public static int FeatherJumpCountStack = 1; public static bool IncludeStrangeScrapInScrapTotal = true; } [BepInPlugin("com.RiskOfBrainrot.MoreStats", "MoreStats", "1.3.0")] public class MoreStatsPlugin : BaseUnityPlugin { public const string guid = "com.RiskOfBrainrot.MoreStats"; public const string teamName = "RiskOfBrainrot"; public const string modName = "MoreStats"; public const string version = "1.3.0"; public static PluginInfo PInfo { get; private set; } private void Awake() { StatHooks.Init(); OnHit.Init(); OnJump.Init(); } public static void DebugBreakpoint(string methodName, int breakpointNumber = -1) { string text = "MoreStats: " + methodName + " IL hook failed!"; if (breakpointNumber >= 0) { text += $" (breakpoint {breakpointNumber})"; } Debug.LogError((object)text); } } public static class OnHit { public delegate void HitHookEventHandler(CharacterBody attackerBody, DamageInfo damageInfo, CharacterBody victimBody); private static bool initialized; public static event HitHookEventHandler GetHitBehavior; internal static void Init() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (!initialized) { initialized = true; GlobalEventManager.ProcessHitEnemy += new hook_ProcessHitEnemy(GlobalEventManager_OnHitEnemy); } } private static void GlobalEventManager_OnHitEnemy(orig_ProcessHitEnemy orig, GlobalEventManager self, DamageInfo damageInfo, GameObject victim) { if (Object.op_Implicit((Object)(object)damageInfo.attacker) && damageInfo.procCoefficient > 0f) { CharacterBody val = null; CharacterBody victimBody = null; if (damageInfo.attacker.TryGetComponent<CharacterBody>(ref val) && victim.TryGetComponent<CharacterBody>(ref victimBody)) { CharacterMaster master = val.master; if ((Object)(object)master != (Object)null) { DoIgniteOnHit(damageInfo, victim, val, victimBody); OnHit.GetHitBehavior?.Invoke(val, damageInfo, victimBody); } } } orig.Invoke(self, damageInfo, victim); } private static void DoIgniteOnHit(DamageInfo damageInfo, GameObject victim, CharacterBody attackerBody, CharacterBody victimBody) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = attackerBody.inventory; uint? maxStacksFromAttacker = null; if (Object.op_Implicit((Object)(object)damageInfo?.inflictor)) { ProjectileDamage component = damageInfo.inflictor.GetComponent<ProjectileDamage>(); if (Object.op_Implicit((Object)(object)component) && component.useDotMaxStacksFromAttacker) { maxStacksFromAttacker = component.dotMaxStacksFromAttacker; } } float burnChance = StatHooks.GetMoreStatsFromBody(attackerBody).burnChance; if (burnChance > 0f && Util.CheckRoll(burnChance, attackerBody.master)) { InflictDotInfo val = default(InflictDotInfo); val.attackerObject = damageInfo.attacker; val.victimObject = victim; val.totalDamage = damageInfo.damage * 0.5f; val.damageMultiplier = 1f; val.dotIndex = (DotIndex)1; val.maxStacksFromAttacker = maxStacksFromAttacker; InflictDotInfo val2 = val; StrengthenBurnUtils.CheckDotForUpgrade(inventory, ref val2); DotController.InflictDot(ref val2); } } } public static class OnJump { public delegate void OnJumpHandler(CharacterMotor sender, CharacterBody body, ref float verticalBonus); private static bool initialized; public static event OnJumpHandler OnJumpEvent; public static bool IsDoubleJump(CharacterMotor motor, CharacterBody body) { int maxJumpCount = body.maxJumpCount; int baseJumpCount = body.baseJumpCount; int num = motor.jumpCount + 1; if (num > baseJumpCount) { return true; } return false; } public static bool IsBaseJump(CharacterMotor motor, CharacterBody body) { int maxJumpCount = body.maxJumpCount; int baseJumpCount = body.baseJumpCount; int num = motor.jumpCount + 1; if (num <= baseJumpCount) { return true; } return false; } public static bool IsLastJump(CharacterMotor motor, CharacterBody body) { int maxJumpCount = body.maxJumpCount; int baseJumpCount = body.baseJumpCount; int num = motor.jumpCount + 1; if (num == maxJumpCount) { return true; } return false; } internal static void Init() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (!initialized) { initialized = true; GenericCharacterMain.ApplyJumpVelocity += new hook_ApplyJumpVelocity(CharacterMain_JumpVelocity); } } private static void CharacterMain_JumpVelocity(orig_ApplyJumpVelocity orig, CharacterMotor characterMotor, CharacterBody characterBody, float horizontalBonus, float verticalBonus, bool vault) { OnJump.OnJumpEvent?.Invoke(characterMotor, characterBody, ref verticalBonus); orig.Invoke(characterMotor, characterBody, horizontalBonus, verticalBonus, vault); } } public class MoreStatCoefficients { public bool barrierDecayFrozen = false; public float barrierDecayDynamicHalfLife = 0f; public float barrierGenRate = 0f; public float barrierDrainRate = 0f; public float barrierDecayMult = 1f; public float luckFromBody = 0f; public float luckFromMaster = 0f; public float burnChance = 0f; public bool shieldRechargeReady = true; public float shieldRechargeDelay = BaseStats.BaseShieldDelaySeconds; private float shieldToHealthConversion = 0f; public float selfExecutionThresholdAdd = 0f; public float selfExecutionThresholdBase = float.NegativeInfinity; public float healingMult = 1f; public int bodyScrapWhiteCount = 0; public int bodyScrapGreenCount = 0; public int bodyScrapRedCount = 0; public int bodyScrapYellowCount = 0; internal void ResetStats() { barrierDecayFrozen = false; barrierDecayDynamicHalfLife = 0f; barrierGenRate = 0f; luckFromBody = 0f; burnChance = 0f; shieldRechargeReady = true; shieldRechargeDelay = BaseStats.BaseShieldDelaySeconds; selfExecutionThresholdAdd = 0f; selfExecutionThresholdBase = 0f; healingMult = 1f; bodyScrapWhiteCount = 0; bodyScrapGreenCount = 0; bodyScrapRedCount = 0; bodyScrapYellowCount = 0; } } public static class StatHooks { public class MoreStatHookEventArgs { public int barrierFreezeCount = 0; public float barrierDecayRatePercentIncreaseMult = 1f; public float barrierDecayRatePercentDecreaseDiv = 1f; public float barrierGenerationRateAddPostMult = 0f; public float barrierDecayRateAddPreMult = 0f; public int jumpCountAdd = 0; public float burnChanceOnHit = 0f; public float shieldToHealthConversionFractionAdd = 0f; public float shieldDelaySecondsIncreaseAddPreMult = 0f; public float shieldDelaySecondsIncreaseAddPostMult = 0f; public float shieldDelayPercentIncreaseMult = 1f; public float shieldDelayPercentDecreaseDiv = 1f; public float luckAdd = 0f; public float selfExecutionThresholdAdd = 0f; public float healingPercentIncreaseMult = 1f; public int scrapWhiteCountAdd = 0; public int scrapGreenCountAdd = 0; public int scrapRedCountAdd = 0; public int scrapYellowCountAdd = 0; public float barrierDecayMultiplier { get { if (barrierDecayRatePercentDecreaseDiv <= 0f || barrierDecayRatePercentIncreaseMult <= 0f) { return 0f; } return barrierDecayRatePercentIncreaseMult / barrierDecayRatePercentDecreaseDiv; } } public float shieldDelayMultiplier { get { if (shieldDelayPercentDecreaseDiv <= 0f || shieldDelayPercentIncreaseMult <= 0f) { return 0f; } return shieldDelayPercentIncreaseMult / shieldDelayPercentDecreaseDiv; } } public float selfExecutionThresholdBase { get; private set; } = float.NegativeInfinity; public float ModifyBaseExecutionThreshold(float newThreshold, bool condition) { if (newThreshold <= 0f || selfExecutionThresholdBase >= 1f) { return selfExecutionThresholdBase; } if (condition && newThreshold > selfExecutionThresholdBase) { selfExecutionThresholdBase = newThreshold; } return selfExecutionThresholdBase; } } public delegate void MoreStatHookEventHandler(CharacterBody sender, MoreStatHookEventArgs args); private static bool initialized = false; public static FixedConditionalWeakTable<CharacterBody, MoreStatCoefficients> characterCustomStats = new FixedConditionalWeakTable<CharacterBody, MoreStatCoefficients>(); private static MoreStatHookEventArgs StatMods; private static MoreStatCoefficients CustomStats; public static event MoreStatHookEventHandler GetMoreStatCoefficients; public static MoreStatCoefficients GetMoreStatsFromBody(CharacterBody body) { if ((Object)(object)body == (Object)null) { return null; } return characterCustomStats.GetOrCreateValue(body); } internal static void Init() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown if (!initialized) { initialized = true; CharacterBody.RecalculateStats += new Manipulator(RecalculateMoreStats); CharacterBody.UpdateOutOfCombatAndDanger += new hook_UpdateOutOfCombatAndDanger(UpdateDangerMoreStats); Util.CheckRoll_float_float_CharacterMaster += new hook_CheckRoll_float_float_CharacterMaster(RoundLuckInCheckRoll); HealthComponent.ServerFixedUpdate += new Manipulator(HookHealthComponentUpdate); HealthComponent.GetBarrierDecayRate += new Manipulator(HookBarrierDecayRate); HealthComponent.TakeDamageProcess += new Manipulator(InterceptExecutionThreshold); HealthComponent.GetHealthBarValues += new hook_GetHealthBarValues(DisplayExecutionThreshold); HealthComponent.Heal += new Manipulator(ModifyHealing); DrifterTrashToTreasureController.OnInventoryChanged += new hook_OnInventoryChanged(DrifterUpdateScrapCounts); } } private static void HookHealthComponentUpdate(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ILCursor c = new ILCursor(il); ModifyBarrierDecayRate_ServerFixedUpdate(c); ModifyShieldRechargeReady(c); } private static void ModifyHealing(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) ILCursor val = new ILCursor(il); int num = default(int); if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num) })) { MoreStatsPlugin.DebugBreakpoint("ModifyHealing"); return; } int index = val.Index; val.Index = index + 1; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<float, HealthComponent, float>>((Func<float, HealthComponent, float>)delegate(float healAmt, HealthComponent healthComponent) { CharacterBody body = healthComponent.body; MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(body); return (moreStatsFromBody.healingMult > 0f) ? (healAmt * moreStatsFromBody.healingMult) : healAmt; }); val.Emit(OpCodes.Starg, 1); val.Emit(OpCodes.Ldarg_1); } private static void RecalculateMoreStats(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0009: 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) ILCursor val = new ILCursor(il); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)GetStatMods); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Action<CharacterBody>>((Action<CharacterBody>)delegate(CharacterBody body) { CustomStats = GetMoreStatsFromBody(body); if (Object.op_Implicit((Object)(object)body.master)) { CharacterMaster master = body.master; master.luck -= CustomStats.luckFromBody; } CustomStats.ResetStats(); if (Object.op_Implicit((Object)(object)body.master)) { CharacterMaster master2 = body.master; master2.luck += StatMods.luckAdd; CustomStats.luckFromBody = StatMods.luckAdd; } CustomStats.burnChance = StatMods.burnChanceOnHit; CustomStats.healingMult = StatMods.healingPercentIncreaseMult; CustomStats.barrierDecayFrozen = StatMods.barrierFreezeCount > 0; CustomStats.barrierDrainRate = StatMods.barrierDecayRateAddPreMult; CustomStats.barrierDecayMult = StatMods.barrierDecayMultiplier; CustomStats.barrierGenRate = StatMods.barrierGenerationRateAddPostMult; float num = (BaseStats.BaseShieldDelaySeconds + StatMods.shieldDelaySecondsIncreaseAddPreMult) * StatMods.shieldDelayMultiplier + StatMods.shieldDelaySecondsIncreaseAddPostMult; CustomStats.shieldRechargeDelay = Mathf.Max(BaseStats.MinShieldDelaySeconds, num); UpdateShieldRechargeReady(body, CustomStats); CustomStats.selfExecutionThresholdAdd = StatMods.selfExecutionThresholdAdd; CustomStats.selfExecutionThresholdBase = StatMods.selfExecutionThresholdBase; }); ProcessLuck(val); ProcessMaxJumpCount(val); ProcessScrapCounts(val); } private static void GetStatMods(CharacterBody body) { StatMods = new MoreStatHookEventArgs(); if (StatHooks.GetMoreStatCoefficients != null) { StatHooks.GetMoreStatCoefficients(body, StatMods); } } private static void ProcessLuck(ILCursor c) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) c.Index = 0; if (!c.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterMaster>(x, "set_luck") })) { MoreStatsPlugin.DebugBreakpoint("ProcessLuck"); return; } c.EmitDelegate<Func<float>>((Func<float>)(() => StatMods.luckAdd)); c.Emit(OpCodes.Add); } private static void HookBarrierDecayRate(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); float num3 = default(float); float num2 = default(float); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num3), (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num2) })) { val.Remove(); val.Remove(); val.Emit(OpCodes.Ldc_R4, BaseStats.BarrierLowDecayFactor); val.Emit(OpCodes.Ldc_R4, BaseStats.BarrierHighDecayFactor); } else { Debug.LogError((object)"MORE STATS DYNAMIC BARRIER DECAY HOOK FAILED!!!!"); } float num = default(float); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchDiv(x) })) { val.Remove(); val.Emit(OpCodes.Ldc_R4, BaseStats.BarrierDecayStaticMaxHealthTime); } else { Debug.LogError((object)"MORE STATS STATIC BARRIER DECAY HOOK FAILED!!!!"); } } private static void ModifyBarrierDecayRate_ServerFixedUpdate(ILCursor c) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) c.Index = 0; if (c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<HealthComponent>(x, "GetBarrierDecayRate") })) { c.Emit(OpCodes.Ldarg_0); c.EmitDelegate<Func<float, HealthComponent, float>>((Func<float, HealthComponent, float>)delegate(float barrierDecayRatePerSecond, HealthComponent healthComponent) { MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(healthComponent.body); if (moreStatsFromBody == null) { return barrierDecayRatePerSecond; } if (!moreStatsFromBody.barrierDecayFrozen) { barrierDecayRatePerSecond += moreStatsFromBody.barrierDrainRate; barrierDecayRatePerSecond *= moreStatsFromBody.barrierDecayMult; } else { barrierDecayRatePerSecond = 0f; } barrierDecayRatePerSecond -= moreStatsFromBody.barrierGenRate; return barrierDecayRatePerSecond; }); } else { Debug.LogError((object)"MORE STATS BARRIER DECAY HOOK FAILED!!!!"); } } private static void ProcessMaxJumpCount(ILCursor c) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) c.Index = 0; int featherCountLoc = 0; if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.RoR2Content/Items", "Feather") }) || !c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref featherCountLoc) }) || !c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterBody>(x, "baseJumpCount"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, featherCountLoc) })) { MoreStatsPlugin.DebugBreakpoint("ProcessMaxJumpCount"); return; } c.Emit(OpCodes.Ldarg_0); c.EmitDelegate<Func<int, CharacterBody, int>>((Func<int, CharacterBody, int>)delegate(int featherCount, CharacterBody self) { int num = 0; MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(self); if (featherCount > 0) { num += BaseStats.FeatherJumpCountBase + BaseStats.FeatherJumpCountStack * (featherCount - 1); } num += StatMods.jumpCountAdd; return Mathf.Max(num, 0); }); } private static bool RoundLuckInCheckRoll(orig_CheckRoll_float_float_CharacterMaster orig, float percentChance, float luck, CharacterMaster effectOriginMaster) { float num = luck % 1f; if (num < 0f) { num += 1f; } luck = ((!(num > float.Epsilon) || !Util.CheckRoll(num * 100f, 0f, (CharacterMaster)null)) ? ((float)Math.Floor(luck)) : ((float)Math.Ceiling(luck))); return orig.Invoke(percentChance, luck, effectOriginMaster); } private static void UpdateDangerMoreStats(orig_UpdateOutOfCombatAndDanger orig, CharacterBody self) { orig.Invoke(self); MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(self); UpdateShieldRechargeReady(self, moreStatsFromBody); } private static void UpdateShieldRechargeReady(CharacterBody body, MoreStatCoefficients stats) { bool flag = body.outOfDangerStopwatch >= stats.shieldRechargeDelay; if (stats.shieldRechargeReady != flag) { stats.shieldRechargeReady = flag; body.statsDirty = true; } } private static void ModifyShieldRechargeReady(ILCursor c) { c.Index = 0; if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(x, "get_maxShield") }) || !c.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(x, "get_outOfDanger") })) { MoreStatsPlugin.DebugBreakpoint("ModifyShieldRechargeReady"); return; } c.Remove(); c.EmitDelegate<Func<CharacterBody, bool>>((Func<CharacterBody, bool>)delegate(CharacterBody body) { MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(body); return moreStatsFromBody.shieldRechargeReady; }); } private static void InterceptExecutionThreshold(ILContext il) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int thresholdPosition = 0; if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, float.NegativeInfinity), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref thresholdPosition) }) || !val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<HealthComponent>(x, "get_isInFrozenState") })) { MoreStatsPlugin.DebugBreakpoint("InterceptExecutionThreshold"); return; } val.Emit(OpCodes.Ldloc, thresholdPosition); val.Emit(OpCodes.Ldarg, 0); val.EmitDelegate<Func<float, HealthComponent, float>>((Func<float, HealthComponent, float>)((float currentThreshold, HealthComponent hc) => RecalculateExecutionThreshold(currentThreshold, hc))); val.Emit(OpCodes.Stloc, thresholdPosition); } private static float RecalculateExecutionThreshold(float currentThreshold, HealthComponent healthComponent, float mult = 1f) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) CharacterBody body = healthComponent.body; if ((Object)(object)body != (Object)null && !((Enum)body.bodyFlags).HasFlag((Enum)(object)(BodyFlags)16)) { MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(body); float num = Mathf.Max(currentThreshold, moreStatsFromBody.selfExecutionThresholdBase * mult); return num + moreStatsFromBody.selfExecutionThresholdAdd; } return currentThreshold; } private static HealthBarValues DisplayExecutionThreshold(orig_GetHealthBarValues orig, HealthComponent self) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) HealthBarValues val = orig.Invoke(self); val.cullFraction = Mathf.Clamp01(RecalculateExecutionThreshold(val.cullFraction, self, Mathf.Clamp01(1f - (1f - 1f / self.body.cursePenalty)))); return val; } private static void ProcessScrapCounts(ILCursor c) { ProcessScrapCount("ScrapWhite", delegate(int scrapCount, CharacterBody self) { MoreStatCoefficients moreStatsFromBody4 = GetMoreStatsFromBody(self); moreStatsFromBody4.bodyScrapWhiteCount = scrapCount + StatMods.scrapWhiteCountAdd; if (BaseStats.IncludeStrangeScrapInScrapTotal) { moreStatsFromBody4.bodyScrapWhiteCount += self.inventory.GetItemCountEffective(Items.ScrapWhiteSuppressed); } return moreStatsFromBody4.bodyScrapWhiteCount; }); ProcessScrapCount("ScrapGreen", delegate(int scrapCount, CharacterBody self) { MoreStatCoefficients moreStatsFromBody3 = GetMoreStatsFromBody(self); moreStatsFromBody3.bodyScrapGreenCount = scrapCount + StatMods.scrapGreenCountAdd; if (BaseStats.IncludeStrangeScrapInScrapTotal) { moreStatsFromBody3.bodyScrapGreenCount += self.inventory.GetItemCountEffective(Items.ScrapGreenSuppressed); } return moreStatsFromBody3.bodyScrapGreenCount; }); ProcessScrapCount("ScrapRed", delegate(int scrapCount, CharacterBody self) { MoreStatCoefficients moreStatsFromBody2 = GetMoreStatsFromBody(self); moreStatsFromBody2.bodyScrapRedCount = scrapCount + StatMods.scrapRedCountAdd; if (BaseStats.IncludeStrangeScrapInScrapTotal) { moreStatsFromBody2.bodyScrapRedCount += self.inventory.GetItemCountEffective(Items.ScrapRedSuppressed); } return moreStatsFromBody2.bodyScrapRedCount; }); ProcessScrapCount("ScrapYellow", delegate(int scrapCount, CharacterBody self) { MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(self); moreStatsFromBody.bodyScrapYellowCount = scrapCount + StatMods.scrapYellowCountAdd; return moreStatsFromBody.bodyScrapYellowCount; }); void ProcessScrapCount(string scrapName, Func<int, CharacterBody, int> callback) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) c.Index = 0; if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.RoR2Content/Items", scrapName) }) || !c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCountEffective") })) { MoreStatsPlugin.DebugBreakpoint("ProcessScrapCount/" + scrapName); } else { c.Emit(OpCodes.Ldarg_0); c.EmitDelegate<Func<int, CharacterBody, int>>(callback); } } } private static void DrifterUpdateScrapCounts(orig_OnInventoryChanged orig, DrifterTrashToTreasureController self) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) MoreStatCoefficients moreStatsFromBody = GetMoreStatsFromBody(self.body); self.body.SetBuffCount(Buffs.TrashToTreasureWhite.buffIndex, moreStatsFromBody.bodyScrapWhiteCount); self.body.SetBuffCount(Buffs.TrashToTreasureGreen.buffIndex, moreStatsFromBody.bodyScrapGreenCount); self.body.SetBuffCount(Buffs.TrashToTreasureRed.buffIndex, moreStatsFromBody.bodyScrapRedCount); self.body.SetBuffCount(Buffs.TrashToTreasureYellow.buffIndex, moreStatsFromBody.bodyScrapYellowCount); } }