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 SaneTranscendence v1.0.0
SaneTranscendence.dll
Decompiled a day agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using IL.RoR2; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.Cil; using R2API; using RoR2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SaneTranscendence")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SaneTranscendence")] [assembly: AssemblyTitle("SaneTranscendence")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 SaneTranscendence { internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static string Format(object data, string file, int line) { string fileName = Path.GetFileName(file); return $"[{fileName}:{line}] {data}"; } internal static void Debug(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogDebug((object)Format(data, file, line)); } internal static void Error(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogError((object)Format(data, file, line)); } internal static void Fatal(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogFatal((object)Format(data, file, line)); } internal static void Info(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogInfo((object)Format(data, file, line)); } internal static void Message(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogMessage((object)Format(data, file, line)); } internal static void Warning(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogWarning((object)Format(data, file, line)); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.paimcakes.sanetranscendence", "SaneTranscendence", "1.0.0")] public class SaneTranscendence : BaseUnityPlugin { private const float DelayPerStack = 0.2f; private const float RechargeKeptPerStack = 0.8f; private void Awake() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown CharacterBody.RecalculateStats += new Manipulator(ChangeItemStats); CharacterBody.UpdateOutOfCombatAndDanger += new Manipulator(PatchDangerDelay); HealthComponent.ServerFixedUpdate += new Manipulator(PatchShieldRecharge); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(UpdateDescription)); } private static int Stacks(CharacterBody body) { if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.inventory)) { return 0; } return body.inventory.GetItemCountEffective(Items.ShieldOnly); } private void ChangeItemStats(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = default(int); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[4] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 1.5f), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 1), (Instruction x) => ILPatternMatchingExt.MatchSub(x) })) { int index = val.Index; val.Index = index + 1; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<float, CharacterBody, float>>((Func<float, CharacterBody, float>)((float vanilla, CharacterBody body) => (Stacks(body) > 0) ? 1f : vanilla)); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"SaneTranscendence: health IL match failed"); } } private void PatchDangerDelay(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterBody>(x, "outOfDangerStopwatch") || ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_outOfDangerStopwatch"), (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 7f) })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<float, CharacterBody, float>>((Func<float, CharacterBody, float>)((float delay, CharacterBody body) => delay * (1f + 0.2f * (float)Stacks(body)))); return; } ((BaseUnityPlugin)this).Logger.LogError((object)("SaneTranscendence: delay match failed in " + ((MemberReference)il.Method).Name + ". Instructions touching outOfDanger or 7f:")); Collection<Instruction> instrs = il.Instrs; for (int num = 0; num < instrs.Count; num++) { object operand = instrs[num].Operand; MemberReference val2 = (MemberReference)((operand is MemberReference) ? operand : null); if ((val2 != null && val2.Name.Contains("outOfDanger")) || (instrs[num].Operand is float num2 && num2 == 7f)) { ((BaseUnityPlugin)this).Logger.LogError((object)$"--- at instruction {num}"); for (int num3 = Math.Max(0, num - 1); num3 <= Math.Min(instrs.Count - 1, num + 3); num3++) { ((BaseUnityPlugin)this).Logger.LogError((object)(" " + Describe(instrs[num3]))); } } } } private static string Describe(Instruction ins) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) string text; if (ins.Operand == null) { text = ""; } else { object operand = ins.Operand; MemberReference val = (MemberReference)((operand is MemberReference) ? operand : null); text = ((val != null) ? val.FullName : ((!(ins.Operand is float) && !(ins.Operand is int)) ? ins.Operand.GetType().Name : ins.Operand.ToString())); } return ((object)ins.OpCode/*cast due to .constrained prefix*/).ToString() + " " + text; } private void PatchShieldRecharge(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "Play_item_proc_personal_shield_end") }) && val.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0.5f) })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<float, HealthComponent, float>>((Func<float, HealthComponent, float>)((float rate, HealthComponent hc) => rate * Mathf.Pow(0.8f, (float)Stacks(hc.body)))); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"SaneTranscendence: shield recharge IL match failed"); } } private void UpdateDescription() { ItemDef shieldOnly = Items.ShieldOnly; string text = "<style=cIsHealing>Convert all but 1 health</style> into <style=cIsHealing>regenerating shields</style>. Gain <style=cIsHealing>0% maximum health</style> <style=cStack>(+25% per stack)</style>. " + $"Increase shield recharge delay by <style=cIsDamage>{20f:0}%</style> <style=cStack>(+{20f:0}% per stack)</style>. " + $"Reduce shield recharge rate by <style=cIsDamage>{19.999998f:0}%</style> <style=cStack>(-{19.999998f:0}% per stack)</style>."; LanguageAPI.Add(shieldOnly.descriptionToken, text); LanguageAPI.Add(shieldOnly.pickupToken, "Convert all but 1 health into regenerating shields. Slower shield recharge."); } } }