Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of SurvivorEnemyAndSkillCustomizer v1.3.1
SurvivorEnemyAndSkillCustomizer.dll
Decompiled 3 days agousing System; 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 System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using EntityStates; using Microsoft.CodeAnalysis; using R2API.Utils; using RoR2; using RoR2.Skills; 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("SurvivorEnemyAndSkillCustomizer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SurvivorEnemyAndSkillCustomizer")] [assembly: AssemblyTitle("SurvivorEnemyAndSkillCustomizer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 SurvivorEnemyAndSkillCustomizer { public class ROStuff { public static readonly IReadOnlyDictionary<string, InterruptPriority> SToInPr = new Dictionary<string, InterruptPriority> { { "Any", (InterruptPriority)0 }, { "Skill", (InterruptPriority)1 }, { "PrioritySkill", (InterruptPriority)2 }, { "Pain", (InterruptPriority)3 }, { "Frozen", (InterruptPriority)7 }, { "Vehicle", (InterruptPriority)8 }, { "Death", (InterruptPriority)9 } }; public static readonly List<Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>> SurvivorModifyableValues = new List<Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>> { new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseAcceleration", "float", (CharacterBody character) => character.baseAcceleration.ToString(), delegate(CharacterBody character, string value) { character.baseAcceleration = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseArmor", "float", (CharacterBody character) => character.baseArmor.ToString(), delegate(CharacterBody character, string value) { character.baseArmor = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelArmor", "float", (CharacterBody character) => character.levelArmor.ToString(), delegate(CharacterBody character, string value) { character.levelArmor = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseAttackSpeed", "float", (CharacterBody character) => character.baseAttackSpeed.ToString(), delegate(CharacterBody character, string value) { character.baseAttackSpeed = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelAttackSpeed", "float", (CharacterBody character) => character.levelAttackSpeed.ToString(), delegate(CharacterBody character, string value) { character.levelAttackSpeed = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseCrit", "float", (CharacterBody character) => character.baseCrit.ToString(), delegate(CharacterBody character, string value) { character.baseCrit = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelCrit", "float", (CharacterBody character) => character.levelCrit.ToString(), delegate(CharacterBody character, string value) { character.levelCrit = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseDamage", "float", (CharacterBody character) => character.baseDamage.ToString(), delegate(CharacterBody character, string value) { character.baseDamage = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelDamage", "float", (CharacterBody character) => character.levelDamage.ToString(), delegate(CharacterBody character, string value) { character.levelDamage = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseJumpCount", "int", (CharacterBody character) => character.baseJumpCount.ToString(), delegate(CharacterBody character, string value) { character.baseJumpCount = int.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseJumpPower", "float", (CharacterBody character) => character.baseJumpPower.ToString(), delegate(CharacterBody character, string value) { character.baseJumpPower = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelJumpPower", "float", (CharacterBody character) => character.levelJumpPower.ToString(), delegate(CharacterBody character, string value) { character.levelJumpPower = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseMaxHealth", "float", (CharacterBody character) => character.baseMaxHealth.ToString(), delegate(CharacterBody character, string value) { character.baseMaxHealth = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelMaxHealth", "float", (CharacterBody character) => character.levelMaxHealth.ToString(), delegate(CharacterBody character, string value) { character.levelMaxHealth = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseMaxShield", "float", (CharacterBody character) => character.baseMaxShield.ToString(), delegate(CharacterBody character, string value) { character.baseMaxShield = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelMaxShield", "float", (CharacterBody character) => character.levelMaxShield.ToString(), delegate(CharacterBody character, string value) { character.levelMaxShield = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseMoveSpeed", "float", (CharacterBody character) => character.baseMoveSpeed.ToString(), delegate(CharacterBody character, string value) { character.baseMoveSpeed = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelMoveSpeed", "float", (CharacterBody character) => character.levelMoveSpeed.ToString(), delegate(CharacterBody character, string value) { character.levelMoveSpeed = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("baseRegen", "float", (CharacterBody character) => character.baseRegen.ToString(), delegate(CharacterBody character, string value) { character.baseRegen = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("levelRegen", "float", (CharacterBody character) => character.levelRegen.ToString(), delegate(CharacterBody character, string value) { character.levelRegen = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("sprintingSpeedMultiplier", "float", (CharacterBody character) => character.sprintingSpeedMultiplier.ToString(), delegate(CharacterBody character, string value) { character.sprintingSpeedMultiplier = float.Parse(value); }), new Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>>("scale", "float", delegate(CharacterBody character) { //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) Vector3 localScale = ((Component)character).GetComponent<ModelLocator>().modelTransform.localScale; string text = ((object)(Vector3)(ref localScale)).ToString(); return text.Substring(1, text.Length - 2); }, delegate(CharacterBody character, string value) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) float[] array = (from x in value.Split(',') select float.Parse(x)).ToArray(); ((Component)character).GetComponent<ModelLocator>().modelTransform.localScale = new Vector3(array[0], array[1], array[2]); }) }; public static readonly List<Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>> SkillModifyableValues = new List<Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>> { new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("InterruptPriority", "interruptPriority", (SkillDef skill) => ((object)(InterruptPriority)(ref skill.interruptPriority)).ToString(), delegate(SkillDef skill, string value) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) skill.interruptPriority = SToInPr[value]; }, "Priority of the skill. Explained on webpage."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("baseRechargeInterval", "float", (SkillDef skill) => skill.baseRechargeInterval.ToString(), delegate(SkillDef skill, string value) { skill.baseRechargeInterval = float.Parse(value); }, "How long it takes for this skill to recharge after being used."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("baseMaxStock", "int", (SkillDef skill) => skill.baseMaxStock.ToString(), delegate(SkillDef skill, string value) { skill.baseMaxStock = int.Parse(value); }, "Maximum number of charges this skill can carry."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("rechargeStock", "int", (SkillDef skill) => skill.rechargeStock.ToString(), delegate(SkillDef skill, string value) { skill.rechargeStock = int.Parse(value); }, "How much stock to restore on a recharge."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("requiredStock", "int", (SkillDef skill) => skill.requiredStock.ToString(), delegate(SkillDef skill, string value) { skill.requiredStock = int.Parse(value); }, "How much stock is required to activate this skill."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("stockToConsume", "int", (SkillDef skill) => skill.stockToConsume.ToString(), delegate(SkillDef skill, string value) { skill.stockToConsume = int.Parse(value); }, "How much stock to deduct when the skill is activated."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("resetCooldownTimerOnUse", "bool", (SkillDef skill) => skill.resetCooldownTimerOnUse.ToString(), delegate(SkillDef skill, string value) { skill.resetCooldownTimerOnUse = bool.Parse(value); }, "Whether or not it resets any progress on cooldowns."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("fullRestockOnAssign", "bool", (SkillDef skill) => skill.fullRestockOnAssign.ToString(), delegate(SkillDef skill, string value) { skill.fullRestockOnAssign = bool.Parse(value); }, "Whether or not to fully restock this skill when it's assigned."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("dontAllowPastMaxStocks", "bool", (SkillDef skill) => skill.dontAllowPastMaxStocks.ToString(), delegate(SkillDef skill, string value) { skill.dontAllowPastMaxStocks = bool.Parse(value); }, "Whether or not this skill can hold past it's maximum stock."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("beginSkillCooldownOnSkillEnd", "bool", (SkillDef skill) => skill.beginSkillCooldownOnSkillEnd.ToString(), delegate(SkillDef skill, string value) { skill.beginSkillCooldownOnSkillEnd = bool.Parse(value); }, "Whether or not the cooldown waits until it leaves the set state"), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("cancelSprintingOnActivation", "bool", (SkillDef skill) => skill.cancelSprintingOnActivation.ToString(), delegate(SkillDef skill, string value) { skill.cancelSprintingOnActivation = bool.Parse(value); }, "Whether or not activating the skill forces off sprinting."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("forceSprintDuringState", "bool", (SkillDef skill) => skill.forceSprintDuringState.ToString(), delegate(SkillDef skill, string value) { skill.forceSprintDuringState = bool.Parse(value); }, "Whether or not this skill is considered 'mobility'. Currently just forces sprint."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("canceledFromSprinting", "bool", (SkillDef skill) => skill.canceledFromSprinting.ToString(), delegate(SkillDef skill, string value) { skill.canceledFromSprinting = bool.Parse(value); }, "Whether or not sprinting sets the skill's state to be reset."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("isCombatSkill", "bool", (SkillDef skill) => skill.isCombatSkill.ToString(), delegate(SkillDef skill, string value) { skill.isCombatSkill = bool.Parse(value); }, "Whether or not this is considered a combat skill. If true, will stop items like Red Whip on use."), new Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string>("mustKeyPress", "bool", (SkillDef skill) => skill.mustKeyPress.ToString(), delegate(SkillDef skill, string value) { skill.mustKeyPress = bool.Parse(value); }, "The skill can't be activated if the key is held.") }; public static readonly List<string> LunarSkills = new List<string> { "LunarPrimaryReplacement", "LunarSecondaryReplacement", "LunarUtilityReplacement", "LunarSpecialReplacement" }; } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("GiGaGon.SurvivorEnemyAndSkillCustomizer", "SurvivorEnemyAndSkillCustomizer", "1.3.0")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class SurvivorEnemyAndSkillCustomizer : BaseUnityPlugin { internal class ModConfig { public static ConfigEntry<KeyboardShortcut> reloadKeyBind; public static ConfigEntry<bool> generateConfigs; public static ConfigEntry<bool> midRunChanges; public static void InitConfig(ConfigFile config) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) reloadKeyBind = config.Bind<KeyboardShortcut>("_General", "Reload Keybind", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Keybind to press to reload the mod's configs."); generateConfigs = config.Bind<bool>("_General", "Generate Configs", true, "If disabled, new configs will not be generated. Existing configs will still function normally. Can be used to speed up load times during testing/playing."); midRunChanges = config.Bind<bool>("_General", "Mid Run Changes", true, "If enabled, the mod will attempt to make the changes mid run."); } } public const string PluginGUID = "GiGaGon.SurvivorEnemyAndSkillCustomizer"; public const string PluginAuthor = "GiGaGon"; public const string PluginName = "SurvivorEnemyAndSkillCustomizer"; public const string PluginVersion = "1.3.0"; private void Awake() { ModConfig.InitConfig(((BaseUnityPlugin)this).Config); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(AfterLoad)); } private void Update() { //IL_0006: 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) KeyboardShortcut value = ModConfig.reloadKeyBind.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Reloading Config"); ModConfig.InitConfig(((BaseUnityPlugin)this).Config); MakeChanges(); Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Reloading Finished"); } } private void AfterLoad() { Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Inital Load"); MakeChanges(); Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Loading Finished"); } private void MakeChanges() { ((BaseUnityPlugin)this).Config.Reload(); if (ModConfig.generateConfigs.Value) { Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Generating Configs"); GenerateConfigs(); Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Configs Generated"); } Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Making Changes"); ChangeValues(BodyCatalog.allBodyPrefabBodyBodyComponents); Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Changes Made"); if (Object.op_Implicit((Object)(object)Run.instance) && ModConfig.midRunChanges.Value) { Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Making Mid-Run Changes"); ChangeValues(CharacterMaster.instancesList.Select((CharacterMaster x) => x.GetBody())); Debug.Log((object)"SurvivorEnemyAndSkillCustomizer - Mid-Run Changes Made"); } ((BaseUnityPlugin)this).Config.Reload(); } public void GenerateConfigs() { foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents) { string text = RemoveIllegalChars(Language.english.GetLocalizedStringByToken(allBodyPrefabBodyBodyComponent.baseNameToken)); if (text == "") { continue; } ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>(text, text + " Enable", false, "If true, " + text + "'s configs will be generated/values will be changed."); if (!val.Value) { continue; } foreach (Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>> survivorModifyableValue in ROStuff.SurvivorModifyableValues) { ((BaseUnityPlugin)this).Config.Bind<string>(text, text + "_" + survivorModifyableValue.Item1, "Unchanged", "Type: " + survivorModifyableValue.Item2 + ", Default: " + survivorModifyableValue.Item3(allBodyPrefabBodyBodyComponent)); } foreach (SkillDef item in from x in ((Component)allBodyPrefabBodyBodyComponent).GetComponents<GenericSkill>().SelectMany((GenericSkill x) => x.skillFamily.variants) select x.skillDef) { string text2 = RemoveIllegalChars(Language.english.GetLocalizedStringByToken(item.skillNameToken)); if (text2 == "") { continue; } ConfigEntry<bool> val2 = ((BaseUnityPlugin)this).Config.Bind<bool>(text + "_" + text2, text + "_" + text2 + " Enable", false, "If true, " + text + "'s skill " + text2 + "'s configs will be generated/values will be changed."); if (!val2.Value) { continue; } foreach (Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string> skillModifyableValue in ROStuff.SkillModifyableValues) { ((BaseUnityPlugin)this).Config.Bind<string>(text + "_" + text2, text + "_" + text2 + "_" + skillModifyableValue.Item1, "Unchanged", "Type: " + skillModifyableValue.Item2 + ", Default: " + skillModifyableValue.Item3(item) + ", Description: " + skillModifyableValue.Item5); } } } string text3 = "Lunar Skills"; ConfigEntry<bool> val3 = ((BaseUnityPlugin)this).Config.Bind<bool>(text3, text3 + " Enable", false, "If true, the lunar skill replacement's configs will be generated/changed."); if (!val3.Value) { return; } foreach (SkillDef item2 in ROStuff.LunarSkills.Select((string x) => GetSkillFromToken(x))) { string text4 = RemoveIllegalChars(Language.english.GetLocalizedStringByToken(item2.skillNameToken)); if (text4 == "") { continue; } ConfigEntry<bool> val4 = ((BaseUnityPlugin)this).Config.Bind<bool>(text3 + "_" + text4, text3 + "_" + text4 + " Enable", false, "If true, " + text4 + "'s configs will be generated/values will be changed."); if (!val4.Value) { continue; } foreach (Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string> skillModifyableValue2 in ROStuff.SkillModifyableValues) { ((BaseUnityPlugin)this).Config.Bind<string>(text3 + "_" + text4, text3 + "_" + text4 + "_" + skillModifyableValue2.Item1, "Unchanged", "Type: " + skillModifyableValue2.Item2 + ", Default: " + skillModifyableValue2.Item3(item2) + ", Description: " + skillModifyableValue2.Item5); } } } public void ChangeValues(IEnumerable<CharacterBody> characterBodies) { ConfigEntry<bool> val = default(ConfigEntry<bool>); ConfigEntry<string> val2 = default(ConfigEntry<string>); ConfigEntry<bool> val3 = default(ConfigEntry<bool>); ConfigEntry<string> val4 = default(ConfigEntry<string>); foreach (CharacterBody characterBody in characterBodies) { string text = RemoveIllegalChars(Language.english.GetLocalizedStringByToken(characterBody.baseNameToken)); if (text == "" || !((BaseUnityPlugin)this).Config.TryGetEntry<bool>(text, text + " Enable", ref val) || !val.Value) { continue; } foreach (Tuple<string, string, Func<CharacterBody, string>, Action<CharacterBody, string>> survivorModifyableValue in ROStuff.SurvivorModifyableValues) { if (((BaseUnityPlugin)this).Config.TryGetEntry<string>(text, text + "_" + survivorModifyableValue.Item1, ref val2) && val2.Value != "Unchanged") { Debug.Log((object)("SurvivorEnemyAndSkillCustomizer - Changing " + text + "_" + survivorModifyableValue.Item1 + " to " + val2.Value)); survivorModifyableValue.Item4(characterBody, val2.Value); } } foreach (SkillDef item in from x in ((Component)characterBody).GetComponents<GenericSkill>().SelectMany((GenericSkill x) => x.skillFamily.variants) select x.skillDef) { string text2 = RemoveIllegalChars(Language.english.GetLocalizedStringByToken(item.skillNameToken)); if (text2 == "" || !((BaseUnityPlugin)this).Config.TryGetEntry<bool>(text + "_" + text2, text + "_" + text2 + " Enable", ref val3) || !val3.Value) { continue; } foreach (Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string> skillModifyableValue in ROStuff.SkillModifyableValues) { if (((BaseUnityPlugin)this).Config.TryGetEntry<string>(text + "_" + text2, text + "_" + text2 + "_" + skillModifyableValue.Item1, ref val4) && val4.Value != "Unchanged") { Debug.Log((object)("SurvivorEnemyAndSkillCustomizer - Changing " + text + "_" + text2 + "_" + skillModifyableValue.Item1 + " to " + val4.Value)); skillModifyableValue.Item4(item, val4.Value); } } } } string text3 = "Lunar Skills"; ConfigEntry<bool> val5 = default(ConfigEntry<bool>); if (!((BaseUnityPlugin)this).Config.TryGetEntry<bool>(text3, text3 + " Enable", ref val5) || !val5.Value) { return; } ConfigEntry<bool> val6 = default(ConfigEntry<bool>); ConfigEntry<string> val7 = default(ConfigEntry<string>); foreach (SkillDef item2 in ROStuff.LunarSkills.Select(GetSkillFromToken)) { string text4 = RemoveIllegalChars(Language.english.GetLocalizedStringByToken(item2.skillNameToken)); if (text4 == "" || !((BaseUnityPlugin)this).Config.TryGetEntry<bool>(text3 + "_" + text4, text3 + "_" + text4 + " Enable", ref val6) || !val6.Value) { continue; } foreach (Tuple<string, string, Func<SkillDef, string>, Action<SkillDef, string>, string> skillModifyableValue2 in ROStuff.SkillModifyableValues) { if (((BaseUnityPlugin)this).Config.TryGetEntry<string>(text3 + "_" + text4, text3 + "_" + text4 + "_" + skillModifyableValue2.Item1, ref val7) && val7.Value != "Unchanged") { Debug.Log((object)("SurvivorEnemyAndSkillCustomizer - Changing " + text3 + "_" + text4 + "_" + skillModifyableValue2.Item1 + " to " + val7.Value)); skillModifyableValue2.Item4(item2, val7.Value); } } } } public string RemoveIllegalChars(string input) { return Regex.Replace(input, "[^\\w]", ""); } public SkillDef GetSkillFromToken(string input) { return SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName(input)); } } }