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 CorpseBloomReborn v1.4.0
plugins/CorpseBloomReborn/CorpseBloomReborn.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using On.RoR2; using On.RoR2.UI; using RoR2; using RoR2.ContentManagement; using RoR2.UI; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; [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("CorpseBloomReborn")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CorpseBloomReborn")] [assembly: AssemblyTitle("CorpseBloomReborn")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace TPDespair.CorpseBloomReborn; public static class Configuration { public static ConfigEntry<bool> HideReserveBuff { get; set; } public static ConfigEntry<bool> HealBeforeReserve { get; set; } public static ConfigEntry<bool> HealWhenReserveFull { get; set; } public static ConfigEntry<float> BaseAbsorbMult { get; set; } public static ConfigEntry<float> AddedAbsorbMult { get; set; } public static ConfigEntry<float> BaseExportMult { get; set; } public static ConfigEntry<float> AddedExportMult { get; set; } public static ConfigEntry<int> AegisInteraction { get; set; } public static ConfigEntry<bool> RestoreRejuvBehavior { get; set; } public static ConfigEntry<float> BaseHealthReserve { get; set; } public static ConfigEntry<float> AddedHealthReserve { get; set; } public static ConfigEntry<bool> VanillaUsageBehavior { get; set; } public static ConfigEntry<float> BaseMaxUsageRate { get; set; } public static ConfigEntry<float> StackMaxUsageRate { get; set; } public static ConfigEntry<float> BaseMinUsageRate { get; set; } public static ConfigEntry<float> StackMinUsageRate { get; set; } internal static void Init(ConfigFile Config) { HideReserveBuff = Config.Bind<bool>("General", "HideReserveBuff", true, "Set CBReserve buff as hidden, preventing it from being drawn on your active buffs bar."); HealBeforeReserve = Config.Bind<bool>("General", "HealBeforeReserve", false, "If incoming healing should apply to health before going into reserve."); HealWhenReserveFull = Config.Bind<bool>("General", "HealWhenReserveFull", false, "If incoming healing should apply to health after reserve is full."); BaseAbsorbMult = Config.Bind<float>("General", "BaseAbsorbMult", 2f, "Reserve absorption. Base effectiveness of healing going into reserve."); AddedAbsorbMult = Config.Bind<float>("General", "AddedAbsorbMult", 1f, "Increased absorption effect per stack."); BaseExportMult = Config.Bind<float>("General", "BaseExportMult", 1f, "Base effectiveness of healing coming out of reserve."); AddedExportMult = Config.Bind<float>("General", "AddedExportMult", 0f, "Increased healing effect per stack."); AegisInteraction = Config.Bind<int>("General", "AegisInteraction", 1, "How does Aegis affect usage rate. 0 = No Effect, 1 = MaxUsage at MinBarrier / MinUsage at MaxBarrier, 2 = Always MaxUsage. Chooses highest between this and amount going to health (amount going to health is highest between MinUsage and HealMissingHealth capped at MaxUsage)."); RestoreRejuvBehavior = Config.Bind<bool>("General", "RestoreRejuvBehavior", false, "Most healing multipliers used to apply twice when used with Corpsebloom. Set to true to restore this behavior for Rejuvenation Rack."); BaseHealthReserve = Config.Bind<float>("General", "BaseHealthReserve", 1f, "Base reserve gained from health."); AddedHealthReserve = Config.Bind<float>("General", "AddedHealthReserve", 0.5f, "Added reserve gained from health per stack."); VanillaUsageBehavior = Config.Bind<bool>("General", "VanillaUsageBehavior", false, "Scale reserve outputs by 1 / stack count."); BaseMaxUsageRate = Config.Bind<float>("General", "BaseMaxUsageRate", 0.1f, "Base maximum healing output from reserve per second."); StackMaxUsageRate = Config.Bind<float>("General", "StackMaxUsageRate", 0f, "Stack maximum healing output from reserve per second."); BaseMinUsageRate = Config.Bind<float>("General", "BaseMinUsageRate", 0.05f, "Base minimum healing output from reserve per second. Set to 0 to disable reserve decay."); StackMinUsageRate = Config.Bind<float>("General", "StackMinUsageRate", 0f, "Stack minimum healing output from reserve per second."); if (BaseAbsorbMult.Value < 0.1f) { BaseAbsorbMult.Value = 0.1f; } if (BaseExportMult.Value < 0.1f) { BaseExportMult.Value = 0.1f; } if (BaseHealthReserve.Value < 0.1f) { BaseHealthReserve.Value = 0.1f; } if (BaseMaxUsageRate.Value < 0.01f) { BaseMaxUsageRate.Value = 0.01f; } if (BaseMinUsageRate.Value < 0f) { BaseMinUsageRate.Value = 0f; } } } public class CorpseBloomRebornContent : IContentPackProvider { public static class Buffs { public static BuffDef CBReserve; public static List<BuffDef> buffDefs = new List<BuffDef>(); public static void Create() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) CBReserve = ScriptableObject.CreateInstance<BuffDef>(); ((Object)CBReserve).name = "CBReserve"; CBReserve.buffColor = new Color(0.65f, 0.35f, 1f); CBReserve.canStack = true; CBReserve.isDebuff = false; CBReserve.iconSprite = LegacyResourcesAPI.Load<BuffDef>("BuffDefs/MedkitHeal").iconSprite; if (Configuration.HideReserveBuff.Value) { CBReserve.isHidden = true; } buffDefs.Add(CBReserve); } } [CompilerGenerated] private sealed class <FinalizeAsync>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public FinalizeAsyncArgs args; public CorpseBloomRebornContent <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FinalizeAsync>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; args.ReportProgress(1f); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <GenerateContentPackAsync>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GetContentPackAsyncArgs args; public CorpseBloomRebornContent <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GenerateContentPackAsync>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; ContentPack.Copy(<>4__this.contentPack, args.output); args.ReportProgress(1f); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadStaticContentAsync>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public LoadStaticContentAsyncArgs args; public CorpseBloomRebornContent <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadStaticContentAsync>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; Buffs.Create(); ReserveManager.IndicatorBuff = Buffs.CBReserve; <>4__this.contentPack.buffDefs.Add(Buffs.buffDefs.ToArray()); args.ReportProgress(1f); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public ContentPack contentPack = new ContentPack(); public string identifier => "CorpseBloomRebornContent"; [IteratorStateMachine(typeof(<LoadStaticContentAsync>d__3))] public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadStaticContentAsync>d__3(0) { <>4__this = this, args = args }; } [IteratorStateMachine(typeof(<GenerateContentPackAsync>d__4))] public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GenerateContentPackAsync>d__4(0) { <>4__this = this, args = args }; } [IteratorStateMachine(typeof(<FinalizeAsync>d__5))] public IEnumerator FinalizeAsync(FinalizeAsyncArgs args) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FinalizeAsync>d__5(0) { <>4__this = this, args = args }; } } [BepInPlugin("com.TPDespair.CorpseBloomReborn", "CorpseBloomReborn", "1.4.0")] public class CorpseBloomRebornPlugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_Awake <>9__11_0; public static hook_Awake <>9__12_0; public static hook_TokenIsRegistered <>9__14_0; public static hook_GetString_string <>9__14_1; internal void <HudAwakeHook>b__11_0(orig_Awake orig, HUD self) { orig.Invoke(self); HudReserveDisplay hudReserveDisplay = ((Component)self).gameObject.AddComponent<HudReserveDisplay>(); hudReserveDisplay.hud = self; } internal void <AllyCardAwakeHook>b__12_0(orig_Awake orig, AllyCardController self) { orig.Invoke(self); AllyReserveDisplay allyReserveDisplay = ((Component)self).gameObject.AddComponent<AllyReserveDisplay>(); allyReserveDisplay.controller = self; } internal bool <LanguageOverride>b__14_0(orig_TokenIsRegistered orig, Language self, string token) { if (token != null && LangTokens.ContainsKey(token)) { return true; } return orig.Invoke(self, token); } internal string <LanguageOverride>b__14_1(orig_GetString_string orig, string token) { if (token != null && LangTokens.ContainsKey(token)) { return LangTokens[token]; } return orig.Invoke(token); } } public const string ModVer = "1.4.0"; public const string ModName = "CorpseBloomReborn"; public const string ModGuid = "com.TPDespair.CorpseBloomReborn"; public static Dictionary<string, string> LangTokens = new Dictionary<string, string>(); public static ArtifactIndex DiluvianArtifact = (ArtifactIndex)(-1); public void Awake() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown RoR2Application.isModded = true; NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Append("com.TPDespair.CorpseBloomReborn:1.4.0"); Configuration.Init(((BaseUnityPlugin)this).Config); ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(ContentManager_collectContentPackProviders); ReserveManager.Init(); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(ApplicationOnLoad)); HudAwakeHook(); AllyCardAwakeHook(); HUD.onHudTargetChangedGlobal += HudTargetChanged; LanguageOverride(); RegisterLanguageToken("ITEM_REPEATHEAL_DESC", GetCorpseBloomDesc()); RegisterLanguageToken("ITEM_REPEATHEAL_PICKUP", GetCorpseBloomPickup()); } public void FixedUpdate() { ReserveManager.OnFixedUpdate(); } private void ContentManager_collectContentPackProviders(AddContentPackProviderDelegate addContentPackProvider) { addContentPackProvider.Invoke((IContentPackProvider)(object)new CorpseBloomRebornContent()); } private static void ApplicationOnLoad() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_002a: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown Run.onRunStartGlobal += RunStartHealPriority; ArtifactIndex val = ArtifactCatalog.FindArtifactIndex("ARTIFACT_DILUVIFACT"); if ((int)val != -1) { DiluvianArtifact = val; RunArtifactManager.onArtifactEnabledGlobal += new ArtifactStateChangeDelegate(ArtifactEnabledHealPriority); } } private static void RunStartHealPriority(Run run) { ReserveManager.RequestPriorityHealHook(); } private static void ArtifactEnabledHealPriority(RunArtifactManager manager, ArtifactDef artifactDef) { //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) if (Object.op_Implicit((Object)(object)artifactDef) && artifactDef.artifactIndex == DiluvianArtifact) { ReserveManager.RequestPriorityHealHook(); } } private static void HudAwakeHook() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown object obj = <>c.<>9__11_0; if (obj == null) { hook_Awake val = delegate(orig_Awake orig, HUD self) { orig.Invoke(self); HudReserveDisplay hudReserveDisplay = ((Component)self).gameObject.AddComponent<HudReserveDisplay>(); hudReserveDisplay.hud = self; }; <>c.<>9__11_0 = val; obj = (object)val; } HUD.Awake += (hook_Awake)obj; } private static void AllyCardAwakeHook() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown object obj = <>c.<>9__12_0; if (obj == null) { hook_Awake val = delegate(orig_Awake orig, AllyCardController self) { orig.Invoke(self); AllyReserveDisplay allyReserveDisplay = ((Component)self).gameObject.AddComponent<AllyReserveDisplay>(); allyReserveDisplay.controller = self; }; <>c.<>9__12_0 = val; obj = (object)val; } AllyCardController.Awake += (hook_Awake)obj; } private static void HudTargetChanged(HUD hud) { HudReserveDisplay component = ((Component)hud).GetComponent<HudReserveDisplay>(); if (Object.op_Implicit((Object)(object)component)) { component.RequestRebuild(); } } private static void LanguageOverride() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown object obj = <>c.<>9__14_0; if (obj == null) { hook_TokenIsRegistered val = (orig_TokenIsRegistered orig, Language self, string token) => (token != null && LangTokens.ContainsKey(token)) || orig.Invoke(self, token); <>c.<>9__14_0 = val; obj = (object)val; } Language.TokenIsRegistered += (hook_TokenIsRegistered)obj; object obj2 = <>c.<>9__14_1; if (obj2 == null) { hook_GetString_string val2 = (orig_GetString_string orig, string token) => (token != null && LangTokens.ContainsKey(token)) ? LangTokens[token] : orig.Invoke(token); <>c.<>9__14_1 = val2; obj2 = (object)val2; } Language.GetString_string += (hook_GetString_string)obj2; } public static void RegisterLanguageToken(string token, string text) { if (!LangTokens.ContainsKey(token)) { LangTokens.Add(token, text); } else { LangTokens[token] = text; } } private static string GetCorpseBloomDesc() { string text = ""; text = (Configuration.HealBeforeReserve.Value ? (text + "Gain extra healing as reserve.") : ((!Configuration.HealWhenReserveFull.Value) ? (text + "All healing is applied over time.") : (text + "Store healing to heal over time."))); text += "\nGain <style=cIsHealing>"; text += $"{Configuration.BaseHealthReserve.Value * 100f:0.##}%</style>"; if (Configuration.AddedHealthReserve.Value != 0f) { text += " <style=cStack>("; if (Configuration.AddedHealthReserve.Value > 0f) { text += "+"; } text += $"{Configuration.AddedHealthReserve.Value * 100f:0.##}% per stack)</style>"; } text += " of your <style=cIsHealing>maximum health</style> as <style=cIsHealing>maximum reserve</style>."; text = text + "\nStore <style=cIsHealing>" + Configuration.BaseAbsorbMult.Value * 100f + "%</style>"; if (Configuration.AddedAbsorbMult.Value != 0f) { text += " <style=cStack>("; if (Configuration.AddedAbsorbMult.Value > 0f) { text += "+"; } text = text + Configuration.AddedAbsorbMult.Value * 100f + "% per stack)</style>"; } text += " of healing as <style=cIsHealing>reserve</style>."; text += "\nCan <style=cIsHealing>heal</style> for <style=cIsHealing>"; text += $"{Configuration.BaseMaxUsageRate.Value * 100f:0.##}%</style>"; if (Configuration.StackMaxUsageRate.Value != 0f) { text += " <style=cStack>("; if (Configuration.StackMaxUsageRate.Value > 0f) { text += "+"; } text += $"{Configuration.StackMaxUsageRate.Value * 100f:0.##}% per stack)</style>"; } text += " of your <style=cIsHealing>maximum health</style> every second from <style=cIsHealing>reserve</style>."; if (Configuration.VanillaUsageBehavior.Value) { text += "\n<style=cStack>(Additional stacks further reduce healing rate)</style>"; } text += "\n"; if (Configuration.BaseExportMult.Value != 1f || Configuration.AddedExportMult.Value != 0f) { string text2 = ((Configuration.AddedExportMult.Value == 0f) ? ((!(Configuration.BaseExportMult.Value > 1f)) ? "<style=cDeath>" : "<style=cIsHealing>") : ((Configuration.AddedExportMult.Value > 0f) ? ((!(Configuration.BaseExportMult.Value >= 1f)) ? "<style=cIsDamage>" : "<style=cIsHealing>") : ((!(Configuration.BaseExportMult.Value > 1f)) ? "<style=cDeath>" : "<style=cIsDamage>"))); text = text + "\n" + text2; if (Configuration.BaseExportMult.Value >= 1f) { text += "+"; } text += $"{(Configuration.BaseExportMult.Value - 1f) * 100f:0.##}%</style>"; if (Configuration.AddedExportMult.Value != 0f) { text += " <style=cStack>("; if (Configuration.AddedExportMult.Value > 0f) { text += "+"; } text += $"{Configuration.AddedExportMult.Value * 100f:0.##}% per stack)</style>"; } text += " Healing Multiplier."; } return text; } private static string GetCorpseBloomPickup() { if (Configuration.HealBeforeReserve.Value) { return "Gain extra healing as reserve."; } if (Configuration.HealWhenReserveFull.Value) { return "Store healing to heal over time."; } return "All healing is applied over time."; } } public class BaseReserveDisplay : MonoBehaviour { public HealthBar healthBar; private GameObject reserveContainer; private RectTransform containerTransform; private GameObject reserveBar; private RectTransform barTransform; private float reserveFraction = 0f; private float displayScale = 0f; private bool rebuild = true; private float rebuildTimer = 0.25f; public void UpdateReserveDisplay() { UpdateDisplayValues(); UpdateContainer(); UpdateDisplay(); } public void UpdateDisplayValues() { reserveFraction = 0f; if (!Object.op_Implicit((Object)(object)healthBar)) { return; } HealthComponent source = healthBar.source; if (!Object.op_Implicit((Object)(object)source)) { return; } CharacterBody body = source.body; if (Object.op_Implicit((Object)(object)body)) { int buffCount = body.GetBuffCount(CorpseBloomRebornContent.Buffs.CBReserve); if (buffCount > 0) { reserveFraction = Mathf.Clamp((float)buffCount / 100f, 0f, 1f); displayScale = 1f / body.cursePenalty * (source.fullHealth / source.fullCombinedHealth); } } } public void UpdateContainer() { if (Object.op_Implicit((Object)(object)reserveContainer) && rebuild) { rebuildTimer -= Time.deltaTime; if (rebuildTimer <= 0f) { rebuildTimer = 0.25f; rebuild = false; DestroyReserveBar(); } } if (reserveFraction > 0f && !Object.op_Implicit((Object)(object)reserveContainer)) { CreateReserveBar(); } } public void UpdateDisplay() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reserveContainer)) { return; } if (reserveFraction > 0f) { float num = -0.5f + reserveFraction * displayScale; barTransform.anchorMax = new Vector2(num, 0.5f); if (!reserveContainer.activeSelf) { reserveContainer.SetActive(true); } } else if (reserveContainer.activeSelf) { reserveContainer.SetActive(false); } } public void RequestRebuild() { rebuildTimer = 0.25f; rebuild = true; } private void DestroyReserveBar() { reserveContainer.SetActive(false); Object.Destroy((Object)(object)reserveContainer); reserveContainer = null; containerTransform = null; reserveBar = null; barTransform = null; } private void CreateReserveBar() { //IL_000c: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) Rect rect = healthBar.barContainer.rect; float width = ((Rect)(ref rect)).width; float num = Mathf.CeilToInt(((Rect)(ref rect)).height / 3.125f); float num2 = width / 2f; reserveContainer = new GameObject("ReserveRect"); containerTransform = reserveContainer.AddComponent<RectTransform>(); ((Transform)containerTransform).position = new Vector3(0f, 0f); containerTransform.anchoredPosition = new Vector2(num2, 0f); containerTransform.anchorMin = new Vector2(0f, 0f); containerTransform.anchorMax = new Vector2(0f, 0f); containerTransform.offsetMin = new Vector2(num2, 0f); containerTransform.offsetMax = new Vector2(num2, num); containerTransform.sizeDelta = new Vector2(width, num); containerTransform.pivot = new Vector2(0f, 0f); reserveBar = new GameObject("ReserveBar"); reserveBar.transform.SetParent(((Component)containerTransform).transform); barTransform = reserveBar.AddComponent<RectTransform>(); barTransform.sizeDelta = new Vector2(width, num); barTransform.pivot = new Vector2(0.5f, 1f); ((Graphic)reserveBar.AddComponent<Image>()).color = new Color(0.625f, 0.25f, 1f, 0.65f); reserveContainer.transform.SetParent(((Component)healthBar).transform, false); } } public class HudReserveDisplay : BaseReserveDisplay { public HUD hud; public void Update() { if (Object.op_Implicit((Object)(object)hud)) { healthBar = hud.healthBar; } UpdateReserveDisplay(); } } public class AllyReserveDisplay : BaseReserveDisplay { public AllyCardController controller; public bool indented = false; public void Update() { if (Object.op_Implicit((Object)(object)controller)) { healthBar = controller.healthBar; bool shouldIndent = controller.shouldIndent; if (indented != shouldIndent) { RequestRebuild(); indented = shouldIndent; } } UpdateReserveDisplay(); } } public static class ReserveManager { public class ReserveInfo { public HealthComponent healthComponent; public float healTimer = 0.25f; public float displayTimer = 0.25f; public int buffCount = 0; public float maximum = 1f; public float reserve = 0f; public float maxRate = 0.1f; public float minRate = 0f; public float absorbMult = 1f; public float exportMult = 1f; public bool healingDisabled = false; public int aegisState = 0; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_RecalculateStats <>9__15_0; public static hook_OnDestroy <>9__16_0; internal void <RecalculateReserveHook>b__15_0(orig_RecalculateStats orig, CharacterBody self) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (NetworkServer.active && Object.op_Implicit((Object)(object)self) && ReserveData.ContainsKey(((NetworkBehaviour)self).netId)) { RecalcReserveInfo(self); } } internal void <DestroyReserveHook>b__16_0(orig_OnDestroy orig, CharacterBody self) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) if (NetworkServer.active & Object.op_Implicit((Object)(object)self)) { DestroyedBodies.Add(((NetworkBehaviour)self).netId, 3.5f); if (ReserveData.ContainsKey(((NetworkBehaviour)self).netId)) { ReserveData[((NetworkBehaviour)self).netId].healthComponent = null; } } orig.Invoke(self); } } public static Dictionary<NetworkInstanceId, ReserveInfo> ReserveData = new Dictionary<NetworkInstanceId, ReserveInfo>(); private static Dictionary<NetworkInstanceId, float> DestroyedBodies = new Dictionary<NetworkInstanceId, float>(); private static float DestroyFixedUpdateStopwatch = 0f; private const float ReserveUpdateInterval = 0.25f; internal static BuffDef IndicatorBuff; private static bool Rehook = false; private static float RehookTimer = 0f; private static bool HealHooked = false; public static ReserveInfo GetReserveInfo(HealthComponent healthComponent) { CharacterBody body = healthComponent.body; if (Object.op_Implicit((Object)(object)body)) { return GetReserveInfo(body); } return null; } public static ReserveInfo GetReserveInfo(CharacterBody body) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (DestroyedBodies.ContainsKey(((NetworkBehaviour)body).netId)) { return null; } if (!ReserveData.ContainsKey(((NetworkBehaviour)body).netId)) { ReserveInfo value = new ReserveInfo(); ReserveData.Add(((NetworkBehaviour)body).netId, value); RecalcReserveInfo(body); } return ReserveData[((NetworkBehaviour)body).netId]; } private static void RecalcReserveInfo(CharacterBody body) { ReserveInfo reserveInfo = GetReserveInfo(body); if (reserveInfo == null) { return; } float num = 1f; float num2 = 0.1f; float num3 = 0f; float num4 = 1f; float exportMult = 1f; int aegisState = 0; if (!Object.op_Implicit((Object)(object)reserveInfo.healthComponent)) { HealthComponent healthComponent = body.healthComponent; if (Object.op_Implicit((Object)(object)healthComponent)) { reserveInfo.healthComponent = healthComponent; } } Inventory inventory = body.inventory; if (Object.op_Implicit((Object)(object)inventory)) { int itemCountEffective = inventory.GetItemCountEffective(Items.RepeatHeal); if (itemCountEffective > 0) { num = Mathf.Max(0.1f, Configuration.BaseHealthReserve.Value + Configuration.AddedHealthReserve.Value * (float)(itemCountEffective - 1)); num3 = Mathf.Max(0f, Configuration.BaseMinUsageRate.Value + Configuration.StackMinUsageRate.Value * (float)(itemCountEffective - 1)); num2 = Mathf.Max(new float[3] { 0.01f, num3, Configuration.BaseMaxUsageRate.Value + Configuration.StackMaxUsageRate.Value * (float)(itemCountEffective - 1) }); if (Configuration.VanillaUsageBehavior.Value) { num3 = Mathf.Max(0f, num3 / (float)itemCountEffective); num2 = Mathf.Max(0.01f, num2 / (float)itemCountEffective); } num4 = Mathf.Max(0.1f, Configuration.BaseAbsorbMult.Value + Configuration.AddedAbsorbMult.Value * (float)(itemCountEffective - 1)); exportMult = Mathf.Max(0.1f, Configuration.BaseExportMult.Value + Configuration.AddedExportMult.Value * (float)(itemCountEffective - 1)); } else { reserveInfo.reserve = 0f; } if (Configuration.RestoreRejuvBehavior.Value) { itemCountEffective = inventory.GetItemCountEffective(Items.IncreaseHealing); if (itemCountEffective > 0) { num4 *= 1f + (float)itemCountEffective; } } if (Configuration.AegisInteraction.Value > 0) { itemCountEffective = inventory.GetItemCountEffective(Items.BarrierOnOverHeal); if (itemCountEffective > 0) { aegisState = Configuration.AegisInteraction.Value; } } } reserveInfo.maximum = Mathf.Max(1f, body.maxHealth * num); reserveInfo.reserve = Mathf.Min(reserveInfo.reserve, reserveInfo.maximum); reserveInfo.maxRate = num2; reserveInfo.minRate = num3; reserveInfo.absorbMult = num4; reserveInfo.exportMult = exportMult; reserveInfo.healingDisabled = body.HasBuff(Buffs.HealingDisabled); reserveInfo.aegisState = aegisState; } public static void AddReserve(ReserveInfo reserveInfo, float amount) { //IL_00b6: 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) float num = 0f; float num2 = 0f; HealthComponent healthComponent = reserveInfo.healthComponent; if (Object.op_Implicit((Object)(object)healthComponent)) { if (Configuration.HealBeforeReserve.Value) { num = Math.Min(amount, (healthComponent.fullHealth - healthComponent.health) / reserveInfo.exportMult); amount -= num; } if (amount > 0f) { num2 = Math.Min(amount, (reserveInfo.maximum - reserveInfo.reserve) / reserveInfo.absorbMult); amount -= num2; } if (amount > 0f && Configuration.HealWhenReserveFull.Value) { num += amount; } if (num > 0f) { ProcChainMask val = default(ProcChainMask); ((ProcChainMask)(ref val)).AddProc((ProcType)13); healthComponent.Heal(num * reserveInfo.exportMult, val, true); } } else { num2 = amount; } reserveInfo.reserve = Mathf.Min(reserveInfo.reserve + num2 * reserveInfo.absorbMult, reserveInfo.maximum); } internal static void Init() { RecalculateReserveHook(); DestroyReserveHook(); } internal static void OnFixedUpdate() { PrioritizeHealHook(); DestroyReserveData(); if (NetworkServer.active && Object.op_Implicit((Object)(object)Run.instance)) { UpdateReserveInfos(); } } private static void RecalculateReserveHook() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown object obj = <>c.<>9__15_0; if (obj == null) { hook_RecalculateStats val = delegate(orig_RecalculateStats orig, CharacterBody self) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (NetworkServer.active && Object.op_Implicit((Object)(object)self) && ReserveData.ContainsKey(((NetworkBehaviour)self).netId)) { RecalcReserveInfo(self); } }; <>c.<>9__15_0 = val; obj = (object)val; } CharacterBody.RecalculateStats += (hook_RecalculateStats)obj; } private static void DestroyReserveHook() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown object obj = <>c.<>9__16_0; if (obj == null) { hook_OnDestroy val = delegate(orig_OnDestroy orig, CharacterBody self) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) if (NetworkServer.active & Object.op_Implicit((Object)(object)self)) { DestroyedBodies.Add(((NetworkBehaviour)self).netId, 3.5f); if (ReserveData.ContainsKey(((NetworkBehaviour)self).netId)) { ReserveData[((NetworkBehaviour)self).netId].healthComponent = null; } } orig.Invoke(self); }; <>c.<>9__16_0 = val; obj = (object)val; } CharacterBody.OnDestroy += (hook_OnDestroy)obj; } internal static void RequestPriorityHealHook() { RehookTimer = 1f; Rehook = true; } private static void PrioritizeHealHook() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown if (!Rehook) { return; } RehookTimer -= Time.fixedDeltaTime; if (RehookTimer <= 0f) { RehookTimer = 1f; Rehook = false; if (HealHooked) { HealthComponent.Heal -= new hook_Heal(PriorityHealHook); HealHooked = false; } HealthComponent.Heal += new hook_Heal(PriorityHealHook); HealHooked = true; } } private static float PriorityHealHook(orig_Heal orig, HealthComponent self, float amount, ProcChainMask procChainMask, bool nonRegen) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && nonRegen && Object.op_Implicit((Object)(object)self.repeatHealComponent) && !((ProcChainMask)(ref procChainMask)).HasProc((ProcType)13)) { if (self.alive && amount > 0f && !self.body.HasBuff(Buffs.HealingDisabled)) { ReserveInfo reserveInfo = GetReserveInfo(self); if (reserveInfo != null) { AddReserve(reserveInfo, amount); } } return 0f; } return orig.Invoke(self, amount, procChainMask, nonRegen); } private static void DestroyReserveData() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) DestroyFixedUpdateStopwatch += Time.fixedDeltaTime; if (!(DestroyFixedUpdateStopwatch >= 0.5f)) { return; } List<NetworkInstanceId> list = new List<NetworkInstanceId>(DestroyedBodies.Keys); foreach (NetworkInstanceId item in list) { DestroyedBodies[item] -= DestroyFixedUpdateStopwatch; if (DestroyedBodies[item] <= 0f) { DestroyedBodies.Remove(item); if (ReserveData.ContainsKey(item)) { ReserveData.Remove(item); } } } DestroyFixedUpdateStopwatch = 0f; } private static void UpdateReserveInfos() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) float fixedDeltaTime = Time.fixedDeltaTime; List<NetworkInstanceId> list = new List<NetworkInstanceId>(ReserveData.Keys); foreach (NetworkInstanceId item in list) { if (!DestroyedBodies.ContainsKey(item)) { UpdateReserveInfo(ReserveData[item], fixedDeltaTime); } } } private static void UpdateReserveInfo(ReserveInfo reserveInfo, float deltaTime) { //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) HealthComponent healthComponent = reserveInfo.healthComponent; if (!Object.op_Implicit((Object)(object)healthComponent) || !healthComponent.alive) { return; } reserveInfo.displayTimer -= deltaTime; if (reserveInfo.displayTimer <= 0f) { reserveInfo.displayTimer = 0.25f; CharacterBody body = healthComponent.body; if (Object.op_Implicit((Object)(object)body)) { int num = 0; if (reserveInfo.reserve > 0f) { num = Mathf.Clamp(Mathf.RoundToInt(reserveInfo.reserve / reserveInfo.maximum * 100f), 1, 100); } reserveInfo.buffCount = num; if (body.GetBuffCount(IndicatorBuff) != num) { body.SetBuffCount(IndicatorBuff.buffIndex, num); } } } if (ResetTimer(reserveInfo)) { reserveInfo.healTimer = 0.25f; return; } reserveInfo.healTimer -= deltaTime; if (reserveInfo.healTimer <= 0f) { reserveInfo.healTimer = 0.25f; reserveInfo.displayTimer = Mathf.Clamp(reserveInfo.displayTimer, 0.15f, 0.2f); float num2 = ReserveHealAmount(reserveInfo); reserveInfo.reserve -= num2; ProcChainMask val = default(ProcChainMask); ((ProcChainMask)(ref val)).AddProc((ProcType)13); reserveInfo.healthComponent.Heal(num2 * reserveInfo.exportMult, val, true); } } private static bool ResetTimer(ReserveInfo reserveInfo) { if (reserveInfo.reserve <= 0f) { return true; } if (reserveInfo.healingDisabled) { return true; } if (reserveInfo.minRate > 0f) { return false; } if (reserveInfo.aegisState > 0) { return false; } HealthComponent healthComponent = reserveInfo.healthComponent; if (healthComponent.health >= healthComponent.fullHealth) { return true; } return false; } private static float ReserveHealAmount(ReserveInfo reserveInfo) { HealthComponent healthComponent = reserveInfo.healthComponent; float fullHealth = healthComponent.fullHealth; float num = fullHealth * reserveInfo.maxRate * 0.25f; if (reserveInfo.aegisState >= 2) { return Mathf.Min(reserveInfo.reserve, num); } float num2 = fullHealth * reserveInfo.minRate * 0.25f; float num3 = (fullHealth - healthComponent.health) / reserveInfo.exportMult; float num4 = Mathf.Max(num2, num3); if (reserveInfo.aegisState == 1) { float num5 = Mathf.Lerp(num, num2, healthComponent.barrier / healthComponent.fullBarrier); num4 = Mathf.Max(num4, num5); } return Mathf.Min(new float[3] { reserveInfo.reserve, num, num4 }); } }