Decompiled source of AurelionRebalance v1.5.3

AurelionRebalance.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API;
using RoR2;
using RoR2.Projectile;
using RoR2.Skills;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;

[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("AurelionRebalance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.5.3.0")]
[assembly: AssemblyInformationalVersion("1.5.3")]
[assembly: AssemblyProduct("AurelionRebalance")]
[assembly: AssemblyTitle("AurelionRebalance")]
[assembly: AssemblyVersion("1.5.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 AurelionRebalance
{
	internal static class AurelionRefs
	{
		internal static Assembly AurelionAsm;

		internal static Type TAurelion;

		internal static Type TPrefabs;

		internal static Type TPassive;

		internal static FieldInfo FCharacterPrefab;

		internal static FieldInfo FStardustBuff;

		internal static FieldInfo FOrbitalProjectile;

		internal static FieldInfo FNukeProjectile;

		internal static FieldInfo FSpecialOverride;

		internal static FieldInfo FMinSpecialRadius;

		internal static PropertyInfo PPassiveStarCount;

		internal static PropertyInfo PImpactEffect;

		internal static MethodInfo MTcdStatHook;

		internal static bool Ready { get; private set; }

		internal static GameObject CharacterPrefab => (GameObject)FCharacterPrefab.GetValue(null);

		internal static BuffDef StardustBuff => (BuffDef)FStardustBuff.GetValue(null);

		internal static GameObject OrbitalProjectile => (GameObject)FOrbitalProjectile.GetValue(null);

		internal static GameObject NukeProjectile => (GameObject)FNukeProjectile.GetValue(null);

		internal static GameObject ImpactEffect
		{
			get
			{
				object? obj = PImpactEffect?.GetValue(null);
				return (GameObject)((obj is GameObject) ? obj : null);
			}
		}

		internal static float StockMinSpecialRadius { get; private set; } = 12f;

		internal static void Resolve()
		{
			AurelionAsm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Aurelion");
			if (AurelionAsm == null)
			{
				Plugin.Log.LogError((object)"Aurelion assembly not loaded - AurelionRebalance disabled.");
				return;
			}
			TAurelion = AurelionAsm.GetType("Aurelion.Aurelion", throwOnError: false);
			TPrefabs = AurelionAsm.GetType("Aurelion.Prefabs", throwOnError: false);
			TPassive = AurelionAsm.GetType("Aurelion.AurelionPassiveBehaviour", throwOnError: false);
			if (TAurelion == null || TPrefabs == null || TPassive == null)
			{
				Plugin.Log.LogError((object)$"Missing Aurelion types: Aurelion={TAurelion != null}, Prefabs={TPrefabs != null}, Passive={TPassive != null}.");
				return;
			}
			FCharacterPrefab = TAurelion.GetField("characterPrefab", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			FStardustBuff = TPrefabs.GetField("stardust", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			FOrbitalProjectile = TPrefabs.GetField("aurelionOrbitalProjectile", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			FNukeProjectile = TPrefabs.GetField("aurelionNukeProjectile", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			FSpecialOverride = TPassive.GetField("specialOverride", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			FMinSpecialRadius = TPassive.GetField("minSpecialRadius", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			PPassiveStarCount = TPassive.GetProperty("starCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			PImpactEffect = TPrefabs.GetProperty("aurelionOrbitalProjectileImpact", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (FCharacterPrefab == null || FStardustBuff == null || FOrbitalProjectile == null || FNukeProjectile == null || FSpecialOverride == null || FMinSpecialRadius == null || PPassiveStarCount == null)
			{
				Plugin.Log.LogError((object)"Failed to bind one or more Aurelion fields/properties - AurelionRebalance disabled.");
				return;
			}
			StockMinSpecialRadius = (float)FMinSpecialRadius.GetValue(null);
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "TrueCosmicDragon");
			if (assembly != null)
			{
				MTcdStatHook = assembly.GetType("CenterOfTheUniverseUpgrade.CenterOfTheUniverseUpgradePlugin", throwOnError: false)?.GetMethod("OnGetStatCoefficients", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (MTcdStatHook == null)
				{
					Plugin.Log.LogWarning((object)"Could not find TrueCosmicDragon.OnGetStatCoefficients - Stardust stat override will be skipped.");
				}
			}
			else
			{
				Plugin.Log.LogWarning((object)"TrueCosmicDragon assembly not loaded - Stardust stat override will be skipped.");
			}
			Ready = true;
		}

		internal static int ReadStarCount(object collector)
		{
			if (collector == null)
			{
				return 0;
			}
			try
			{
				return (int)PPassiveStarCount.GetValue(collector);
			}
			catch
			{
				return 0;
			}
		}
	}
	internal static class CometDashPatch
	{
		private static readonly HashSet<int> Dashing = new HashSet<int>();

		private static readonly FieldInfo FHealthComponent = AccessTools.Field(typeof(EntityState), "healthComponent");

		internal static void Apply(Harmony h)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("Aurelion.AurelionUtility");
			MethodInfo methodInfo = AccessTools.Method(type, "OnEnter", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(type, "OnExit", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(HealthComponent), "TakeDamage", new Type[1] { typeof(DamageInfo) }, (Type[])null);
			if (methodInfo == null || methodInfo2 == null || methodInfo3 == null)
			{
				Plugin.Log.LogError((object)$"Comet dash DR disabled (onEnter={methodInfo != null}, onExit={methodInfo2 != null}, TakeDamage={methodInfo3 != null}).");
				return;
			}
			h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(CometDashPatch), "OnEnterPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			h.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(CometDashPatch), "OnExitPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			h.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(CometDashPatch), "TakeDamagePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Plugin.Log.LogInfo((object)$"Comet of Legend dash damage reduction active ({RebalanceConfig.CometDamageReduction.Value:0.##} of incoming damage negated).");
		}

		private static int Id(object stateInstance)
		{
			object? obj = FHealthComponent?.GetValue(stateInstance);
			HealthComponent val = (HealthComponent)((obj is HealthComponent) ? obj : null);
			if (val == null || !((Object)(object)val != (Object)null))
			{
				return 0;
			}
			return ((Object)val).GetInstanceID();
		}

		private static void OnEnterPostfix(object __instance)
		{
			int num = Id(__instance);
			if (num != 0)
			{
				Dashing.Add(num);
			}
		}

		private static void OnExitPostfix(object __instance)
		{
			int num = Id(__instance);
			if (num != 0)
			{
				Dashing.Remove(num);
			}
		}

		private static void TakeDamagePrefix(HealthComponent __instance, DamageInfo damageInfo)
		{
			if (!((Object)(object)__instance == (Object)null) && damageInfo != null && !(damageInfo.damage <= 0f))
			{
				float value = RebalanceConfig.CometDamageReduction.Value;
				if (!(value <= 0f) && Dashing.Count != 0 && Dashing.Contains(((Object)__instance).GetInstanceID()))
				{
					damageInfo.damage *= Mathf.Clamp01(1f - value);
				}
			}
		}
	}
	internal static class DescriptionPatch
	{
		private static string D => "<style=cIsDamage>";

		private static string U => "<style=cIsUtility>";

		private static string E => "</style>";

		private static string Sub => "<style=cSub>";

		private static string CC => "<style=cKeywordName><style=cIsDamage>Cosmic Creator</style></style><style=cSub>";

		private static string NL => "\r\n\r\n";

		private static string NL1 => "\r\n";

		private static int Pct(float f)
		{
			return Mathf.RoundToInt(f * 100f);
		}

		private static string ProcNote(float p)
		{
			return $"{Sub}(proc coefficient {p:0.##}){E}";
		}

		internal static void Apply()
		{
			if (!RebalanceConfig.RewriteDescriptions.Value)
			{
				Plugin.Log.LogInfo((object)"Description rewrite disabled by config.");
				return;
			}
			int value = RebalanceConfig.RadiusStackCap.Value;
			string text = "<style=cKeywordName><style=cIsDamage>The Skies Descend</style></style><style=cSub>";
			LanguageAPI.AddOverlay("AURELION_M2NEW_DESCRIPTION", "Aurelion Sol conjures a black hole, dragging enemies towards the centre and dealing " + D + "20% damage" + E + " every 0.25 seconds for 5 seconds, increased to 30% in the centre. Enemies that die in the black hole are counted as Aurelion Sol killing them." + NL + CC + "Enemies that die in the black hole grant 1 stardust each. The black hole's size increases with " + $"{U}stardust{E}{Sub} and caps at {value} {U}stardust{E}{Sub}.");
			LanguageAPI.AddOverlay("AURELION_M2_DESCRIPTION", "Aurelion Sol channels a newborn star which travels in the target direction. When recast or it strays more " + $"than {U}{RebalanceConfig.StarsurgeMaxDistance.Value:0.#} units{E}{Sub} from Aurelion Sol it detonates, " + $"{D}stunning{E} and dealing {D}{Pct(RebalanceConfig.StarsurgeBaseDamageCoefficient.Value)}%{E}, " + "increasing with distance travelled." + NL + CC + $"Damage with distance is increased, scaled to {D}{Pct(RebalanceConfig.StarsurgeBlastRadiusDamageMultiplier.Value)}%{E}{Sub}.");
			LanguageAPI.AddOverlay("AURELION_SPECNEW_DESCRIPTION", "Call down a star to impact the target location after 1.25 seconds, dealing " + $"{D}{Pct(RebalanceConfig.FallingStarDamageCoefficient.Value)}% damage{E} to enemies hit and " + D + "stunning" + E + " them for " + U + "1s" + E + ". " + ProcNote(RebalanceConfig.FallingStarProcCoefficient.Value) + NL + CC + "Falling Star grants 1 " + U + "stardust" + E + Sub + " for each enemy hit. Damage and effect radius increase with " + U + "stardust" + E + Sub + ", at 900 " + U + "stardust" + E + Sub + " this skill permanently becomes " + text);
			string text2 = "Aurelion Sol summons an enormous star to impact the target location after 2 seconds, dealing " + $"{D}{Pct(RebalanceConfig.SkiesDescendDamageCoefficient.Value)}% damage{E} to enemies hit and " + D + "stunning" + E + " them for " + U + "1s" + E + " " + ProcNote(RebalanceConfig.SkiesDescendProcCoefficient.Value) + ", upon impact, a massive shockwave rapidly expands through the map, dealing " + $"{D}{Pct(RebalanceConfig.ShockwaveDamageCoefficient.Value)}% damage{E} to anything caught and slowing them." + NL1 + CC + "Effect radius, shockwave travel distance and damage are all increased with " + U + "stardust" + E + Sub + ".";
			LanguageAPI.AddOverlay("AURELION_SPECNEW2_DESCRIPTION", text2);
			LanguageAPI.AddOverlay("AURELION_SPECNEW2_DESCRIPTION_KEYWORD", text + text2);
			LanguageAPI.AddOverlay("AURELION_UTIL_DESCRIPTION", $"Aurelion Sol flies in a burst of speed in the direction aimed at {U}{RebalanceConfig.CometSpeedMultiplier.Value:0.##}x{E}{Sub} " + "the base speed, further scaling with " + U + "movement speed" + E + Sub + ", and takes " + $"{D}{Pct(RebalanceConfig.CometDamageReduction.Value)}% less damage{E}{Sub} while dashing. " + "If Starsurge is currently active or is cast during Comet of Legend, it will center itself on Aurelion Sol " + $"while he travels and grows at {U}{Pct(RebalanceConfig.StarsurgeCometGrowthMultiplier.Value)}%{E}{Sub} of its usual rate. " + "Can be cancelled at any time by pressing Jump." + NL + CC + "Maximum travel distance is increased further with " + U + "stardust" + E + Sub + ".");
			LanguageAPI.AddOverlay("AURELION_PASSIVE2_DESCRIPTION", "Aurelion Sol can fly at will and his abilities break his foes down to " + U + "stardust" + E + Sub + ". Each " + U + "stardust" + E + Sub + " stack empowers his abilities and, via <style=cKeywordName>True Cosmic Dragon" + E + ", his stats: " + StatSummary() + ". Skill effect radii also grow per stack (see each skill)." + NL + CC);
			Plugin.Log.LogInfo((object)"Skill descriptions rewritten to match config.");
		}

		private static string StatSummary()
		{
			List<string> parts = new List<string>();
			Add(RebalanceConfig.HealthPerStack.Value, "health");
			Add(RebalanceConfig.RegenPerStack.Value, "regen");
			Add(RebalanceConfig.DamagePerStack.Value, "damage");
			Add(RebalanceConfig.AttackSpeedPerStack.Value, "attack speed");
			Add(RebalanceConfig.MoveSpeedPerStack.Value, "move speed");
			Add(RebalanceConfig.CritPerStack.Value, "crit");
			Add(RebalanceConfig.AccelerationPerStack.Value, "acceleration");
			parts.Add("scaling armor");
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < parts.Count; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append((i == parts.Count - 1) ? " and " : ", ");
				}
				stringBuilder.Append(parts[i]);
			}
			stringBuilder.Append(" per stack");
			return stringBuilder.ToString();
			void Add(float perStack, string label)
			{
				if (perStack > 0f)
				{
					parts.Add($"+{perStack * 100f:0.###}% {label}");
				}
			}
		}
	}
	internal static class ImpactVfxPatch
	{
		internal static void Apply()
		{
			GameObject impactEffect = AurelionRefs.ImpactEffect;
			if ((Object)(object)impactEffect == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Impact VFX prefab not found - flash unchanged.");
				return;
			}
			float num = Mathf.Clamp01(RebalanceConfig.ImpactFlashWeight.Value);
			PostProcessVolume componentInChildren = impactEffect.GetComponentInChildren<PostProcessVolume>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.weight = num;
				if (num <= 0f)
				{
					((Behaviour)componentInChildren).enabled = false;
				}
				Plugin.Log.LogInfo((object)$"Falling Star / The Skies Descend impact flash weight -> {num:0.##}.");
			}
			else
			{
				Plugin.Log.LogWarning((object)"Impact VFX has no PostProcessVolume - screen flash unchanged.");
			}
			float num2 = Mathf.Max(0f, RebalanceConfig.ImpactLightMultiplier.Value);
			if (!Mathf.Approximately(num2, 1f))
			{
				Light componentInChildren2 = impactEffect.GetComponentInChildren<Light>(true);
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.intensity *= num2;
					Plugin.Log.LogInfo((object)$"Impact flash light intensity x{num2:0.##} -> {componentInChildren2.intensity:0.##}.");
				}
			}
		}
	}
	internal static class SkillTuningPatch
	{
		internal static void ApplyStatic(Harmony h)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("Aurelion.AurelionNewSpecialCast"), "OnEnter", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(SkillTuningPatch), "ImpactDamageTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogError((object)"AurelionNewSpecialCast.OnEnter not found - Falling Star / Skies Descend impact damage unchanged.");
			}
			MethodInfo methodInfo2 = AccessTools.Method(AccessTools.TypeByName("Aurelion.CometImpact"), "Search", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				h.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(SkillTuningPatch), "ShockwaveDamageTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogError((object)"CometImpact.Search not found - Skies Descend shockwave damage unchanged.");
			}
			MethodInfo methodInfo3 = AccessTools.Method(AurelionRefs.TAurelion, "HealthComponent_TakeDamage", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				h.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(SkillTuningPatch), "BreathBurstTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogError((object)"Aurelion.HealthComponent_TakeDamage not found - Breath of Light burst Stardust scaling unchanged.");
			}
			MethodInfo methodInfo4 = AccessTools.Method(AccessTools.TypeByName("Aurelion.AurelionPrimary"), "OnEnter", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				h.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(SkillTuningPatch), "SolarFlareTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogError((object)"AurelionPrimary.OnEnter not found - Solar Flare Stardust attack-speed unchanged.");
			}
		}

		internal static float FallingStarMult()
		{
			return RebalanceConfig.FallingStarDamageCoefficient.Value;
		}

		internal static float SkiesDescendMult()
		{
			return RebalanceConfig.SkiesDescendDamageCoefficient.Value;
		}

		internal static float ShockwaveMult()
		{
			return RebalanceConfig.ShockwaveDamageCoefficient.Value;
		}

		internal static float ShockwaveStardustRate()
		{
			return 0.05f * RebalanceConfig.ShockwaveStardustDamageMultiplier.Value;
		}

		internal static float BreathBurstStardustRate()
		{
			return 0.01f * RebalanceConfig.BreathOfLightBurstStardustMultiplier.Value;
		}

		internal static float SolarFlareStardustRate()
		{
			return 0.005f * RebalanceConfig.SolarFlareStardustAttackSpeedMultiplier.Value;
		}

		private static bool SwapStarCountLiteral(List<CodeInstruction> code, float stockLiteral, MethodInfo replacement)
		{
			int num = code.FindIndex((CodeInstruction c) => (c.opcode == OpCodes.Callvirt || c.opcode == OpCodes.Call) && c.operand is MethodBase methodBase && methodBase.Name == "get_starCount");
			if (num < 0)
			{
				return false;
			}
			for (int num2 = num + 1; num2 < code.Count && num2 < num + 6; num2++)
			{
				if (code[num2].opcode == OpCodes.Ldc_R4 && code[num2].operand is float num3 && Mathf.Approximately(num3, stockLiteral))
				{
					code[num2].opcode = OpCodes.Call;
					code[num2].operand = replacement;
					return true;
				}
			}
			return false;
		}

		private static IEnumerable<CodeInstruction> BreathBurstTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			if (SwapStarCountLiteral(list, 0.01f, AccessTools.Method(typeof(SkillTuningPatch), "BreathBurstStardustRate", (Type[])null, (Type[])null)))
			{
				Plugin.Log.LogInfo((object)"Breath of Light burst Stardust scaling patched.");
				return list;
			}
			Plugin.Log.LogWarning((object)"Breath of Light burst Stardust scaling: 0.01 literal not found in HealthComponent_TakeDamage - unchanged.");
			return list;
		}

		private static IEnumerable<CodeInstruction> SolarFlareTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			if (SwapStarCountLiteral(list, 0.005f, AccessTools.Method(typeof(SkillTuningPatch), "SolarFlareStardustRate", (Type[])null, (Type[])null)))
			{
				Plugin.Log.LogInfo((object)"Solar Flare Stardust attack-speed patched.");
				return list;
			}
			Plugin.Log.LogWarning((object)"Solar Flare Stardust attack-speed: 0.005 literal not found in AurelionPrimary.OnEnter - unchanged.");
			return list;
		}

		private static IEnumerable<CodeInstruction> ImpactDamageTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo operand = AccessTools.Method(typeof(SkillTuningPatch), "FallingStarMult", (Type[])null, (Type[])null);
			MethodInfo operand2 = AccessTools.Method(typeof(SkillTuningPatch), "SkiesDescendMult", (Type[])null, (Type[])null);
			int num = list.FindIndex((CodeInstruction c) => c.opcode == OpCodes.Ldc_I4_S && c.operand is sbyte b && b == 30);
			int num2 = ((num < 0) ? (-1) : list.FindLastIndex(num, (CodeInstruction c) => c.opcode == OpCodes.Ldc_I4_5));
			if (num >= 0 && num2 >= 0)
			{
				list[num2].opcode = OpCodes.Call;
				list[num2].operand = operand;
				list[num].opcode = OpCodes.Call;
				list[num].operand = operand2;
				Plugin.Log.LogInfo((object)"Falling Star / The Skies Descend impact damage coefficients patched.");
			}
			else
			{
				Plugin.Log.LogWarning((object)$"Impact-damage transpiler could not locate the 5/30 literal pair in AurelionNewSpecialCast.OnEnter (i5={num2}, i30={num}) - Aurelion.dll may have changed; impact damage unchanged.");
			}
			return list;
		}

		private static IEnumerable<CodeInstruction> ShockwaveDamageTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = list.FindIndex((CodeInstruction c) => c.opcode == OpCodes.Ldc_R4 && c.operand is float num2 && Mathf.Approximately(num2, 18f));
			bool flag = num >= 0;
			if (flag)
			{
				list[num].opcode = OpCodes.Call;
				list[num].operand = AccessTools.Method(typeof(SkillTuningPatch), "ShockwaveMult", (Type[])null, (Type[])null);
			}
			bool flag2 = SwapStarCountLiteral(list, 0.05f, AccessTools.Method(typeof(SkillTuningPatch), "ShockwaveStardustRate", (Type[])null, (Type[])null));
			if (flag && flag2)
			{
				Plugin.Log.LogInfo((object)"The Skies Descend shockwave damage (base + Stardust) patched.");
			}
			else
			{
				Plugin.Log.LogWarning((object)$"Shockwave-damage transpiler incomplete (base={flag}, stardust={flag2}) - CometImpact.Search may have changed.");
			}
			return list;
		}

		internal static void ApplyContent()
		{
			GameObject characterPrefab = AurelionRefs.CharacterPrefab;
			if ((Object)(object)characterPrefab == (Object)null)
			{
				Plugin.Log.LogError((object)"Aurelion characterPrefab is null - cooldown patch skipped.");
				return;
			}
			SkillLocator component = characterPrefab.GetComponent<SkillLocator>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)"Aurelion characterPrefab has no SkillLocator - cooldown patch skipped.");
				return;
			}
			SetRecharge(component.secondary, "AURELION_M2NEW", RebalanceConfig.SingularityCooldown.Value, "Singularity");
			SetRecharge(component.special, "AURELION_SPECNEW", RebalanceConfig.FallingStarCooldown.Value, "Falling Star");
			object? value = AurelionRefs.FSpecialOverride.GetValue(null);
			SkillDef val = (SkillDef)((value is SkillDef) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				val.baseRechargeInterval = RebalanceConfig.SkiesDescendCooldown.Value;
				Plugin.Log.LogInfo((object)$"The Skies Descend cooldown -> {val.baseRechargeInterval}s.");
			}
			else
			{
				Plugin.Log.LogError((object)"AurelionPassiveBehaviour.specialOverride is null - Skies Descend cooldown unchanged.");
			}
			SetProc(AurelionRefs.OrbitalProjectile, RebalanceConfig.FallingStarProcCoefficient.Value, "Falling Star");
			SetProc(AurelionRefs.NukeProjectile, RebalanceConfig.SkiesDescendProcCoefficient.Value, "The Skies Descend");
		}

		private static void SetRecharge(GenericSkill slot, string skillName, float seconds, string label)
		{
			//IL_0042: 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)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (((slot == null) ? null : slot.skillFamily?.variants) == null)
			{
				Plugin.Log.LogError((object)(label + ": skill slot/family missing."));
				return;
			}
			Variant[] variants = slot.skillFamily.variants;
			foreach (Variant val in variants)
			{
				if ((Object)(object)val.skillDef != (Object)null && val.skillDef.skillName == skillName)
				{
					val.skillDef.baseRechargeInterval = seconds;
					Plugin.Log.LogInfo((object)$"{label} cooldown -> {seconds}s.");
					return;
				}
			}
			Plugin.Log.LogError((object)(label + ": variant '" + skillName + "' not found in family."));
		}

		private static void SetProc(GameObject projectilePrefab, float proc, string label)
		{
			if ((Object)(object)projectilePrefab == (Object)null)
			{
				Plugin.Log.LogError((object)(label + ": projectile prefab null - proc unchanged."));
				return;
			}
			ProjectileController component = projectilePrefab.GetComponent<ProjectileController>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)(label + ": projectile prefab has no ProjectileController."));
				return;
			}
			component.procCoefficient = proc;
			Plugin.Log.LogInfo((object)$"{label} impact proc coefficient -> {proc}.");
		}
	}
	internal static class StardustRadiusPatch
	{
		private const float SingularityBase = 10f;

		private const float ShockwaveInnerToOuter = 2.5f;

		private static readonly FieldInfo FCometEnlargeImpact = Fld("Aurelion.CometEnlarge", "impact");

		private static readonly FieldInfo FCometEnlargeCollector = Fld("Aurelion.CometEnlarge", "collector");

		private static readonly FieldInfo FCometImpactCollector = Fld("Aurelion.CometImpact", "collector");

		private static readonly FieldInfo FCometImpactSearch = Fld("Aurelion.CometImpact", "search");

		private static readonly FieldInfo FCometImpactMaxRadius = Fld("Aurelion.CometImpact", "maxRadius");

		private static readonly FieldInfo FGravExplosion = Fld("Aurelion.AurelionGravSphereBehaviour", "explosion");

		private static readonly FieldInfo FGravRadialForce = Fld("Aurelion.AurelionGravSphereBehaviour", "radialForce");

		private static readonly FieldInfo FGravCollector = Fld("Aurelion.AurelionGravSphereBehaviour", "collector");

		private static readonly FieldInfo FNewSpecialIndicator = Fld("Aurelion.AurelionNewSpecial", "areaIndicator");

		private static readonly FieldInfo FNewSecondaryIndicator = Fld("Aurelion.AurelionNewSecondary", "areaIndicator");

		private static bool _loggedGrav;

		private static float StockBase => AurelionRefs.StockMinSpecialRadius;

		internal static void Apply(Harmony h)
		{
			Hook(h, "Aurelion.CometEnlarge", "Start", "CometEnlarge_Start");
			Hook(h, "Aurelion.CometImpact", "Start", "CometImpact_Start");
			Hook(h, "Aurelion.AurelionGravSphereBehaviour", "Start", "GravSphere_Start");
			Hook(h, "Aurelion.AurelionNewSpecial", "OnEnter", "NewSpecial_OnEnter");
			Hook(h, "Aurelion.AurelionNewSecondary", "OnEnter", "NewSecondary_OnEnter");
			Plugin.Log.LogInfo((object)($"Radius patch active (Falling Star/Skies base x{RebalanceConfig.SpecialBaseRadiusMultiplier.Value}, " + $"{RebalanceConfig.RadiusGrowthPerStack.Value}/stack; Singularity {RebalanceConfig.SingularityRadiusGrowthPerStack.Value}/stack; " + $"cap {RebalanceConfig.RadiusStackCap.Value}, post-cap x{RebalanceConfig.PostCapRadiusMultiplier.Value}; " + $"shockwave x{RebalanceConfig.ShockwaveRadiusMultiplier.Value})."));
		}

		private static void Hook(Harmony h, string typeName, string method, string postfix)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			Type type = AccessTools.TypeByName(typeName);
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, method, (Type[])null, (Type[])null));
			if (methodInfo == null)
			{
				Plugin.Log.LogError((object)("Radius patch: " + typeName + "." + method + " not found."));
			}
			else
			{
				h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(StardustRadiusPatch), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static float Bonus(int starCount, float perStack, bool hardCap)
		{
			int num = Mathf.Max(0, RebalanceConfig.RadiusStackCap.Value);
			int num2 = Mathf.Min(starCount, num);
			int num3 = Mathf.Max(0, starCount - num);
			float num4 = (hardCap ? 0f : Mathf.Max(0f, RebalanceConfig.PostCapRadiusMultiplier.Value));
			return (float)num2 * perStack + (float)num3 * perStack * num4;
		}

		private static float SpecialImpactRadius(int sc)
		{
			return StockBase * RebalanceConfig.SpecialBaseRadiusMultiplier.Value + Bonus(sc, RebalanceConfig.RadiusGrowthPerStack.Value, hardCap: false);
		}

		private static int StarCount(object instance, FieldInfo collectorField)
		{
			return AurelionRefs.ReadStarCount(collectorField?.GetValue(instance));
		}

		private static FieldInfo Fld(string typeName, string field)
		{
			Type type = AccessTools.TypeByName(typeName);
			FieldInfo fieldInfo = ((type == null) ? null : AccessTools.Field(type, field));
			if (fieldInfo == null)
			{
				Plugin.Log.LogError((object)("Radius patch: field " + typeName + "." + field + " not found."));
			}
			return fieldInfo;
		}

		private static void CometEnlarge_Start(object __instance)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			object? obj = FCometEnlargeImpact?.GetValue(__instance);
			ProjectileExplosion val = (ProjectileExplosion)((obj is ProjectileExplosion) ? obj : null);
			if (val != null)
			{
				float num = (val.blastRadius = SpecialImpactRadius(StarCount(__instance, FCometEnlargeCollector)));
				((Component)((__instance is Component) ? __instance : null)).transform.localScale = Vector3.one * num;
			}
		}

		private static void CometImpact_Start(object __instance)
		{
			//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)
			int starCount = StarCount(__instance, FCometImpactCollector);
			float num = Mathf.Max(0f, RebalanceConfig.ShockwaveRadiusMultiplier.Value);
			float num2 = (StockBase + Bonus(starCount, RebalanceConfig.RadiusGrowthPerStack.Value, hardCap: false)) * num;
			float num3 = 2.5f * (StockBase + Bonus(starCount, RebalanceConfig.ShockwaveMaxGrowthPerStack.Value, hardCap: false)) * num;
			FCometImpactMaxRadius?.SetValue(__instance, num3);
			object? obj = FCometImpactSearch?.GetValue(__instance);
			SphereSearch val = (SphereSearch)((obj is SphereSearch) ? obj : null);
			if (val != null)
			{
				val.radius = num2;
				((Component)((__instance is Component) ? __instance : null)).transform.localScale = Vector3.one * num2;
			}
		}

		private static void GravSphere_Start(object __instance)
		{
			//IL_0074: 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)
			object? obj = FGravExplosion?.GetValue(__instance);
			ProjectileExplosion val = (ProjectileExplosion)((obj is ProjectileExplosion) ? obj : null);
			if (val != null)
			{
				int num = StarCount(__instance, FGravCollector);
				float num2 = (val.blastRadius = 10f + Bonus(num, RebalanceConfig.SingularityRadiusGrowthPerStack.Value, hardCap: true));
				object? obj2 = FGravRadialForce?.GetValue(__instance);
				RadialForce val2 = (RadialForce)((obj2 is RadialForce) ? obj2 : null);
				if (val2 != null)
				{
					val2.radius = num2;
				}
				((Component)((__instance is Component) ? __instance : null)).transform.localScale = Vector3.one * num2;
				if (!_loggedGrav)
				{
					_loggedGrav = true;
					Plugin.Log.LogInfo((object)($"Singularity radius: starCount={num}, cap={RebalanceConfig.RadiusStackCap.Value}, " + $"perStack={RebalanceConfig.SingularityRadiusGrowthPerStack.Value} -> radius {num2:0.##} (stock would be {10f + (float)num * 0.05f:0.##})."));
				}
			}
		}

		private static void NewSpecial_OnEnter(object __instance)
		{
			object collector = BehaviourField(__instance.GetType())?.GetValue(__instance);
			SetIndicator(__instance, FNewSpecialIndicator, SpecialImpactRadius(AurelionRefs.ReadStarCount(collector)));
		}

		private static void NewSecondary_OnEnter(object __instance)
		{
			object collector = BehaviourField(__instance.GetType())?.GetValue(__instance);
			float radius = 10f + Bonus(AurelionRefs.ReadStarCount(collector), RebalanceConfig.SingularityRadiusGrowthPerStack.Value, hardCap: true);
			SetIndicator(__instance, FNewSecondaryIndicator, radius);
		}

		private static void SetIndicator(object stateInstance, FieldInfo indicatorField, float radius)
		{
			//IL_0025: 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)
			object? obj = indicatorField?.GetValue(stateInstance);
			GameObject val = (GameObject)((obj is GameObject) ? obj : null);
			if (val != null && (Object)(object)val != (Object)null)
			{
				val.transform.localScale = Vector3.one * Mathf.Max(0f, radius);
			}
		}

		private static FieldInfo BehaviourField(Type stateType)
		{
			return AccessTools.Field(stateType, "behaviour");
		}
	}
	internal static class StardustStatsPatch
	{
		private static readonly FieldInfo AccelBackingField = typeof(CharacterBody).GetField("<acceleration>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);

		internal static void Apply(Harmony h)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			if (!RebalanceConfig.EnableStatOverride.Value)
			{
				Plugin.Log.LogInfo((object)"Stardust stat override disabled by config - True Cosmic Dragon's handler runs unchanged.");
				return;
			}
			if (AurelionRefs.MTcdStatHook == null)
			{
				Plugin.Log.LogWarning((object)"Skipping Stardust stat override (TCD hook not resolved).");
				return;
			}
			h.Patch((MethodBase)AurelionRefs.MTcdStatHook, new HarmonyMethod(typeof(StardustStatsPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Plugin.Log.LogInfo((object)($"Stardust stat override active (moveSpeed/stack={RebalanceConfig.MoveSpeedPerStack.Value}, " + $"accel/stack={RebalanceConfig.AccelerationPerStack.Value}, crit/stack={RebalanceConfig.CritPerStack.Value})."));
		}

		private static bool Prefix(CharacterBody sender, StatHookEventArgs args)
		{
			if ((Object)(object)sender == (Object)null)
			{
				return false;
			}
			BuffDef stardustBuff = AurelionRefs.StardustBuff;
			if ((Object)(object)stardustBuff == (Object)null)
			{
				return false;
			}
			int buffCount = sender.GetBuffCount(stardustBuff);
			if (buffCount <= 0)
			{
				return false;
			}
			float num = buffCount;
			args.healthMultAdd += RebalanceConfig.HealthPerStack.Value * num;
			args.regenMultAdd += RebalanceConfig.RegenPerStack.Value * num;
			args.damageMultAdd += RebalanceConfig.DamagePerStack.Value * num;
			args.attackSpeedMultAdd += RebalanceConfig.AttackSpeedPerStack.Value * num;
			args.moveSpeedMultAdd += RebalanceConfig.MoveSpeedPerStack.Value * num;
			args.critAdd += RebalanceConfig.CritPerStack.Value * num;
			float num2 = Mathf.Log(1f + RebalanceConfig.ArmorLogInner.Value * num) * RebalanceConfig.ArmorLogOuter.Value;
			if (num2 < 1f)
			{
				args.armorAdd += 100f * num2 / (1f - num2);
			}
			float value = RebalanceConfig.AccelerationPerStack.Value;
			if (value > 0f)
			{
				float num3 = (sender.baseAcceleration = 14f * (1f + value * num));
				AccelBackingField?.SetValue(sender, num3);
			}
			sender.sprintingSpeedMultiplier = RebalanceConfig.SprintMultiplier.Value;
			return false;
		}
	}
	internal static class StarsurgeCometPatch
	{
		private static readonly FieldInfo FSpeedMultiplier = FieldOf("Aurelion.AurelionSecondaryBehaviour", "speedMultiplier");

		private static readonly FieldInfo FUtilController = FieldOf("Aurelion.AurelionUtility", "controller");

		private static readonly FieldInfo FCtrlBehaviour = FieldOf("Aurelion.AurelionSecondaryController", "behaviour");

		internal static float BaseDamage()
		{
			return RebalanceConfig.StarsurgeBaseDamageCoefficient.Value;
		}

		internal static float GrowthRate()
		{
			return RebalanceConfig.StarsurgeGrowthPerSecond.Value;
		}

		internal static float StardustPerStack()
		{
			return RebalanceConfig.StarsurgeStardustDamagePerStack.Value;
		}

		internal static float BlastRadiusDamageMult()
		{
			return RebalanceConfig.StarsurgeBlastRadiusDamageMultiplier.Value;
		}

		internal static float MaxDistance()
		{
			return RebalanceConfig.StarsurgeMaxDistance.Value;
		}

		internal static float CometSpeed()
		{
			return RebalanceConfig.CometSpeedMultiplier.Value;
		}

		internal static void ApplyStatic(Harmony h)
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("Aurelion.AurelionSecondaryBehaviour");
			Type type2 = AccessTools.TypeByName("Aurelion.AurelionSecondaryController");
			Type type3 = AccessTools.TypeByName("Aurelion.AurelionSecondary");
			Type type4 = AccessTools.TypeByName("Aurelion.AurelionUtility");
			Patch(h, AccessTools.DeclaredConstructor(type, Type.EmptyTypes, false), "CtorTranspiler", "AurelionSecondaryBehaviour..ctor");
			Patch(h, AccessTools.Method(type3, "Fire", (Type[])null, (Type[])null), "FireTranspiler", "AurelionSecondary.Fire");
			Patch(h, AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null), "BehaviourFixedUpdateTranspiler", "AurelionSecondaryBehaviour.FixedUpdate");
			Patch(h, AccessTools.Method(type2, "Detonate", (Type[])null, (Type[])null), "DetonateTranspiler", "AurelionSecondaryController.Detonate");
			Patch(h, AccessTools.Method(type4, "FixedUpdate", (Type[])null, (Type[])null), "CometFixedUpdateTranspiler", "AurelionUtility.FixedUpdate");
			MethodInfo methodInfo = AccessTools.Method(type, "UpdateSpeedMult", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(StarsurgeCometPatch), "UpdateSpeedMultPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogError((object)"AurelionSecondaryBehaviour.UpdateSpeedMult not found - Comet star-growth multiplier unchanged.");
			}
			MethodInfo methodInfo2 = AccessTools.Method(type4, "OnExit", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				h.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(StarsurgeCometPatch), "CometOnExitPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogError((object)"AurelionUtility.OnExit not found - Starsurge growth will stay stuck after a dash.");
			}
			Plugin.Log.LogInfo((object)($"Starsurge/Comet patch active (base {BaseDamage()}x, growth {GrowthRate()}/s, comet growth x{RebalanceConfig.StarsurgeCometGrowthMultiplier.Value}, " + $"blast-radius dmg x{BlastRadiusDamageMult()}, leash {MaxDistance()}, comet speed x{CometSpeed()})."));
		}

		private static void Patch(Harmony h, MethodBase target, string transpiler, string label)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if (target == null)
			{
				Plugin.Log.LogError((object)("Starsurge/Comet: " + label + " not found - skipped."));
			}
			else
			{
				h.Patch(target, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(StarsurgeCometPatch), transpiler, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static FieldInfo FieldOf(string typeName, string field)
		{
			Type type = AccessTools.TypeByName(typeName);
			FieldInfo fieldInfo = ((type == null) ? null : AccessTools.Field(type, field));
			if (fieldInfo == null)
			{
				Plugin.Log.LogError((object)("Starsurge/Comet: field " + typeName + "." + field + " not found."));
			}
			return fieldInfo;
		}

		private static IEnumerable<CodeInstruction> CtorTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = SwapFirstLdcR4(list, 2.5f, "GrowthRate");
			Log(num == 1, "Starsurge base growth rate", num);
			return list;
		}

		private static IEnumerable<CodeInstruction> FireTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = SwapLdcR4AfterCall(list, "get_damage", 4f, "BaseDamage");
			Log(num == 1, "Starsurge base damage coefficient", num);
			return list;
		}

		private static IEnumerable<CodeInstruction> BehaviourFixedUpdateTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = SwapLdcR4AfterCall(list, "Distance", 13f, "MaxDistance");
			int num2 = SwapLdcR4AfterCall(list, "get_starCount", 0.005f, "StardustPerStack");
			int num3 = InjectAfterDivBy10(list, "BlastRadiusDamageMult");
			Log(num == 1 && num3 == 1, "Starsurge FixedUpdate (leash / stardust / blast-radius dmg)", num + num2 * 10 + num3 * 100);
			return list;
		}

		private static IEnumerable<CodeInstruction> DetonateTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = InjectAfterDivBy10(list, "BlastRadiusDamageMult");
			Log(num == 1, "Starsurge Detonate blast-radius damage multiplier", num);
			return list;
		}

		private static IEnumerable<CodeInstruction> CometFixedUpdateTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = list.FindIndex((CodeInstruction c) => c.opcode == OpCodes.Ldfld && c.operand is FieldInfo fieldInfo && fieldInfo.Name == "speedCoefficient");
			int num2 = 0;
			if (num >= 0 && num + 3 < list.Count && list[num + 1].opcode == OpCodes.Mul && list[num + 3].opcode == OpCodes.Mul)
			{
				list.InsertRange(num + 4, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(StarsurgeCometPatch), "CometSpeed", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Mul, (object)null)
				});
				num2 = 1;
			}
			Log(num2 == 1, "Comet of Legend movement speed", num2);
			return list;
		}

		private static void UpdateSpeedMultPostfix(object __instance)
		{
			if (!(FSpeedMultiplier == null))
			{
				float value = RebalanceConfig.StarsurgeCometGrowthMultiplier.Value;
				FSpeedMultiplier.SetValue(__instance, (float)FSpeedMultiplier.GetValue(__instance) * value);
			}
		}

		private static void CometOnExitPostfix(object __instance)
		{
			if (FUtilController == null || FCtrlBehaviour == null || FSpeedMultiplier == null)
			{
				return;
			}
			object value = FUtilController.GetValue(__instance);
			if (value != null)
			{
				object value2 = FCtrlBehaviour.GetValue(value);
				if (value2 != null)
				{
					FSpeedMultiplier.SetValue(value2, GrowthRate());
				}
			}
		}

		private static int SwapFirstLdcR4(List<CodeInstruction> code, float literal, string getter)
		{
			MethodInfo operand = AccessTools.Method(typeof(StarsurgeCometPatch), getter, (Type[])null, (Type[])null);
			int num = 0;
			for (int i = 0; i < code.Count; i++)
			{
				if (code[i].opcode == OpCodes.Ldc_R4 && code[i].operand is float num2 && Mathf.Approximately(num2, literal))
				{
					code[i].opcode = OpCodes.Call;
					code[i].operand = operand;
					num++;
				}
			}
			return num;
		}

		private static int SwapLdcR4AfterCall(List<CodeInstruction> code, string calleeName, float literal, string getter)
		{
			MethodInfo operand = AccessTools.Method(typeof(StarsurgeCometPatch), getter, (Type[])null, (Type[])null);
			int num = code.FindIndex((CodeInstruction c) => (c.opcode == OpCodes.Call || c.opcode == OpCodes.Callvirt) && c.operand is MethodBase methodBase && methodBase.Name == calleeName);
			if (num < 0)
			{
				return 0;
			}
			for (int num2 = num + 1; num2 < code.Count && num2 <= num + 6; num2++)
			{
				if (code[num2].opcode == OpCodes.Ldc_R4 && code[num2].operand is float num3 && Mathf.Approximately(num3, literal))
				{
					code[num2].opcode = OpCodes.Call;
					code[num2].operand = operand;
					return 1;
				}
			}
			return 0;
		}

		private static int InjectAfterDivBy10(List<CodeInstruction> code, string getter)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			for (int i = 0; i < code.Count - 1; i++)
			{
				if (code[i].opcode == OpCodes.Ldc_R4 && code[i].operand is float num && Mathf.Approximately(num, 10f) && code[i + 1].opcode == OpCodes.Div)
				{
					code.InsertRange(i + 2, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(StarsurgeCometPatch), getter, (Type[])null, (Type[])null)),
						new CodeInstruction(OpCodes.Mul, (object)null)
					});
					return 1;
				}
			}
			return 0;
		}

		private static void Log(bool ok, string what, int code)
		{
			if (ok)
			{
				Plugin.Log.LogInfo((object)(what + " patched."));
			}
			else
			{
				Plugin.Log.LogWarning((object)$"{what}: IL anchor not found (code {code}) - Aurelion.dll may have changed; unchanged.");
			}
		}
	}
	[BepInPlugin("com.local.aurelionrebalance", "AurelionRebalance", "1.5.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.local.aurelionrebalance";

		public const string AurelionGuid = "com.Dragonyck.AurelionSol";

		public const string TrueCosmicDragonGuid = "com.phong.aurelionsol.truecosmicdragon";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			RebalanceConfig.Bind(((BaseUnityPlugin)this).Config);
			AurelionRefs.Resolve();
			if (!AurelionRefs.Ready)
			{
				Log.LogError((object)"AurelionRebalance could not bind AurelionSol - no changes applied.");
				return;
			}
			_harmony = new Harmony("com.local.aurelionrebalance");
			SkillTuningPatch.ApplyStatic(_harmony);
			StardustStatsPatch.Apply(_harmony);
			StardustRadiusPatch.Apply(_harmony);
			StarsurgeCometPatch.ApplyStatic(_harmony);
			CometDashPatch.Apply(_harmony);
			SkillTuningPatch.ApplyContent();
			ImpactVfxPatch.Apply();
			DescriptionPatch.Apply();
			Log.LogInfo((object)"AurelionRebalance 1.5.3 applied.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class RebalanceConfig
	{
		internal static ConfigEntry<bool> EnableStatOverride;

		internal static ConfigEntry<float> HealthPerStack;

		internal static ConfigEntry<float> RegenPerStack;

		internal static ConfigEntry<float> DamagePerStack;

		internal static ConfigEntry<float> MoveSpeedPerStack;

		internal static ConfigEntry<float> AttackSpeedPerStack;

		internal static ConfigEntry<float> CritPerStack;

		internal static ConfigEntry<float> AccelerationPerStack;

		internal static ConfigEntry<float> ArmorLogInner;

		internal static ConfigEntry<float> ArmorLogOuter;

		internal static ConfigEntry<float> SprintMultiplier;

		internal static ConfigEntry<float> SpecialBaseRadiusMultiplier;

		internal static ConfigEntry<float> RadiusGrowthPerStack;

		internal static ConfigEntry<float> SingularityRadiusGrowthPerStack;

		internal static ConfigEntry<int> RadiusStackCap;

		internal static ConfigEntry<float> PostCapRadiusMultiplier;

		internal static ConfigEntry<float> SingularityCooldown;

		internal static ConfigEntry<float> FallingStarCooldown;

		internal static ConfigEntry<float> SkiesDescendCooldown;

		internal static ConfigEntry<float> FallingStarDamageCoefficient;

		internal static ConfigEntry<float> SkiesDescendDamageCoefficient;

		internal static ConfigEntry<float> FallingStarProcCoefficient;

		internal static ConfigEntry<float> SkiesDescendProcCoefficient;

		internal static ConfigEntry<float> ShockwaveRadiusMultiplier;

		internal static ConfigEntry<float> ShockwaveMaxGrowthPerStack;

		internal static ConfigEntry<float> ShockwaveDamageCoefficient;

		internal static ConfigEntry<bool> RewriteDescriptions;

		internal static ConfigEntry<float> ImpactFlashWeight;

		internal static ConfigEntry<float> ImpactLightMultiplier;

		internal static ConfigEntry<float> ShockwaveStardustDamageMultiplier;

		internal static ConfigEntry<float> BreathOfLightBurstStardustMultiplier;

		internal static ConfigEntry<float> SolarFlareStardustAttackSpeedMultiplier;

		internal static ConfigEntry<float> StarsurgeBaseDamageCoefficient;

		internal static ConfigEntry<float> StarsurgeGrowthPerSecond;

		internal static ConfigEntry<float> StarsurgeCometGrowthMultiplier;

		internal static ConfigEntry<float> StarsurgeStardustDamagePerStack;

		internal static ConfigEntry<float> StarsurgeBlastRadiusDamageMultiplier;

		internal static ConfigEntry<float> StarsurgeMaxDistance;

		internal static ConfigEntry<float> CometSpeedMultiplier;

		internal static ConfigEntry<float> CometDamageReduction;

		internal static void Bind(ConfigFile cfg)
		{
			EnableStatOverride = cfg.Bind<bool>("1. Stardust Passive", "EnableStatOverride", true, "Master switch. When true this mod replaces True Cosmic Dragon's Stardust RecalculateStats handler with the per-stack values below. When false, TCD's original handler runs untouched.");
			HealthPerStack = cfg.Bind<float>("1. Stardust Passive", "HealthPerStack", 0.005f, "Max health multiplier added per Stardust stack. (TCD 0.2.0: 0.005)");
			RegenPerStack = cfg.Bind<float>("1. Stardust Passive", "RegenPerStack", 0f, "Regen multiplier added per Stardust stack. (TCD 0.2.0: 0.0)");
			DamagePerStack = cfg.Bind<float>("1. Stardust Passive", "DamagePerStack", 0f, "Damage multiplier added per Stardust stack. (TCD 0.2.0: 0.0)");
			MoveSpeedPerStack = cfg.Bind<float>("1. Stardust Passive", "MoveSpeedPerStack", 0f, "Move speed multiplier added per Stardust stack. 0 = removed. (TCD 0.2.0: 0.001)");
			AttackSpeedPerStack = cfg.Bind<float>("1. Stardust Passive", "AttackSpeedPerStack", 0f, "Attack speed multiplier added per Stardust stack. (TCD 0.2.0: 0.0)");
			CritPerStack = cfg.Bind<float>("1. Stardust Passive", "CritPerStack", 0f, "Crit chance added per Stardust stack. 0 = removed. (TCD 0.2.0: 0.01)");
			AccelerationPerStack = cfg.Bind<float>("1. Stardust Passive", "AccelerationPerStack", 0f, "Acceleration bonus per Stardust stack: acceleration = 14 * (1 + value * stacks). 0 = acceleration left at the body base of 14. (TCD 0.2.0: 0.01)");
			ArmorLogInner = cfg.Bind<float>("1. Stardust Passive", "ArmorLogInner", 0f, "Inner coefficient of the logarithmic Stardust armor bonus: Mathf.Log(1 + inner * stacks). (TCD 0.2.0: 0.08)");
			ArmorLogOuter = cfg.Bind<float>("1. Stardust Passive", "ArmorLogOuter", 0f, "Outer coefficient of the logarithmic Stardust armor bonus. (TCD 0.2.0: 0.0)");
			SprintMultiplier = cfg.Bind<float>("1. Stardust Passive", "SprintMultiplier", 1f, "Sprint speed multiplier forced while any Stardust stack is held. (TCD 0.2.0 and body base: 1.)");
			SpecialBaseRadiusMultiplier = cfg.Bind<float>("2. Skill Effect Radius", "SpecialBaseRadiusMultiplier", 1.3f, "Multiplier on the base impact radius of Falling Star and The Skies Descend (stock base 12). 1.3 = +30%. Does NOT affect Singularity or the Skies Descend shockwave.");
			RadiusGrowthPerStack = cfg.Bind<float>("2. Skill Effect Radius", "RadiusGrowthPerStack", 0.025f, "Effect radius added per Stardust stack for Falling Star, the Skies Descend impact indicator and the shockwave's inner search radius. (Default: 0.025)");
			SingularityRadiusGrowthPerStack = cfg.Bind<float>("2. Skill Effect Radius", "SingularityRadiusGrowthPerStack", 0.05f, "Singularity black-hole radius (pull + damage + visual) added per Stardust stack, separate from RadiusGrowthPerStack. Still hard-capped at RadiusStackCap. Stock game: 0.05.");
			RadiusStackCap = cfg.Bind<int>("2. Skill Effect Radius", "RadiusStackCap", 300, "Stardust stacks up to this count grow skill effect radii at the full RadiusGrowthPerStack rate.");
			PostCapRadiusMultiplier = cfg.Bind<float>("2. Skill Effect Radius", "PostCapRadiusMultiplier", 0.5f, "Falling Star and The Skies Descend: Stardust stacks ABOVE RadiusStackCap still grow the radius, but each contributes this fraction of RadiusGrowthPerStack. Singularity ignores this and is hard-capped (stacks above the cap add no radius).");
			SingularityCooldown = cfg.Bind<float>("3. Skill Cooldowns", "SingularityCooldown", 12f, "Singularity (alt secondary) base recharge, seconds. Default: 10.");
			FallingStarCooldown = cfg.Bind<float>("3. Skill Cooldowns", "FallingStarCooldown", 24f, "Falling Star (alt special) base recharge, seconds. Default: 24. Stock game: 12.");
			SkiesDescendCooldown = cfg.Bind<float>("3. Skill Cooldowns", "SkiesDescendCooldown", 24f, "The Skies Descend (Stardust special override at 900 stacks) base recharge, seconds. Default: 24. Stock game: 12.");
			FallingStarDamageCoefficient = cfg.Bind<float>("4. Falling Star / The Skies Descend impact", "FallingStarDamageCoefficient", 10f, "Falling Star impact damage as a fraction of base damage. 10 = 1000%. Default: 10 (1000%). Stock game: 5 (500%).");
			SkiesDescendDamageCoefficient = cfg.Bind<float>("4. Falling Star / The Skies Descend impact", "SkiesDescendDamageCoefficient", 30f, "The Skies Descend star-impact damage as a fraction of base damage. 30 = 3000%. Default: 30.");
			FallingStarProcCoefficient = cfg.Bind<float>("4. Falling Star / The Skies Descend impact", "FallingStarProcCoefficient", 1.5f, "Falling Star impact proc coefficient. Default: inherited from Captain Airstrike (~1.0).");
			SkiesDescendProcCoefficient = cfg.Bind<float>("4. Falling Star / The Skies Descend impact", "SkiesDescendProcCoefficient", 2f, "The Skies Descend star-impact proc coefficient. Default: inherited from Captain Airstrike (~1.0).");
			ShockwaveRadiusMultiplier = cfg.Bind<float>("5. The Skies Descend Shockwave", "ShockwaveRadiusMultiplier", 2f, "Overall size multiplier for the expanding ground shockwave (the second, larger AoE). 2.0 = +100%.");
			ShockwaveMaxGrowthPerStack = cfg.Bind<float>("5. The Skies Descend Shockwave", "ShockwaveMaxGrowthPerStack", 0.06f, "Shockwave outer/maximum radius added per Stardust stack (before the game's internal x2.5). Default: 0.06.");
			ShockwaveDamageCoefficient = cfg.Bind<float>("5. The Skies Descend Shockwave", "ShockwaveDamageCoefficient", 8f, "Shockwave per-hit damage as a fraction of base damage. 18 = 1800%. Default: 18. The shockwave proc coefficient stays 0.");
			RewriteDescriptions = cfg.Bind<bool>("6. Descriptions", "RewriteDescriptions", true, "Overwrite the in-game skill descriptions for Singularity / Falling Star / The Skies Descend / the Stardust passive so their numbers match this config and the True Cosmic Dragon add-on.");
			ImpactFlashWeight = cfg.Bind<float>("7. Impact Visuals", "ImpactFlashWeight", 0.3f, "Weight (0..1) of the full-screen post-processing flash on the Falling Star / The Skies Descend star impact. 0 removes the white screen wash entirely; 1 is the stock intensity. Both skills share this effect.");
			ImpactLightMultiplier = cfg.Bind<float>("7. Impact Visuals", "ImpactLightMultiplier", 0.3f, "Multiplier on the impact flash's point-light intensity. 1 is stock.");
			ShockwaveStardustDamageMultiplier = cfg.Bind<float>("8. Other Stardust Scaling", "ShockwaveStardustDamageMultiplier", 0.025f, "Multiplier on the Skies Descend shockwave's flat per-Stardust-stack damage bonus (stock: 0.05 damage per stack). 0.025 = 1/40th. This is separate from ShockwaveDamageCoefficient, which is the base multiple of your damage stat.");
			BreathOfLightBurstStardustMultiplier = cfg.Bind<float>("8. Other Stardust Scaling", "BreathOfLightBurstStardustMultiplier", 0.8f, "Multiplier on the Stardust scaling of Breath of Light's 150% burst (stock: the burst is damage * (attackSpeed * 1.5 + starCount * 0.01); this scales the 0.01 term). 0.8 = 80% of stock. 1 = stock. 0 = burst no longer scales with Stardust.");
			SolarFlareStardustAttackSpeedMultiplier = cfg.Bind<float>("8. Other Stardust Scaling", "SolarFlareStardustAttackSpeedMultiplier", 0.5f, "Multiplier on Solar Flare's per-Stardust-stack fire-rate bonus (stock: starCount * 0.005 added to attack speed for that skill only). 0.5 = half. 1 = stock.");
			StarsurgeBaseDamageCoefficient = cfg.Bind<float>("9. Starsurge & Comet of Legend", "StarsurgeBaseDamageCoefficient", 5f, "Starsurge star base damage as a fraction of your damage stat, before the blast-radius multiplier. Default: 5 (500%). Stock game: 4 (400%).");
			StarsurgeGrowthPerSecond = cfg.Bind<float>("9. Starsurge & Comet of Legend", "StarsurgeGrowthPerSecond", 3.5f, "How fast the Starsurge star's blast radius grows per second while NOT being carried by Comet of Legend. Default: 3.5. Stock game: 2.5.");
			StarsurgeCometGrowthMultiplier = cfg.Bind<float>("9. Starsurge & Comet of Legend", "StarsurgeCometGrowthMultiplier", 0.5f, "Multiplier applied to the star's growth rate while Comet of Legend is carrying it (stock: the star grows at Aurelion's full move speed). 0.5 = half. 1 = stock.");
			StarsurgeStardustDamagePerStack = cfg.Bind<float>("9. Starsurge & Comet of Legend", "StarsurgeStardustDamagePerStack", 0.005f, "Flat bonus added to the star's effective blast radius per Stardust stack in the detonation-damage formula. Stock game: 0.005.");
			StarsurgeBlastRadiusDamageMultiplier = cfg.Bind<float>("9. Starsurge & Comet of Legend", "StarsurgeBlastRadiusDamageMultiplier", 0.65f, "Multiplier on the whole (blastRadius + stardust) / 10 damage multiplier at both Starsurge detonation sites. Default: 0.65. 0.5 = half - a star that has grown large hits half as hard. 1 = stock.");
			StarsurgeMaxDistance = cfg.Bind<float>("9. Starsurge & Comet of Legend", "StarsurgeMaxDistance", 18f, "How far the Starsurge star may drift from Aurelion before it auto-detonates. Default: 18. Stock game: 13.");
			CometSpeedMultiplier = cfg.Bind<float>("9. Starsurge & Comet of Legend", "CometSpeedMultiplier", 1.6f, "Comet of Legend movement-speed multiplier, applied on top of True Cosmic Dragon's [Flight] CometSpeedMultiplier. Default: 1.6 (60% faster).");
			CometDamageReduction = cfg.Bind<float>("9. Starsurge & Comet of Legend", "CometDamageReduction", 0.8f, "Fraction of incoming damage negated while dashing with Comet of Legend. Default: 0.8 (take 80% less). 0 = no reduction.");
		}
	}
}