using System; using System.Collections; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using BepInEx; using EntityStates; using EntityStates.Executioner2; using Microsoft.CodeAnalysis; using On.EntityStates; using On.RoR2.Orbs; using RoR2; using RoR2.Orbs; using RoR2.Skills; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 ExecutionerRebalance { [BepInPlugin("toni.executionerrebalance", "Executioner Rebalance", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class ExecutionerRebalancePlugin : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static Action <0>__ApplyBalancePatch; public static hook_OnEnter <1>__EntityStateOnEnter; public static hook_AddOrb <2>__OrbManagerOnAddOrb; } public const string PluginGuid = "toni.executionerrebalance"; public const string PluginName = "Executioner Rebalance"; public const string PluginVersion = "1.0.0"; private const string ExecutionerBodyName = "Executioner2Body"; private const string QuickDashDescription = "Quickly dash forward."; private const string ExecutionDescription = "Leap and slam down for 1500% damage."; private const string ConsecrationDescription = "Consume all Ion Charges to heal, gain movement speed, and reduce your cooldowns by 0.7 second per charge."; private const string DeadlyVoltageDescription = "Fire arcs of lightning forward for 70%-90% damage randomly that can chain between enemies up to 3-6 additional times."; private const float ExecutionDamageCoefficient = 15f; private const float DeadlyVoltageRange = 43.2f; private const float DeadlyVoltageDamageMin = 0.7f; private const float DeadlyVoltageDamageMax = 0.9f; private const float DeadlyVoltagePerBounceScale = 0.6f; private static readonly BindingFlags AllInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly FieldInfo FireTaserAttackRangeField = typeof(FireTaser).GetField("attackRange", AllInstance); private static bool _applied; private void Awake() { RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(ApplyBalancePatch)); } private static void ApplyBalancePatch() { if (!_applied) { _applied = true; PatchConsecrationCooldownDeduction(); PatchExecutionDamage(); PatchExecutionerSkills(); HookDeadlyVoltage(); } } private static void PatchExecutionDamage() { FieldInfo field = typeof(ExecuteSlam).GetField("baseDamageCoefficient", BindingFlags.Static | BindingFlags.Public); if (field != null) { field.SetValue(null, 15f); } } private static void PatchConsecrationCooldownDeduction() { FieldInfo field = typeof(Consecration).GetField("cooldownDeduction", BindingFlags.Static | BindingFlags.NonPublic); if (field != null) { field.SetValue(null, 0.7f); } } private static void PatchExecutionerSkills() { GameObject val = BodyCatalog.FindBodyPrefab("Executioner2Body"); if (Object.op_Implicit((Object)(object)val)) { SkillLocator component = val.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { GenericSkill special = component.special; PatchSpecialCooldown((special != null) ? special.skillFamily : null); GenericSkill primary = component.primary; SkillFamily primaryFamily = ((primary != null) ? primary.skillFamily : null); GenericSkill secondary = component.secondary; PatchPrimaryAndSecondaryDescriptions(primaryFamily, (secondary != null) ? secondary.skillFamily : null); GenericSkill utility = component.utility; AddNoFearUtilityVariant((utility != null) ? utility.skillFamily : null); } } } private static void PatchSpecialCooldown(SkillFamily specialFamily) { if ((Object)(object)specialFamily == (Object)null) { return; } for (int i = 0; i < specialFamily.variants.Length; i++) { SkillDef skillDef = specialFamily.variants[i].skillDef; if (Object.op_Implicit((Object)(object)skillDef)) { Type stateType = ((SerializableEntityStateType)(ref skillDef.activationState)).stateType; if (stateType == typeof(ExecuteHold) || stateType == typeof(ExecuteLeap) || stateType == typeof(ExecuteLeapScepter)) { skillDef.baseRechargeInterval = 16f; skillDef.skillDescriptionToken = "Leap and slam down for 1500% damage."; } } } } private static void PatchPrimaryAndSecondaryDescriptions(SkillFamily primaryFamily, SkillFamily secondaryFamily) { if ((Object)(object)primaryFamily != (Object)null) { for (int i = 0; i < primaryFamily.variants.Length; i++) { SkillDef skillDef = primaryFamily.variants[i].skillDef; if (Object.op_Implicit((Object)(object)skillDef) && ((SerializableEntityStateType)(ref skillDef.activationState)).stateType == typeof(FireTaser)) { skillDef.skillDescriptionToken = "Fire arcs of lightning forward for 70%-90% damage randomly that can chain between enemies up to 3-6 additional times."; } } } if (!((Object)(object)secondaryFamily != (Object)null)) { return; } for (int j = 0; j < secondaryFamily.variants.Length; j++) { SkillDef skillDef2 = secondaryFamily.variants[j].skillDef; if (Object.op_Implicit((Object)(object)skillDef2)) { Type stateType = ((SerializableEntityStateType)(ref skillDef2.activationState)).stateType; if (stateType == typeof(ChargeConsecration) || stateType == typeof(Consecration)) { skillDef2.skillDescriptionToken = "Consume all Ion Charges to heal, gain movement speed, and reduce your cooldowns by 0.7 second per charge."; } } } } private static void AddNoFearUtilityVariant(SkillFamily utilityFamily) { //IL_006e: 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_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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)utilityFamily == (Object)null) && !utilityFamily.variants.Any((Variant v) => Object.op_Implicit((Object)(object)v.skillDef) && ((SerializableEntityStateType)(ref v.skillDef.activationState)).stateType == typeof(CrowdDispersionNoFear))) { int num = Array.FindIndex(utilityFamily.variants, (Variant v) => Object.op_Implicit((Object)(object)v.skillDef) && ((SerializableEntityStateType)(ref v.skillDef.activationState)).stateType == typeof(Dash)); if (num >= 0) { Variant val = utilityFamily.variants[num]; SkillDef skillDef = val.skillDef; SkillDef val2 = Object.Instantiate(skillDef); ((Object)val2).name = skillDef.skillName + "_NoFearRebalance"; val2.skillName = skillDef.skillName + "_NoFearRebalance"; val2.skillNameToken = "Quick Dash"; val2.skillDescriptionToken = "Quickly dash forward."; val2.activationState = new SerializableEntityStateType(typeof(CrowdDispersionNoFear)); val2.baseRechargeInterval = 6f; val2.mustKeyPress = true; val2.cancelSprintingOnActivation = true; val2.canceledFromSprinting = false; Variant val3 = val; val3.skillDef = val2; ((Variant)(ref val3)).viewableNode = new Node(val2.skillNameToken, false, (Node)null); Array.Resize(ref utilityFamily.variants, utilityFamily.variants.Length + 1); utilityFamily.variants[utilityFamily.variants.Length - 1] = val3; } } } private static void HookDeadlyVoltage() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<1>__EntityStateOnEnter; if (obj == null) { hook_OnEnter val = EntityStateOnEnter; <>O.<1>__EntityStateOnEnter = val; obj = (object)val; } EntityState.OnEnter += (hook_OnEnter)obj; object obj2 = <>O.<2>__OrbManagerOnAddOrb; if (obj2 == null) { hook_AddOrb val2 = OrbManagerOnAddOrb; <>O.<2>__OrbManagerOnAddOrb = val2; obj2 = (object)val2; } OrbManager.AddOrb += (hook_AddOrb)obj2; } private static void EntityStateOnEnter(orig_OnEnter orig, EntityState self) { orig.Invoke(self); if (self != null && ((object)self).GetType() == typeof(FireTaser)) { FireTaserAttackRangeField?.SetValue(self, 43.2f); } } private static void OrbManagerOnAddOrb(orig_AddOrb orig, OrbManager self, Orb orb) { if (orb != null && ((object)orb).GetType().Name == "ExecutionerTaserOrb") { PatchTaserOrbValues(orb); } orig.Invoke(self, orb); } private static void PatchTaserOrbValues(Orb taserOrb) { Type type = ((object)taserOrb).GetType(); SetFieldValue(type, taserOrb, "damageCoefficientPerBounce", 0.6f); IList fieldValue = GetFieldValue(type, taserOrb, "bouncedObjects"); if (fieldValue == null || fieldValue.Count == 0) { GameObject fieldValue2 = GetFieldValue(type, taserOrb, "attacker"); CharacterBody val = (Object.op_Implicit((Object)(object)fieldValue2) ? fieldValue2.GetComponent() : null); if ((Object)(object)val != (Object)null) { float num = Random.Range(0.7f, 0.9f); SetFieldValue(type, taserOrb, "damageValue", val.damage * num); } SetFieldValue(type, taserOrb, "bouncesRemaining", Random.Range(3, 7)); } else { float fieldValue3 = GetFieldValue(type, taserOrb, "procCoefficient"); SetFieldValue(type, taserOrb, "procCoefficient", fieldValue3 * 1.2f); } } private static T GetFieldValue(Type type, object instance, string fieldName) { FieldInfo field = type.GetField(fieldName, AllInstance); if (field == null) { return default(T); } object value = field.GetValue(instance); if (value is T) { return (T)value; } return default(T); } private static void SetFieldValue(Type type, object instance, string fieldName, object value) { type.GetField(fieldName, AllInstance)?.SetValue(instance, value); } } public sealed class CrowdDispersionNoFear : BaseSkillState { private const float TurnSpeed = 360f; private const float SpeedMultiplier = 2.4f; private const float HopVelocity = 17f; private const float OverlayDurationScale = 1.3f; private const float ExitTurnSpeed = 720f; private const float AnimationBlendOut = 0.33f; private float _duration; private EntityStateMachine _bodyStateMachine; private Vector3 _currentDirection; private Vector3 _directionVelocity; private bool _playedExitAnimation; private bool _inMasterySkin; public override void OnEnter() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); _duration = 0.9375f; _bodyStateMachine = EntityStateMachine.FindByCustomName(((EntityState)this).gameObject, "Body"); Util.PlayAttackSpeedSound("ExecutionerUtility", ((EntityState)this).gameObject, 1f); ((EntityState)this).PlayAnimation("FullBody, Override", "Dash", "Utility.playbackRate", _duration * 0.33f, 0f); if (!((EntityState)this).characterMotor.isGrounded) { ((BaseState)this).SmallHop(((EntityState)this).characterMotor, 17f); } ((EntityState)this).characterDirection.turnSpeed = 360f; _currentDirection = ((EntityState)this).characterDirection.forward; Transform modelTransform = ((EntityState)this).GetModelTransform(); ModelSkinController val = ((modelTransform != null) ? ((Component)modelTransform).GetComponentInChildren() : null); if ((Object)(object)val != (Object)null && val.skins.Length > ((EntityState)this).characterBody.skinIndex) { _inMasterySkin = val.skins[((EntityState)this).characterBody.skinIndex].nameToken == "SS2_SKIN_EXECUTIONER2_MASTERY"; } if (NetworkServer.active) { if (_inMasterySkin) { EffectManager.SimpleMuzzleFlash(Dash.dashEffectMastery, ((EntityState)this).gameObject, Dash.ExhaustL, true); EffectManager.SimpleMuzzleFlash(Dash.dashEffectMastery, ((EntityState)this).gameObject, Dash.ExhaustR, true); } else { EffectManager.SimpleMuzzleFlash(Dash.dashEffect, ((EntityState)this).gameObject, Dash.ExhaustL, true); EffectManager.SimpleMuzzleFlash(Dash.dashEffect, ((EntityState)this).gameObject, Dash.ExhaustR, true); } } Transform modelTransform2 = ((EntityState)this).GetModelTransform(); if ((Object)(object)modelTransform2 != (Object)null) { TemporaryOverlayInstance obj = TemporaryOverlayManager.AddOverlay(((Component)modelTransform2).gameObject); obj.duration = _duration * 1.3f; obj.animateShaderAlpha = true; obj.alphaCurve = AnimationCurve.EaseInOut(0f, 1f, 1f, 0f); obj.destroyComponentOnEnd = true; obj.originalMaterial = (_inMasterySkin ? Dash.dashMasteryMaterial : Dash.dashMaterial); obj.AddToCharacterModel(((Component)modelTransform2).GetComponent()); } } public override void FixedUpdate() { //IL_004d: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) ((EntityState)this).FixedUpdate(); ((EntityState)this).characterBody.isSprinting = true; bool flag = (Object)(object)_bodyStateMachine != (Object)null && _bodyStateMachine.state is ExecuteLeap; Vector3 val = (flag ? ((EntityState)this).inputBank.moveVector : ((EntityState)this).characterDirection.forward); if (flag) { _playedExitAnimation = true; val = (_currentDirection = Vector3.SmoothDamp(_currentDirection, val, ref _directionVelocity, 0.25f)); } else { _currentDirection = ((EntityState)this).characterDirection.forward; } if ((Object)(object)((EntityState)this).characterDirection != (Object)null && (Object)(object)((EntityState)this).characterMotor != (Object)null) { CharacterMotor characterMotor = ((EntityState)this).characterMotor; characterMotor.rootMotion += val * ((EntityState)this).characterBody.moveSpeed * 2.4f * Time.fixedDeltaTime; } if (((EntityState)this).fixedAge >= _duration) { if (!_playedExitAnimation) { ((EntityState)this).PlayAnimation("FullBody, Override", "DashEnd"); _playedExitAnimation = true; } if (((EntityState)this).isAuthority && !flag) { ((EntityState)this).outer.SetNextStateToMain(); } } } public override void OnExit() { ((EntityState)this).OnExit(); ((EntityState)this).characterDirection.turnSpeed = 720f; if (!_playedExitAnimation) { ((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty"); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)2; } } }