public override void WriteNewHooks() { bool runStockScaling = FireboltAttackSpeedStockScaling.Value && FireboltAttackSpeedStockScalingCoefficient.IsNotDefault(); bool runCooldownScaling = FireboltAttackSpeedCooldownScaling.Value && FireboltAttackSpeedCooldownScalingCoefficient.IsNotDefault(); float cooldownCoeff = FireboltAttackSpeedCooldownScalingCoefficient.FloatValue; float stockCoeff = FireboltAttackSpeedStockScalingCoefficient.FloatValue; if (runStockScaling || runCooldownScaling) { IL.RoR2.CharacterBody.RecalculateStats += il => { ILCursor c = new ILCursor(il); c.GotoNext(x => x.MatchRet() ); c.Emit(OpCodes.Ldarg_0); c.Emit <CharacterBody>(OpCodes.Ldfld, "skillLocator"); c.Emit(OpCodes.Ldloc_S, (byte)45); c.Emit(OpCodes.Ldloc_S, (byte)42); c.EmitDelegate <Action <SkillLocator, float, float> >( (skillLocator, cooldownScale, attackSpeed) => { GenericSkill primary = skillLocator != null ? skillLocator.primary : null; if (primary != null && primary.skillName == "FireFirebolt") { if (runCooldownScaling) { float val = cooldownScale * (1 / (1 + cooldownCoeff * (attackSpeed - 1))); primary.cooldownScale = val; } if (runStockScaling) { primary.SetBonusStockFromBody( (int)((attackSpeed - 1) * stockCoeff * primary.baseMaxStock)); } } }); }; } On.EntityStates.Mage.Weapon.Flamethrower.OnEnter += (orig, self) => { Type flamethrowerType = self.GetType(); GameObject go = typeof(EntityState) .GetProperty("gameObject", BindingFlags.NonPublic | BindingFlags.Instance) ?.GetValue(self) as GameObject; CharacterBody body = go.GetComponent <CharacterBody>(); if (FlamethrowerTickFrequencyScaleWithAttackSpeed.Value && FlamethrowerTickFrequencyScaleCoefficient.IsNotDefault()) { float baseVal = FlamethrowerTickFrequency.ValueConfigWrapper.IsNotDefault() ? FlamethrowerTickFrequency.ValueConfigWrapper.FloatValue : VanillaFlamethrowerTickFrequency; float val = baseVal + (body.attackSpeed - 1) * FlamethrowerTickFrequencyScaleCoefficient.FloatValue * baseVal ; flamethrowerType.SetFieldValue("tickFrequency", val ); } if (FlamethrowerDurationScaleDownWithAttackSpeed.Value && FlamethrowerDurationScaleCoefficient.IsNotDefault()) { float baseVal = FlamethrowerDuration.ValueConfigWrapper.IsNotDefault() ? FlamethrowerDuration.ValueConfigWrapper.FloatValue : VanillaFlamethrowerDuration; float val = baseVal - (body.attackSpeed - 1) * FlamethrowerDurationScaleCoefficient.FloatValue * baseVal; if (val < FlamethrowerMinimalDuration.FloatValue) { val = FlamethrowerMinimalDuration.FloatValue; } flamethrowerType.SetFieldValue("baseFlamethrowerDuration", val ); } orig(self); }; }