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 True Cosmic Dragon v0.2.0
True_Cosmic_Dragon/TrueCosmicDragon.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using R2API; using R2API.Utils; using RoR2; using RoR2.Skills; using UnityEngine; using UnityEngine.Networking; [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("TrueCosmicDragon")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0")] [assembly: AssemblyProduct("TrueCosmicDragon")] [assembly: AssemblyTitle("TrueCosmicDragon")] [assembly: AssemblyVersion("0.2.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace CenterOfTheUniverseUpgrade { public sealed class DynamicStarsController : MonoBehaviour { private const int MinStarCount = 3; private const int MaxStarCount = 6; private const float FireFrequency = 60f; private const float BaseResetInterval = 2.7f; private const float RotationDegreesPerSecond = -120f; private const float DamageCoefficient = 5f; private const float CloseProcCoefficient = 0.8f; private const float ExpandedProcCoefficient = 0.5f; private const float MinimumRadiusLerpFactor = 0.08f; private static readonly Vector3 InnerRadiusScale = Vector3.one * 0.75f; private static readonly Vector3 OuterRadiusScale = Vector3.one * 1.65f; private static readonly Vector3 HitboxScale = new Vector3(0.85f, 2f, 0.85f); private static readonly FieldInfo? OutOfCombatStopwatchField = typeof(CharacterBody).GetField("outOfCombatStopwatch", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private readonly List<StarRuntime> stars = new List<StarRuntime>(); private readonly List<HurtBox> victimsStruck = new List<HurtBox>(); private CharacterBody body; private Component attachment; private FieldInfo toggleField; private FieldInfo? controllerToggleField; private MonoBehaviour originalController; private ChildLocator? childLocator; private GameObject? visualTemplate; private Transform? hitboxAnchorTemplate; private int currentStarCount; private float resetTimer; private float fireTimer; private float currentRadiusFactor = 1f; private bool hasLastExpandedState; private bool lastExpandedState; private float lastRadiusLogTime; private float radiusLogUntilTime; private bool initialized; public bool Initialize(CharacterBody ownerBody, Component starsAttachment, FieldInfo attachmentToggleField, MonoBehaviour disabledOriginalController) { body = ownerBody; attachment = starsAttachment; toggleField = attachmentToggleField; originalController = disabledOriginalController; controllerToggleField = ((object)originalController).GetType().GetField("toggle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); childLocator = ((Component)this).GetComponent<ChildLocator>(); if (!CaptureTemplates()) { CenterOfTheUniverseUpgradePlugin.Log.LogError((object)"Could not capture Aurelion star visual/hitbox templates. Dynamic controller disabled."); ((Behaviour)this).enabled = false; return false; } HideOriginalStarChildren(); currentRadiusFactor = GetTargetRadiusFactor(IsExpanded()); SetStarCount(GetWantedStarCount()); initialized = true; return true; } private void Update() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (initialized && Object.op_Implicit((Object)(object)body)) { bool expanded = IsExpanded(); LogExpandedStateChange(expanded); float targetRadiusFactor = GetTargetRadiusFactor(expanded); float radiusLerpFactor = GetRadiusLerpFactor(); currentRadiusFactor = Mathf.Lerp(currentRadiusFactor, targetRadiusFactor, radiusLerpFactor); ((Component)this).transform.localScale = Vector3.one; ApplyRadiusToActiveStars(); LogRadiusProgress(expanded, targetRadiusFactor, radiusLerpFactor); } } private void FixedUpdate() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!initialized || !Object.op_Implicit((Object)(object)body)) { return; } ((Component)this).transform.Rotate(new Vector3(0f, -120f * body.attackSpeed, 0f) * Time.deltaTime); int wantedStarCount = GetWantedStarCount(); if (wantedStarCount != currentStarCount) { SetStarCount(wantedStarCount); } if (NetworkServer.active && Util.HasEffectiveAuthority(body.networkIdentity)) { resetTimer -= Time.fixedDeltaTime; if (resetTimer <= 0f) { resetTimer = GetResetInterval(); victimsStruck.Clear(); RebuildAttacks(); } fireTimer -= Time.fixedDeltaTime; if (!(fireTimer > 0f)) { fireTimer = 1f / 60f; FireStarAttacks(); } } } private bool CaptureTemplates() { Transform val = ResolveTransformFromControllerField("Star1") ?? ResolveTransformFromControllerField("star1") ?? ResolveChild("Star1"); Transform val2 = ResolveTransformFromControllerField("Sphere1") ?? ResolveTransformFromControllerField("sphere1") ?? ResolveChild("Sphere1"); if (val == null) { val = val2; } if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2)) { CenterOfTheUniverseUpgradePlugin.Log.LogError((object)("Template lookup failed. Star1=" + (Object.op_Implicit((Object)(object)val) ? GetTransformPath(val) : "missing") + ", Sphere1=" + (Object.op_Implicit((Object)(object)val2) ? GetTransformPath(val2) : "missing") + ".")); return false; } visualTemplate = ((Component)val).gameObject; hitboxAnchorTemplate = val2; CenterOfTheUniverseUpgradePlugin.Log.LogInfo((object)("Captured Aurelion star templates: Star1=" + GetTransformPath(val) + ", Sphere1=" + GetTransformPath(val2) + ".")); return true; } private static string GetTransformPath(Transform transformValue) { string text = ((Object)transformValue).name; Transform parent = transformValue.parent; while (Object.op_Implicit((Object)(object)parent)) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private Transform? ResolveTransformFromControllerField(string fieldName) { object obj = ((object)originalController).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(originalController); Transform val = (Transform)((obj is Transform) ? obj : null); if (val == null) { GameObject val2 = (GameObject)((obj is GameObject) ? obj : null); if (val2 == null) { Component val3 = (Component)((obj is Component) ? obj : null); if (val3 != null) { return val3.transform; } return null; } return val2.transform; } return val; } private Transform? ResolveChild(string childName) { if (!Object.op_Implicit((Object)(object)childLocator)) { return ((Component)this).transform.Find(childName); } return childLocator.FindChild(childName); } private void HideOriginalStarChildren() { SetOriginalChildActive("Star1", active: false); SetOriginalChildActive("Star2", active: false); SetOriginalChildActive("Star3", active: false); SetOriginalChildActive("Sphere1", active: false); SetOriginalChildActive("Sphere2", active: false); SetOriginalChildActive("Sphere3", active: false); } private void SetOriginalChildActive(string childName, bool active) { Transform val = ResolveChild(childName); if (Object.op_Implicit((Object)(object)val)) { ((Component)val).gameObject.SetActive(active); } } private int GetWantedStarCount() { int num = Mathf.FloorToInt(body.level); return Mathf.Clamp(3 + num / 7, 3, 6); } private float GetResetInterval() { return 2.7f / Mathf.Max(body.attackSpeed, 0.01f); } private float GetRadiusLerpFactor() { float num = 0.01f * (1f + body.level * (Mathf.Max(body.attackSpeed, 0.01f) / 10f)); return Mathf.Clamp01(Mathf.Max(0.08f, num)); } private static float GetTargetRadiusFactor(bool expanded) { if (!expanded) { return InnerRadiusScale.x; } return OuterRadiusScale.x; } private bool IsExpanded() { object obj = toggleField.GetValue(attachment) ?? controllerToggleField?.GetValue(originalController); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private void LogExpandedStateChange(bool expanded) { if (!hasLastExpandedState || expanded != lastExpandedState) { hasLastExpandedState = true; lastExpandedState = expanded; CenterOfTheUniverseUpgradePlugin.Log.LogInfo((object)string.Format("Aurelion star radius mode changed to {0} at {1} stars.", expanded ? "expanded" : "close", currentStarCount)); lastRadiusLogTime = 0f; radiusLogUntilTime = Time.unscaledTime + 3f; } } private void LogRadiusProgress(bool expanded, float targetRadiusFactor, float lerpFactor) { if (!(Time.unscaledTime > radiusLogUntilTime) && !(Time.unscaledTime - lastRadiusLogTime < 1f)) { lastRadiusLogTime = Time.unscaledTime; CenterOfTheUniverseUpgradePlugin.Log.LogInfo((object)string.Format("Aurelion star radius applying {0} at {1} stars: currentRadius={2:0.00}, targetRadius={3:0.00}, lerp={4:0.000}.", expanded ? "expanded" : "close", currentStarCount, currentRadiusFactor, targetRadiusFactor, lerpFactor)); } } private void SetStarCount(int wantedStarCount) { wantedStarCount = Mathf.Clamp(wantedStarCount, 3, 6); while (stars.Count < wantedStarCount) { stars.Add(CreateStar(stars.Count)); } currentStarCount = wantedStarCount; for (int i = 0; i < stars.Count; i++) { bool flag = i < currentStarCount; stars[i].Root.SetActive(flag); if (flag) { PositionStar(stars[i], i, currentStarCount, currentRadiusFactor); } } RebuildAttacks(); CenterOfTheUniverseUpgradePlugin.Log.LogInfo((object)$"Aurelion star count set to {currentStarCount} at level {body.level:0}."); } private StarRuntime CreateStar(int index) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"DynamicStar{index + 1}"); val.transform.SetParent(((Component)this).transform, false); GameObject val2 = Object.Instantiate<GameObject>(visualTemplate, val.transform, false); ((Object)val2).name = $"DynamicStarVisual{index + 1}"; StripHitboxComponents(val2); val2.SetActive(true); GameObject val3 = new GameObject($"DynamicSphere{index + 1}"); val3.transform.SetParent(val.transform, false); HitBoxGroup val4 = val3.AddComponent<HitBoxGroup>(); GameObject val5 = new GameObject("SphereHitbox"); val5.transform.SetParent(val3.transform, false); val5.transform.localPosition = Vector3.zero; val5.transform.localRotation = Quaternion.identity; val5.transform.localScale = HitboxScale; val5.layer = LayerIndex.projectile.intVal; HitBox val6 = val5.AddComponent<HitBox>(); val4.hitBoxes = (HitBox[])(object)new HitBox[1] { val6 }; val4.groupName = "Sphere"; return new StarRuntime { Root = val, Visual = val2, HitBoxRoot = val3, HitBoxGroup = val4 }; } private static void StripHitboxComponents(GameObject visual) { HitBoxGroup[] componentsInChildren = visual.GetComponentsInChildren<HitBoxGroup>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } HitBox[] componentsInChildren2 = visual.GetComponentsInChildren<HitBox>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.Destroy((Object)(object)componentsInChildren2[i]); } } private void ApplyRadiusToActiveStars() { for (int i = 0; i < currentStarCount; i++) { PositionStar(stars[i], i, currentStarCount, currentRadiusFactor); } } private void PositionStar(StarRuntime star, int index, int totalCount, float radiusFactor) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) float num = 360f * (float)index / (float)totalCount; Quaternion val = Quaternion.Euler(0f, num, 0f); Transform transform = star.Visual.transform; Transform transform2 = visualTemplate.transform; transform.localPosition = val * (transform2.localPosition * radiusFactor); transform.localRotation = val * transform2.localRotation; transform.localScale = transform2.localScale * radiusFactor; Transform transform3 = star.HitBoxRoot.transform; Transform val2 = hitboxAnchorTemplate; transform3.localPosition = val * (val2.localPosition * radiusFactor); transform3.localRotation = val * val2.localRotation; transform3.localScale = val2.localScale * radiusFactor; } private void RebuildAttacks() { for (int i = 0; i < currentStarCount; i++) { stars[i].Attack = CreateAttack(stars[i].HitBoxGroup); } } private OverlapAttack CreateAttack(HitBoxGroup hitBoxGroup) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown return new OverlapAttack { procChainMask = default(ProcChainMask), procCoefficient = (IsExpanded() ? 0.5f : 0.8f), attacker = ((Component)body).gameObject, inflictor = ((Component)body).gameObject, teamIndex = body.teamComponent.teamIndex, damage = body.damage * 5f, forceVector = new Vector3(40f, 40f, 40f) * body.attackSpeed, hitEffectPrefab = GetOriginalHitEffectPrefab(), isCrit = body.RollCrit(), damageColorIndex = (DamageColorIndex)0, damageType = DamageTypeCombo.op_Implicit((DamageType)0), maximumOverlapTargets = 100, hitBoxGroup = hitBoxGroup }; } private GameObject? GetOriginalHitEffectPrefab() { object? obj = (((object)originalController).GetType().Assembly.GetType("Aurelion.Prefabs", throwOnError: false)?.GetField("aurelionStarsHitEffect", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(null); return (GameObject?)((obj is GameObject) ? obj : null); } private void FireStarAttacks() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < currentStarCount; i++) { StarRuntime starRuntime = stars[i]; if (starRuntime.Attack == null) { starRuntime.Attack = CreateAttack(starRuntime.HitBoxGroup); } starRuntime.Attack.damage = body.damage * 5f; starRuntime.Attack.forceVector = new Vector3(40f, 40f, 40f) * body.attackSpeed; starRuntime.Attack.procCoefficient = (IsExpanded() ? 0.5f : 0.8f); if (starRuntime.Attack.Fire(victimsStruck)) { OutOfCombatStopwatchField?.SetValue(body, 0f); } } } } internal sealed class FlightTuning : IDisposable { private const BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private const BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static FlightTuning? current; private readonly Harmony harmony; private readonly Type cometType; private readonly Type dragonflightType; private readonly FieldInfo cometSpeedField; private readonly FieldInfo cometDurationField; private readonly FieldInfo cometBehaviourField; private readonly FieldInfo dragonflightDurationField; private readonly FieldInfo dragonflightBehaviourField; private readonly ConfigEntry<float> cometSpeedMultiplier; private readonly ConfigEntry<float> cometStardustDurationPerStack; private readonly ConfigEntry<float> dragonflightSpeedMultiplier; private readonly ConfigEntry<float> dragonflightStardustDurationPerStack; private bool applied; public FlightTuning(BaseUnityPlugin plugin, Assembly aurelionAssembly) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown current = this; harmony = new Harmony("com.phong.aurelionsol.truecosmicdragon.flight"); cometSpeedMultiplier = plugin.Config.Bind<float>("Flight", "CometSpeedMultiplier", 0.5f, "Speed multiplier used by Comet of Legend. The skill also uses Aurelion's movement speed stat."); cometStardustDurationPerStack = plugin.Config.Bind<float>("Flight", "CometStardustDurationPerStack", 0.005f, "Additional Comet of Legend duration per Stardust stack."); dragonflightSpeedMultiplier = plugin.Config.Bind<float>("Flight", "DragonflightSpeedMultiplier", 0.5f, "Speed multiplier used by Dragonflight while its normal movement boost is active."); dragonflightStardustDurationPerStack = plugin.Config.Bind<float>("Flight", "DragonflightStardustDurationPerStack", 0.005f, "Additional Dragonflight duration per Stardust stack."); cometType = RequireType(aurelionAssembly, "Aurelion.AurelionUtility"); dragonflightType = RequireType(aurelionAssembly, "Aurelion.AurelionNewUtilityFlight"); cometSpeedField = RequireField(cometType, "speedCoefficient"); cometDurationField = RequireField(cometType, "duration"); cometBehaviourField = RequireField(cometType, "behaviour"); dragonflightDurationField = RequireField(dragonflightType, "duration"); dragonflightBehaviourField = RequireField(dragonflightType, "behaviour"); } public bool Apply() { try { harmony.Patch((MethodBase)RequireMethod(cometType, "FixedUpdate"), HarmonyMethod("CometFixedUpdatePrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)RequireMethod(cometType, "OnEnter"), (HarmonyMethod)null, HarmonyMethod("CometOnEnterPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)RequirePropertyGetter(dragonflightType, "speedCoefficient"), (HarmonyMethod)null, HarmonyMethod("DragonflightSpeedPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)RequireMethod(dragonflightType, "OnEnter"), (HarmonyMethod)null, HarmonyMethod("DragonflightOnEnterPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); applied = true; CenterOfTheUniverseUpgradePlugin.Log.LogInfo((object)($"Flight config loaded: CometSpeed={NonNegative(cometSpeedMultiplier.Value):0.###}, " + $"CometStardustDuration={NonNegative(cometStardustDurationPerStack.Value):0.###}, " + $"DragonflightSpeed={NonNegative(dragonflightSpeedMultiplier.Value):0.###}, " + $"DragonflightStardustDuration={NonNegative(dragonflightStardustDurationPerStack.Value):0.###}.")); return true; } catch (Exception arg) { CenterOfTheUniverseUpgradePlugin.Log.LogError((object)$"Flight tuning patch failed: {arg}"); Dispose(); return false; } } public void Dispose() { if (applied) { harmony.UnpatchSelf(); applied = false; } if (current == this) { current = null; } } private static void CometFixedUpdatePrefix(object __instance) { if (current != null) { current.cometSpeedField.SetValue(__instance, NonNegative(current.cometSpeedMultiplier.Value)); } } private static void CometOnEnterPostfix(object __instance) { current?.ApplyDuration(__instance, current.cometDurationField, current.cometBehaviourField, current.cometStardustDurationPerStack.Value); } private static void DragonflightSpeedPostfix(ref float __result) { if (current != null && __result > 0f) { __result = NonNegative(current.dragonflightSpeedMultiplier.Value); } } private static void DragonflightOnEnterPostfix(object __instance) { current?.ApplyDuration(__instance, current.dragonflightDurationField, current.dragonflightBehaviourField, current.dragonflightStardustDurationPerStack.Value); } private void ApplyDuration(object instance, FieldInfo durationField, FieldInfo behaviourField, float perStack) { int starCount = GetStarCount(behaviourField.GetValue(instance)); durationField.SetValue(instance, 2f + NonNegative(perStack) * (float)starCount); } private static int GetStarCount(object? behaviour) { if (behaviour == null) { return 0; } if (!(behaviour.GetType().GetProperty("starCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(behaviour) is int val)) { return 0; } return Math.Max(0, val); } private static float NonNegative(float value) { return Math.Max(0f, value); } private static Type RequireType(Assembly assembly, string name) { return assembly.GetType(name, throwOnError: true); } private static FieldInfo RequireField(Type type, string name) { return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingFieldException(type.FullName, name); } private static MethodInfo RequireMethod(Type type, string name) { return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMethodException(type.FullName, name); } private static MethodInfo RequirePropertyGetter(Type type, string name) { return type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetGetMethod(nonPublic: true) ?? throw new MissingMethodException(type.FullName, "get_" + name); } private static HarmonyMethod HarmonyMethod(string name) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown return new HarmonyMethod(typeof(FlightTuning).GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMethodException(typeof(FlightTuning).FullName, name)); } } [BepInPlugin("com.phong.aurelionsol.truecosmicdragon", "True Cosmic Dragon", "0.1.9")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class CenterOfTheUniverseUpgradePlugin : BaseUnityPlugin { public const string PluginGuid = "com.phong.aurelionsol.truecosmicdragon"; public const string PluginName = "True Cosmic Dragon"; public const string PluginVersion = "0.1.9"; private const string AurelionPluginGuid = "com.Dragonyck.AurelionSol"; private const string SupportedAurelionHash = "AFF000FE56C6451396A5B472C2AED0F8C09ADA09E17AC5DA49C2DC896BEF08EF"; private const string AurelionBodyName = "AurelionSolBody"; private static readonly FieldInfo? AccelerationBackingField = typeof(CharacterBody).GetField("<acceleration>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); internal static ManualLogSource Log = null; private Assembly? aurelionAssembly; private Type? starsAttachmentType; private FieldInfo? controllerField; private FieldInfo? toggleField; private PropertyInfo? hasStardustProperty; private FieldInfo? stardustBuffField; private BuffDef? stardustBuff; private FlightTuning? flightTuning; private readonly HashSet<int> installingOrInstalledBodyIds = new HashSet<int>(); private readonly HashSet<int> failedBodyIds = new HashSet<int>(); private void Awake() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; if (!TryBindAurelionTypes()) { ((BaseUnityPlugin)this).Logger.LogError((object)"Unsupported or incomplete AurelionSol install. Center of the Universe upgrade will not run."); ((Behaviour)this).enabled = false; return; } if (!SecondarySkillTuning.Apply(aurelionAssembly)) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not enable Backup Magazine charges for Singularity. Center of the Universe upgrade will not run."); ((Behaviour)this).enabled = false; return; } flightTuning = new FlightTuning((BaseUnityPlugin)(object)this, aurelionAssembly); if (!flightTuning.Apply()) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not install configurable Aurelion flight tuning. Center of the Universe upgrade will not run."); flightTuning.Dispose(); flightTuning = null; ((Behaviour)this).enabled = false; } else { CharacterBody.onBodyAwakeGlobal += OnBodyAwakeGlobal; CharacterBody.onBodyStartGlobal += OnBodyStartGlobal; CharacterBody.onBodyDestroyGlobal += OnBodyDestroyGlobal; RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStatCoefficients); ((MonoBehaviour)this).StartCoroutine(ScanExistingBodies()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"True Cosmic Dragon loaded. Version=0.1.9."); } } private void OnDestroy() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown flightTuning?.Dispose(); flightTuning = null; CharacterBody.onBodyAwakeGlobal -= OnBodyAwakeGlobal; CharacterBody.onBodyStartGlobal -= OnBodyStartGlobal; CharacterBody.onBodyDestroyGlobal -= OnBodyDestroyGlobal; RecalculateStatsAPI.GetStatCoefficients -= new StatHookEventHandler(OnGetStatCoefficients); } private bool TryBindAurelionTypes() { aurelionAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => assembly.GetName().Name == "Aurelion"); if (aurelionAssembly == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Aurelion assembly is not loaded."); return false; } if (!IsSupportedAurelionAssembly(aurelionAssembly)) { return false; } starsAttachmentType = aurelionAssembly.GetType("Aurelion.StarsAttachment", throwOnError: false); Type type = aurelionAssembly.GetType("Aurelion.StarsController", throwOnError: false); if (starsAttachmentType == null || type == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not find Aurelion.StarsAttachment or Aurelion.StarsController."); return false; } controllerField = starsAttachmentType.GetField("controller", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); toggleField = starsAttachmentType.GetField("toggle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); hasStardustProperty = starsAttachmentType.GetProperty("hasStardust", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (controllerField == null || toggleField == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not bind StarsAttachment controller/toggle fields."); return false; } stardustBuffField = aurelionAssembly.GetType("Aurelion.Prefabs", throwOnError: false)?.GetField("stardust", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (stardustBuffField == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not bind Aurelion.Prefabs.stardust."); return false; } return true; } private void OnGetStatCoefficients(CharacterBody sender, StatHookEventArgs args) { if (!Object.op_Implicit((Object)(object)sender) || !TryGetStardustBuff(out BuffDef buffDef)) { return; } int buffCount = sender.GetBuffCount(buffDef); if (buffCount > 0) { float num = buffCount; args.healthMultAdd += 0.01f * num; args.regenMultAdd += 0.005f * num; args.damageMultAdd += 0.008f * num; args.moveSpeedMultAdd += 0.001f * num; args.attackSpeedMultAdd += 0.002f * num; args.critAdd += 0.01f * num; float num2 = Mathf.Log(1f + 0.08f * num) * 0.045511205f; if (num2 < 1f) { args.armorAdd += 100f * num2 / (1f - num2); } float num3 = (sender.baseAcceleration = 14f * (1f + 0.01f * num)); AccelerationBackingField?.SetValue(sender, num3); sender.sprintingSpeedMultiplier = 1.45f; } } private bool TryGetStardustBuff(out BuffDef buffDef) { if (Object.op_Implicit((Object)(object)stardustBuff)) { buffDef = stardustBuff; return true; } ref BuffDef? reference = ref stardustBuff; object? obj = stardustBuffField?.GetValue(null); reference = (BuffDef?)((obj is BuffDef) ? obj : null); buffDef = stardustBuff; return Object.op_Implicit((Object)(object)stardustBuff); } private bool IsSupportedAurelionAssembly(Assembly assembly) { string location = assembly.Location; if (string.IsNullOrWhiteSpace(location) || !File.Exists(location)) { ((BaseUnityPlugin)this).Logger.LogError((object)"Aurelion assembly location is unavailable."); return false; } string text; using (SHA256 sHA = SHA256.Create()) { using FileStream inputStream = File.OpenRead(location); text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", string.Empty); } if (!string.Equals(text, "AFF000FE56C6451396A5B472C2AED0F8C09ADA09E17AC5DA49C2DC896BEF08EF", StringComparison.OrdinalIgnoreCase)) { ((BaseUnityPlugin)this).Logger.LogError((object)("Unsupported Aurelion.dll hash: " + text + ". Expected AFF000FE56C6451396A5B472C2AED0F8C09ADA09E17AC5DA49C2DC896BEF08EF.")); return false; } return true; } private void OnBodyAwakeGlobal(CharacterBody body) { TryBeginInstall(body, "awake"); } private void OnBodyStartGlobal(CharacterBody body) { TryBeginInstall(body, "start"); } private void OnBodyDestroyGlobal(CharacterBody body) { if (Object.op_Implicit((Object)(object)body)) { int instanceID = ((Object)body).GetInstanceID(); installingOrInstalledBodyIds.Remove(instanceID); failedBodyIds.Remove(instanceID); } } private IEnumerator ScanExistingBodies() { WaitForSeconds wait = new WaitForSeconds(1f); while (((Behaviour)this).enabled) { foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { TryBeginInstall(readOnlyInstances, "scan"); } yield return wait; } } private void TryBeginInstall(CharacterBody body, string source) { if (Object.op_Implicit((Object)(object)body) && IsAurelionBody(body)) { int instanceID = ((Object)body).GetInstanceID(); if (!installingOrInstalledBodyIds.Contains(instanceID) && !failedBodyIds.Contains(instanceID)) { installingOrInstalledBodyIds.Add(instanceID); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Detected Aurelion body from {source}: name={((Object)body).name}, level={body.level:0.##}, token={body.baseNameToken}."); ((MonoBehaviour)this).StartCoroutine(InstallWhenReady(body)); } } } private static bool IsAurelionBody(CharacterBody body) { if (!((Object)body).name.StartsWith("AurelionSolBody", StringComparison.Ordinal) && !string.Equals(body.baseNameToken, "AURELION_NAME", StringComparison.Ordinal)) { return ((Object)body).name.IndexOf("Aurelion", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private IEnumerator InstallWhenReady(CharacterBody body) { for (int attempt = 0; attempt < 600; attempt++) { if (!Object.op_Implicit((Object)(object)body)) { yield break; } Component val = ((starsAttachmentType == null) ? null : ((Component)body).GetComponent(starsAttachmentType)); if ((Object)(object)val != (Object)null && IsStardustPassive(val)) { installingOrInstalledBodyIds.Remove(((Object)body).GetInstanceID()); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Skipping Center star controller for " + body.GetDisplayName() + " because the Stardust passive is selected.")); yield break; } object? obj = (((Object)(object)val == (Object)null) ? null : controllerField?.GetValue(val)); MonoBehaviour val2 = (MonoBehaviour)((obj is MonoBehaviour) ? obj : null); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { GameObject gameObject = ((Component)val2).gameObject; if (!Object.op_Implicit((Object)(object)gameObject.GetComponent<DynamicStarsController>())) { DynamicStarsController dynamicStarsController = gameObject.AddComponent<DynamicStarsController>(); if (dynamicStarsController.Initialize(body, val, toggleField, val2)) { ((Behaviour)val2).enabled = false; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Installed dynamic star controller for " + body.GetDisplayName() + ".")); yield break; } Object.Destroy((Object)(object)dynamicStarsController); failedBodyIds.Add(((Object)body).GetInstanceID()); installingOrInstalledBodyIds.Remove(((Object)body).GetInstanceID()); ((BaseUnityPlugin)this).Logger.LogError((object)("Dynamic star controller install failed for " + body.GetDisplayName() + ". Leaving original Aurelion controller enabled.")); } yield break; } if (attempt == 120 || attempt == 300) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Waiting for Aurelion stars: attachment=" + (((Object)(object)val == (Object)null) ? "missing" : "found") + ", controller=" + (((Object)(object)val2 == (Object)null) ? "missing" : "found") + ".")); } yield return null; } failedBodyIds.Add(((Object)body).GetInstanceID()); installingOrInstalledBodyIds.Remove(((Object)body).GetInstanceID()); ((BaseUnityPlugin)this).Logger.LogWarning((object)("Timed out waiting for Aurelion stars on " + ((Object)body).name + ".")); } private bool IsStardustPassive(Component attachment) { object obj = hasStardustProperty?.GetValue(attachment); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } internal static class SecondarySkillTuning { private const string AurelionTypeName = "Aurelion.Aurelion"; private const string SingularitySkillName = "AURELION_M2NEW"; private const BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; public static bool Apply(Assembly aurelionAssembly) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) try { Type type = aurelionAssembly.GetType("Aurelion.Aurelion", throwOnError: true); object? value = (type.GetField("characterPrefab", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingFieldException(type.FullName, "characterPrefab")).GetValue(null); SkillDef? obj = FindSkill(((((GameObject)(((value is GameObject) ? value : null) ?? throw new InvalidOperationException("Aurelion characterPrefab is not available."))).GetComponent<SkillLocator>() ?? throw new MissingComponentException("Aurelion characterPrefab has no SkillLocator.")).secondary ?? throw new InvalidOperationException("Aurelion characterPrefab has no secondary skill.")).skillFamily ?? throw new InvalidOperationException("Aurelion secondary skill has no SkillFamily.")) ?? throw new InvalidOperationException("Could not find Aurelion secondary skill 'AURELION_M2NEW'."); bool dontAllowPastMaxStocks = obj.dontAllowPastMaxStocks; obj.dontAllowPastMaxStocks = false; CenterOfTheUniverseUpgradePlugin.Log.LogInfo((object)$"Singularity extra-stock patch applied: dontAllowPastMaxStocks {dontAllowPastMaxStocks} -> false."); return true; } catch (Exception arg) { CenterOfTheUniverseUpgradePlugin.Log.LogError((object)$"Singularity extra-stock patch failed: {arg}"); return false; } } private static SkillDef? FindSkill(SkillFamily skillFamily) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Variant[] variants = skillFamily.variants; foreach (Variant val in variants) { if ((Object)(object)val.skillDef != (Object)null && string.Equals(val.skillDef.skillName, "AURELION_M2NEW", StringComparison.Ordinal)) { return val.skillDef; } } return null; } } internal sealed class StarRuntime { public GameObject Root; public GameObject Visual; public GameObject HitBoxRoot; public HitBoxGroup HitBoxGroup; public OverlapAttack? Attack; } }