Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AurelionRebalance v1.5.3
AurelionRebalance.dll
Decompiled 7 hours agousing 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."); } } }