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 AcolyteBetterEcho v0.1.0
AcolyteBetterEcho.dll
Decompiled 18 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.Acolyte.Backpack; using EntityStates.Acolyte.Sacrifice; using EntityStates.Acolyte.Weapon; using On.EntityStates.Acolyte.Backpack; using On.EntityStates.Acolyte.Sacrifice; using On.EntityStates.Acolyte.Weapon; using On.RoR2; 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 = "")] [assembly: AssemblyCompany("AcolyteBetterEcho")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("AcolyteBetterEcho")] [assembly: AssemblyTitle("AcolyteBetterEcho")] [assembly: AssemblyVersion("0.1.0.0")] namespace AcolyteBetterEcho; [BepInPlugin("com.EviLord.AcolyteBetterEcho", "AcolyteBetterEcho", "0.1.0")] public class AcolyteBetterEchoPlugin : BaseUnityPlugin { public const string PluginAuthor = "EviLord"; public const string PluginName = "AcolyteBetterEcho"; public const string PluginGUID = "com.EviLord.AcolyteBetterEcho"; public const string PluginVersion = "0.1.0"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> EchoSacrificeConvictions; private void Awake() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the Echo changes. Requires a restart."); EchoSacrificeConvictions = ((BaseUnityPlugin)this).Config.Bind<int>("General", "EchoSacrificeConvictions", 3, new ConfigDescription("Convictions granted by a Sacrifice hit when Anima Echo is selected (vanilla: 2). Kills still grant 1 extra. Gameplay uses the new value immediately; skill descriptions update after a restart.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 7), Array.Empty<object>())); if (Enabled.Value) { EchoChanges.Init(); EchoDescriptions.Init(); } Log.LogInfo((object)"AcolyteBetterEcho 0.1.0 loaded."); } } internal static class EchoChanges { private class ControllerState { public int bufferedSouls; public bool pendingSpecialReset; } private const string AnimaEchoNameToken = "ACOLYTE_SPECIAL_ALT_TRANSFORM_NAME"; private static readonly ConditionalWeakTable<AcolyteFormController, ControllerState> states = new ConditionalWeakTable<AcolyteFormController, ControllerState>(); internal static void Init() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown Sacrifice.OnEnter += new hook_OnEnter(Sacrifice_OnEnter); SacrificeIdle.FixedUpdate += new hook_FixedUpdate(SacrificeIdle_FixedUpdate); BaseBackpackState.OnEnter += new hook_OnEnter(BaseBackpackState_OnEnter); BaseBackpackState.OnExit += new hook_OnExit(BaseBackpackState_OnExit); AcolyteFormController.AddSouls += new hook_AddSouls(AcolyteFormController_AddSouls); } private static ControllerState GetState(AcolyteFormController controller) { return states.GetOrCreateValue(controller); } internal static bool IsEchoSelected(AcolyteFormController controller) { GenericSkill val = (Object.op_Implicit((Object)(object)controller) ? controller.transformSkillSlot : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.skillDef)) { return val.skillDef.skillNameToken == "ACOLYTE_SPECIAL_ALT_TRANSFORM_NAME"; } return false; } private static void Sacrifice_OnEnter(orig_OnEnter orig, Sacrifice self) { if (IsEchoSelected(((Component)((EntityState)self).outer).GetComponent<AcolyteFormController>())) { self.soulValue = AcolyteBetterEchoPlugin.EchoSacrificeConvictions.Value; } orig.Invoke(self); } private static void SacrificeIdle_FixedUpdate(orig_FixedUpdate orig, SacrificeIdle self) { orig.Invoke(self); if (!Object.op_Implicit((Object)(object)((BaseSacrificeState)self).controller)) { return; } ControllerState state = GetState(((BaseSacrificeState)self).controller); if (!state.pendingSpecialReset) { return; } GenericSkill val = ((Component)((EntityState)self).outer).GetComponent<SkillLocator>()?.special; if (!Object.op_Implicit((Object)(object)val)) { state.pendingSpecialReset = false; return; } if ((Object)(object)val.skillDef == (Object)(object)val.baseSkill) { val.Reset(); state.pendingSpecialReset = false; return; } SkillDef skillDef = val.skillDef; GenericSkill transformSkillSlot = ((BaseSacrificeState)self).controller.transformSkillSlot; if ((Object)(object)skillDef != (Object)(object)((transformSkillSlot != null) ? transformSkillSlot.skillDef : null)) { state.pendingSpecialReset = false; } } private static void BaseBackpackState_OnEnter(orig_OnEnter orig, BaseBackpackState self) { AcolyteFormController component = ((Component)((EntityState)self).outer).GetComponent<AcolyteFormController>(); if (Object.op_Implicit((Object)(object)component)) { GetState(component).bufferedSouls = 0; } orig.Invoke(self); if (self is BackpackActivate && IsEchoSelected(component) && Util.HasEffectiveAuthority(((Component)((EntityState)self).outer).gameObject)) { ResetSkills(((Component)((EntityState)self).outer).GetComponent<SkillLocator>()); GetState(component).pendingSpecialReset = true; } } private static void ResetSkills(SkillLocator skillLocator) { if (Object.op_Implicit((Object)(object)skillLocator)) { if (Object.op_Implicit((Object)(object)skillLocator.primary)) { skillLocator.primary.Reset(); } if (Object.op_Implicit((Object)(object)skillLocator.secondary)) { skillLocator.secondary.Reset(); } if (Object.op_Implicit((Object)(object)skillLocator.utility)) { skillLocator.utility.Reset(); } } } private static void BaseBackpackState_OnExit(orig_OnExit orig, BaseBackpackState self) { orig.Invoke(self); AcolyteFormController component = ((Component)((EntityState)self).outer).GetComponent<AcolyteFormController>(); if (!Object.op_Implicit((Object)(object)component)) { return; } ControllerState state = GetState(component); state.pendingSpecialReset = false; if (NetworkServer.active) { int bufferedSouls = state.bufferedSouls; state.bufferedSouls = 0; if (bufferedSouls > 0 && Object.op_Implicit((Object)(object)component.characterBody) && component.characterBody.healthComponent.alive) { component.AddSouls(bufferedSouls); } } } private static void AcolyteFormController_AddSouls(orig_AddSouls orig, AcolyteFormController self, int amount) { if (NetworkServer.active && self.isEchoForm && IsEchoSelected(self)) { GetState(self).bufferedSouls += amount; } else { orig.Invoke(self, amount); } } } internal static class EchoDescriptions { private struct Additions { public string echo; public string sacrifice; } private const string EchoDescriptionToken = "ACOLYTE_SPECIAL_ALT_TRANSFORM_DESCRIPTION"; private const string SacrificeDescriptionToken = "ACOLYTE_SPECIAL_DESCRIPTION"; private static readonly Dictionary<string, Additions> additions = new Dictionary<string, Additions>(StringComparer.OrdinalIgnoreCase) { ["en"] = new Additions { echo = " Activating it <style=cIsUtility>resets all skill cooldowns</style>. Convictions earned during the Litany are <style=cIsUtility>stored</style> and granted when it ends.", sacrifice = " With Anima Echo, gain <style=cIsDamage>{0}</style> Convictions instead." }, ["FR"] = new Additions { echo = " L'activation <style=cIsUtility>réinitialise le temps de recharge de toutes vos compétences</style>. Les Convictions obtenues pendant la Litanie sont <style=cIsUtility>conservées</style> et accordées à la fin de celle-ci.", sacrifice = " Avec l'Écho d'anima, confère <style=cIsDamage>{0}</style> Convictions à la place." }, ["IT"] = new Additions { echo = " L'attivazione <style=cIsUtility>azzera la ricarica di tutte le tue abilità</style>. Le Convinzioni ottenute durante la Litania vengono <style=cIsUtility>conservate</style> e conferite al suo termine.", sacrifice = " Con l'Eco dell'Anima, ottieni invece <style=cIsDamage>{0}</style> Convinzioni." }, ["RU"] = new Additions { echo = " При активации <style=cIsUtility>сбрасывает время восстановления всех навыков</style>. Заряды убеждения, полученные во время Литании, <style=cIsUtility>накапливаются</style> и начисляются после её окончания.", sacrifice = " С Эхом Анимы даёт <style=cIsDamage>{0}</style> {1} убеждения." }, ["de"] = new Additions { echo = " Beim Aktivieren werden <style=cIsUtility>die Abklingzeiten aller deiner Fähigkeiten zurückgesetzt</style>. Während der Litanei erhaltene Überzeugungen werden <style=cIsUtility>gespeichert</style> und nach ihrem Ende gewährt.", sacrifice = " Mit Anima-Echo erhältst du stattdessen <style=cIsDamage>{0}</style> Überzeugungen." }, ["es-ES"] = new Additions { echo = " Al activarlo, <style=cIsUtility>se reinician los tiempos de reutilización de todas tus habilidades</style>. Las convicciones obtenidas durante la Letanía se <style=cIsUtility>acumulan</style> y se otorgan al terminar.", sacrifice = " Con Eco de almas, obtiene <style=cIsDamage>{0}</style> convicciones en su lugar." }, ["es-419"] = new Additions { echo = " Al activarlo, <style=cIsUtility>se reinician los tiempos de reutilización de todas tus habilidades</style>. Las convicciones obtenidas durante la Letanía se <style=cIsUtility>acumulan</style> y se otorgan al terminar.", sacrifice = " Con Eco de almas, obtiene <style=cIsDamage>{0}</style> convicciones en su lugar." }, ["pt-BR"] = new Additions { echo = " Ao ativar, <style=cIsUtility>reinicia a recarga de todas as suas habilidades</style>. Convicções obtidas durante a Litania são <style=cIsUtility>armazenadas</style> e concedidas quando ela termina.", sacrifice = " Com Eco de Anima, ganha <style=cIsDamage>{0}</style> Convicções em vez disso." }, ["tr"] = new Additions { echo = " Etkinleştirildiğinde <style=cIsUtility>tüm yeteneklerinin bekleme sürelerini sıfırlar</style>. Ayin sırasında kazanılan İnançlar <style=cIsUtility>saklanır</style> ve Ayin sona erdiğinde verilir.", sacrifice = " Anima Yankısı seçiliyken bunun yerine <style=cIsDamage>{0}</style> İnanç kazanırsın." }, ["ja"] = new Additions { echo = "発動すると<style=cIsUtility>すべてのスキルのクールダウンがリセットされる</style>。リタニー中に獲得したコンヴィクションは<style=cIsUtility>蓄積され</style>、リタニー終了時に付与される。", sacrifice = "アニマの残響を選択している場合、代わりに<style=cIsDamage>{0}</style> 個のコンヴィクションを獲得する。" }, ["ko"] = new Additions { echo = " 발동 시 <style=cIsUtility>모든 스킬의 재사용 대기시간이 초기화</style>됩니다. 호칭기도 중에 얻은 신념은 <style=cIsUtility>저장</style>되었다가 호칭기도가 끝나면 지급됩니다.", sacrifice = " 생령의 메아리 선택 시 대신 신념 <style=cIsDamage>{0}</style>중첩을 얻습니다." }, ["zh-CN"] = new Additions { echo = "发动时<style=cIsUtility>重置所有技能的冷却时间</style>。诵祷期间获得的信念会被<style=cIsUtility>储存</style>,并在诵祷结束后获得。", sacrifice = "选择灵魂回响时,改为获得<style=cIsDamage>{0}</style>层信念。" } }; internal static void Init() { Language.onCurrentLanguageChanged += Apply; Apply(); } private static void Apply() { Language currentLanguage = Language.currentLanguage; if (currentLanguage != null && additions.TryGetValue(Language.currentLanguageName ?? "", out var value)) { Append(currentLanguage, "ACOLYTE_SPECIAL_ALT_TRANSFORM_DESCRIPTION", value.echo); int value2 = AcolyteBetterEchoPlugin.EchoSacrificeConvictions.Value; if (value2 != 2) { Append(currentLanguage, "ACOLYTE_SPECIAL_DESCRIPTION", string.Format(value.sacrifice, value2, RussianChargeWord(value2))); } } } private static void Append(Language language, string token, string addition) { string localizedStringByToken = language.GetLocalizedStringByToken(token); if (!localizedStringByToken.EndsWith(addition, StringComparison.Ordinal)) { language.SetStringByToken(token, localizedStringByToken + addition); } } private static string RussianChargeWord(int count) { int num = count % 100; int num2 = count % 10; if (num >= 11 && num <= 14) { return "зарядов"; } switch (num2) { case 1: return "заряд"; case 2: case 3: case 4: return "заряда"; default: return "зарядов"; } } } internal static class BuildInfo { public const string Version = "0.1.0"; }