Decompiled source of ExecutionerRebalance v1.0.0

BepInEx/plugins/ExecutionerRebalance/ExecutionerRebalance.dll

Decompiled 11 hours ago
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<SkillLocator>();
				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>(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<IList>(type, taserOrb, "bouncedObjects");
			if (fieldValue == null || fieldValue.Count == 0)
			{
				GameObject fieldValue2 = GetFieldValue<GameObject>(type, taserOrb, "attacker");
				CharacterBody val = (Object.op_Implicit((Object)(object)fieldValue2) ? fieldValue2.GetComponent<CharacterBody>() : 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<float>(type, taserOrb, "procCoefficient");
				SetFieldValue(type, taserOrb, "procCoefficient", fieldValue3 * 1.2f);
			}
		}

		private static T GetFieldValue<T>(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<ModelSkinController>() : 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<CharacterModel>());
			}
		}

		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;
		}
	}
}