Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of GeneticArtifact v4.5.3
GeneticsArtifact.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using On.RoR2; using R2API; using R2API.ScriptableObjects; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("GeneticsArtifact")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GeneticsArtifact")] [assembly: AssemblyTitle("GeneticsArtifact")] [assembly: AssemblyVersion("1.0.0.0")] namespace GeneticsArtifact; public class ArtifactOfGenetics { public static ArtifactDef artifactDef; public static ArtifactCode artifactCode; public static ArtifactCompoundDef geneArtifactCompoundDef; internal static void Init() { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) LanguageAPI.Add("GENETIC_ARTIFACT_NAME_TOKEN", "Artifact of Genetics"); LanguageAPI.Add("GENETIC_ARTIFACT_DESCRIPTION_TOKEN", "Monsters will spawn with adjusted stats. Adjustments are determined by a genetic algorithm."); artifactDef = ScriptableObject.CreateInstance<ArtifactDef>(); artifactDef.nameToken = "GENETIC_ARTIFACT_NAME_TOKEN"; artifactDef.descriptionToken = "GENETIC_ARTIFACT_DESCRIPTION_TOKEN"; artifactDef.smallIconSelectedSprite = GeneticsArtifactPlugin.geneticAssetBundle.LoadAsset<Sprite>("Assets/Genetics/Selected.png"); artifactDef.smallIconDeselectedSprite = GeneticsArtifactPlugin.geneticAssetBundle.LoadAsset<Sprite>("Assets/Genetics/Unselected.png"); artifactDef.pickupModelPrefab = GeneticsArtifactPlugin.geneticAssetBundle.LoadAsset<GameObject>("Assets/Genetics/PickupGene.prefab"); ContentAddition.AddArtifactDef(artifactDef); geneArtifactCompoundDef = ScriptableObject.CreateInstance<ArtifactCompoundDef>(); geneArtifactCompoundDef.modelPrefab = GeneticsArtifactPlugin.geneticAssetBundle.LoadAsset<GameObject>("Assets/Genetics/CompoundGene.prefab"); geneArtifactCompoundDef.value = 15; ArtifactCodeAPI.AddCompound(geneArtifactCompoundDef); artifactCode = ScriptableObject.CreateInstance<ArtifactCode>(); artifactCode.topRow = new Vector3Int(3, 5, 3); artifactCode.middleRow = new Vector3Int(1, geneArtifactCompoundDef.value, 1); artifactCode.bottomRow = new Vector3Int(3, 5, 3); ArtifactCodeAPI.AddCode(artifactDef, artifactCode); } } public class ConfigManager { public static ConfigEntry<int> timeLimit; public static ConfigEntry<int> deathLimit; public static ConfigEntry<int> governorType; public static ConfigEntry<float> geneVarianceLimit; public static ConfigEntry<float> geneCap; public static ConfigEntry<float> geneFloor; public static ConfigEntry<float> geneProductLimit; public static ConfigEntry<bool> maintainIfDisabled; public static ConfigEntry<bool> enableGeneLimitOverrides; public static ConfigEntry<string> geneLimitOverrides; public static void Init(ConfigFile configFile) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_002c: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0062: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_0096: Expected O, but got Unknown //IL_00a6: 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: Expected O, but got Unknown //IL_00cf: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_010c: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0149: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_0186: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Expected O, but got Unknown //IL_01c3: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_01fc: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown //IL_022b: Expected O, but got Unknown governorType = configFile.Bind<int>(new ConfigDefinition("GeneEngineDriver Variables", "Learning Governor Type"), 0, new ConfigDescription("How the algorithm decides when to learn: 0 - Default, 1 - Time Only, 2 - Death Count Only", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); timeLimit = configFile.Bind<int>(new ConfigDefinition("GeneEngineDriver Variables", "Time Limit"), 60, new ConfigDescription("How many seconds between learnings:", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 300), Array.Empty<object>())); deathLimit = configFile.Bind<int>(new ConfigDefinition("GeneEngineDriver Variables", "Death Limit"), 40, new ConfigDescription("How many monster deaths between learnings:", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())); maintainIfDisabled = configFile.Bind<bool>(new ConfigDefinition("GeneEngineDriver Variables", "Keep Mutations While Disabled"), false, new ConfigDescription("Should the stat mods still be applied if the artifact is disabled mid-run:", (AcceptableValueBase)(object)new AcceptableValueList<bool>(new bool[2] { true, false }), Array.Empty<object>())); geneCap = configFile.Bind<float>(new ConfigDefinition("Mutation Variables", "Gene Value Cap"), 10f, new ConfigDescription("Maximum multiplier for any stat:", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); geneFloor = configFile.Bind<float>(new ConfigDefinition("Mutation Variables", "Gene Value Floor"), 0.01f, new ConfigDescription("Minimum multiplier for any stat:", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>())); geneProductLimit = configFile.Bind<float>(new ConfigDefinition("Mutation Variables", "Gene Product Cap"), 1.5f, new ConfigDescription("Maximum product of all stat multipliers:", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); geneVarianceLimit = configFile.Bind<float>(new ConfigDefinition("Mutation Variables", "Gene Variation Limit"), 0.1f, new ConfigDescription("How much a monster can differ from it`s master as a percent: 0.1 is 10% (Bulwark will be 5x this)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>())); enableGeneLimitOverrides = configFile.Bind<bool>(new ConfigDefinition("Mutation Override Variables", "Enable Mutation Overrides"), false, new ConfigDescription("Should the mutation overrides be applied, use with caution", (AcceptableValueBase)(object)new AcceptableValueList<bool>(new bool[2] { true, false }), Array.Empty<object>())); geneLimitOverrides = configFile.Bind<string>(new ConfigDefinition("Mutation Override Variables", "Gene Limit Overrides"), "MoveSpeed,0.5,2|InvalidName,0.8,NaN", new ConfigDescription("Format is as follows: GeneName1,Floor1,Cap1|GeneName2,Floor2,Cap2 where GeneName is in (MaxHealth,MoveSpeed,AttackSpeed,AttackDamage) and Floor and Cap are parseable numerics", (AcceptableValueBase)null, Array.Empty<object>())); } } public enum GovernorType { Default, TimeOnly, DeathsOnly } public class RiskOfOptionsCompat { public static void Init() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown ModSettingsManager.SetModIcon(ArtifactOfGenetics.artifactDef.smallIconSelectedSprite); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ConfigManager.governorType, new IntSliderConfig { min = 0, max = 2 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ConfigManager.timeLimit, new IntSliderConfig { min = 5, max = 300 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ConfigManager.deathLimit, new IntSliderConfig { min = 10, max = 100 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ConfigManager.maintainIfDisabled)); ModSettingsManager.AddOption((BaseOption)new SliderOption(ConfigManager.geneCap, new SliderConfig { min = 1f, max = 50f, formatString = "{0:#0.##}x" })); ModSettingsManager.AddOption((BaseOption)new SliderOption(ConfigManager.geneFloor, new SliderConfig { min = 0.01f, max = 1f, formatString = "{0:0.##}x" })); ModSettingsManager.AddOption((BaseOption)new SliderOption(ConfigManager.geneProductLimit, new SliderConfig { min = 1f, max = 10f, formatString = "{0:#0.##}x" })); ModSettingsManager.AddOption((BaseOption)new SliderOption(ConfigManager.geneVarianceLimit, new SliderConfig { min = 0.01f, max = 1f, formatString = "{0:#0.##%}" })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ConfigManager.enableGeneLimitOverrides)); ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(ConfigManager.geneLimitOverrides)); } } public class GeneEngineDriver : NetworkBehaviour { public static GeneEngineDriver instance; public static List<MasterGeneBehaviour> masterGenes; public static List<MonsterGeneBehaviour> livingGenes; public static List<MonsterGeneBehaviour> deadGenes; public static float timeSinceLastLearning; public static Dictionary<GeneStat, (float, float)> geneLimitOverrides; public event EventHandler GEDPostLearningEvent; public static void RegisterHooks() { //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 Run.Start += new hook_Start(Run_Start); CharacterBody.Start += new hook_Start(CharacterBody_Start); HealthComponent.TakeDamage += new hook_TakeDamage(HealthComponent_TakeDamage); } private static void Run_Start(orig_Start orig, Run self) { orig.Invoke(self); if (NetworkServer.active && RunArtifactManager.instance.IsArtifactEnabled(ArtifactOfGenetics.artifactDef)) { ((Component)self).gameObject.AddComponent<GeneEngineDriver>(); } } private static void CharacterBody_Start(orig_Start orig, CharacterBody self) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Invalid comparison between Unknown and I4 //IL_00c5: 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_00ea: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (!NetworkServer.active || (!RunArtifactManager.instance.IsArtifactEnabled(ArtifactOfGenetics.artifactDef) && !ConfigManager.maintainIfDisabled.Value)) { return; } if ((Object)(object)instance == (Object)null) { ((Component)Run.instance).gameObject.AddComponent<GeneEngineDriver>(); GeneticsArtifactPlugin.geneticLogSource.LogWarning((object)"GeneEngineDriver Emergency Activation! Wasn't ready for a body yet."); } if ((int)self.teamComponent.teamIndex == 2 && Object.op_Implicit((Object)(object)self.inventory)) { if (!masterGenes.Exists((MasterGeneBehaviour x) => x.bodyIndex == self.bodyIndex)) { MasterGeneBehaviour masterGeneBehaviour = new MasterGeneBehaviour(); masterGeneBehaviour.Init(); masterGeneBehaviour.bodyIndex = self.bodyIndex; masterGenes.Add(masterGeneBehaviour); GeneticsArtifactPlugin.geneticLogSource.LogInfo((object)("Generated a Master Template for: " + BodyCatalog.GetBodyName(self.bodyIndex))); } MonsterGeneBehaviour monsterGeneBehaviour = ((Component)self).gameObject.AddComponent<MonsterGeneBehaviour>(); if (RunArtifactManager.instance.IsArtifactEnabled(ArtifactOfGenetics.artifactDef)) { monsterGeneBehaviour.MutateFromMaster(); monsterGeneBehaviour.characterBody.RecalculateStats(); } else { monsterGeneBehaviour.CopyFromMaster(); } } } private static void HealthComponent_TakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo) { orig.Invoke(self, damageInfo); if (!NetworkServer.active || !RunArtifactManager.instance.IsArtifactEnabled(ArtifactOfGenetics.artifactDef)) { return; } GameObject attacker = damageInfo.attacker; if (attacker != null) { if (!((Object)(object)attacker != (Object)null)) { return; } CharacterBody attackerBody = attacker.GetComponent<CharacterBody>(); if (attackerBody == null || !((Object)(object)attackerBody != (Object)null)) { return; } Inventory inventory = attackerBody.inventory; if (inventory != null && inventory.GetItemCount(GeneTokens.blockerDef) == 0) { MonsterGeneBehaviour monsterGeneBehaviour = livingGenes.Find((MonsterGeneBehaviour x) => (Object)(object)x.characterBody == (Object)(object)attackerBody); if ((Object)(object)monsterGeneBehaviour != (Object)null) { monsterGeneBehaviour.damageDealt += damageInfo.damage; } } return; } GameObject inflictor = damageInfo.inflictor; if (inflictor == null) { return; } if (!((Object)(object)inflictor != (Object)null)) { return; } CharacterBody inflictorBody = inflictor.GetComponent<CharacterBody>(); if (inflictorBody == null || !((Object)(object)inflictorBody != (Object)null)) { return; } Inventory inventory2 = inflictorBody.inventory; if (inventory2 != null && inventory2.GetItemCount(GeneTokens.blockerDef) == 0) { MonsterGeneBehaviour monsterGeneBehaviour2 = livingGenes.Find((MonsterGeneBehaviour x) => (Object)(object)x.characterBody == (Object)(object)inflictorBody); if ((Object)(object)monsterGeneBehaviour2 != (Object)null) { monsterGeneBehaviour2.damageDealt += damageInfo.damage; } } } public void Awake() { if ((Object)(object)instance == (Object)null) { instance = this; } if (NetworkServer.active) { masterGenes = new List<MasterGeneBehaviour>(); livingGenes = new List<MonsterGeneBehaviour>(); deadGenes = new List<MonsterGeneBehaviour>(); RegenerateGeneLimitOverrides(); } } public void Update() { if (!NetworkServer.active) { return; } timeSinceLastLearning += Time.deltaTime; switch (ConfigManager.governorType.Value) { case 1: if (timeSinceLastLearning >= (float)ConfigManager.timeLimit.Value) { Learn(); } break; case 2: if (deadGenes.Count >= ConfigManager.deathLimit.Value) { Learn(); } break; default: if (timeSinceLastLearning >= (float)ConfigManager.timeLimit.Value || deadGenes.Count >= ConfigManager.deathLimit.Value) { Learn(); } break; } } public void Learn() { foreach (MasterGeneBehaviour masterGene in masterGenes) { masterGene.MutateFromChildren(); } deadGenes.Clear(); timeSinceLastLearning = 0f; this.GEDPostLearningEvent?.Invoke(this, new EventArgs()); } public void RegenerateGeneLimitOverrides() { geneLimitOverrides = new Dictionary<GeneStat, (float, float)>(); if (!ConfigManager.enableGeneLimitOverrides.Value || string.IsNullOrEmpty(ConfigManager.geneLimitOverrides.Value)) { return; } string[] array = ConfigManager.geneLimitOverrides.Value.Trim().Split(new char[1] { '|' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ',' }); if (Enum.TryParse<GeneStat>(array2[0], ignoreCase: true, out var result) && float.TryParse(array2[1], out var result2) && result2 <= 1f && float.TryParse(array2[2], out var result3) && result3 >= 1f) { try { geneLimitOverrides.Add(result, (result2, result3)); GeneticsArtifactPlugin.geneticLogSource.LogInfo((object)("Adding Valid GeneOverride: " + text)); } catch { goto IL_00ce; } continue; } goto IL_00ce; IL_00ce: GeneticsArtifactPlugin.geneticLogSource.LogWarning((object)("Skipping Invalid GeneOverride: " + text)); } } } public class GeneTokenCalc { public static void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(RecalculateStatsAPI_GetStatCoefficients); } private static void RecalculateStatsAPI_GetStatCoefficients(CharacterBody sender, StatHookEventArgs args) { Inventory inventory = sender.inventory; if (inventory != null && inventory.GetItemCount(GeneTokens.blockerDef) == 0) { args.baseHealthAdd += GetStatValueToAdd(sender, GeneStat.MaxHealth); args.baseMoveSpeedAdd += GetStatValueToAdd(sender, GeneStat.MoveSpeed); args.baseAttackSpeedAdd += GetStatValueToAdd(sender, GeneStat.AttackSpeed); args.baseDamageAdd += GetStatValueToAdd(sender, GeneStat.AttackDamage); } } public static float GetGeneMultiplier(CharacterBody body, GeneStat statType) { float num = 0.01f; Inventory inventory = body.inventory; float num2 = 1f + (num * (float?)((inventory != null) ? new int?(inventory.GetItemCount(GeneTokens.tokenDict[statType][GeneMod.Plus1])) : null)).GetValueOrDefault(); num = 0.01f; Inventory inventory2 = body.inventory; return num2 - (num * (float?)((inventory2 != null) ? new int?(inventory2.GetItemCount(GeneTokens.tokenDict[statType][GeneMod.Minus1])) : null)).GetValueOrDefault(); } public static float GetStatValueToAdd(CharacterBody body, GeneStat statType) { float num = 0f; switch (statType) { case GeneStat.MaxHealth: num = body.baseMaxHealth + body.levelMaxHealth * body.level; break; case GeneStat.MoveSpeed: num = body.baseMoveSpeed + body.levelMoveSpeed * body.level; break; case GeneStat.AttackSpeed: num = body.baseAttackSpeed + body.levelAttackSpeed * body.level; break; case GeneStat.AttackDamage: num = body.baseDamage + body.levelDamage * body.level; break; } return num * GetGeneMultiplier(body, statType) - num; } public static Dictionary<ItemDef, int> GetTokensToAdd(Dictionary<GeneStat, float> oldValues, Dictionary<GeneStat, float> newValues) { Dictionary<ItemDef, int> dictionary = new Dictionary<ItemDef, int>(); Dictionary<GeneStat, float> dictionary2 = new Dictionary<GeneStat, float>(); foreach (GeneStat value in Enum.GetValues(typeof(GeneStat))) { dictionary2.Add(value, newValues[value] - oldValues[value]); } foreach (GeneStat value2 in Enum.GetValues(typeof(GeneStat))) { if (dictionary2[value2] > 0f) { dictionary.Add(GeneTokens.tokenDict[value2][GeneMod.Plus1], (int)(dictionary2[value2] * 100f)); } else { dictionary.Add(GeneTokens.tokenDict[value2][GeneMod.Minus1], (int)(dictionary2[value2] * -100f)); } } return dictionary; } } public class GeneTokens { public static Dictionary<GeneStat, Dictionary<GeneMod, ItemDef>> tokenDict; public static ItemDef blockerDef; public static void Init() { LanguageAPI.Add("GENETIC_EMPTY_TOKEN", "This is better than null I guess"); tokenDict = new Dictionary<GeneStat, Dictionary<GeneMod, ItemDef>>(); foreach (GeneStat value in Enum.GetValues(typeof(GeneStat))) { tokenDict.Add(value, new Dictionary<GeneMod, ItemDef>()); foreach (GeneMod value2 in Enum.GetValues(typeof(GeneMod))) { ItemDef val = ScriptableObject.CreateInstance<ItemDef>(); ((Object)val).name = "GENETOKEN_" + value.ToString().ToUpper() + "_" + value2.ToString().ToUpper(); val.nameToken = "GENETIC_EMPTY_TOKEN"; val.pickupToken = "GENETIC_EMPTY_TOKEN"; val.descriptionToken = "GENETIC_EMPTY_TOKEN"; val.loreToken = "GENETIC_EMPTY_TOKEN"; val.pickupIconSprite = null; val.pickupModelPrefab = null; val.tags = (ItemTag[])(object)new ItemTag[2] { (ItemTag)13, (ItemTag)12 }; Reflection.SetFieldValue<ItemTier>((object)val, "deprecatedTier", (ItemTier)5); val.hidden = true; val.canRemove = false; ContentAddition.AddItemDef(val); tokenDict[value].Add(value2, val); } } blockerDef = ScriptableObject.CreateInstance<ItemDef>(); ((Object)blockerDef).name = "GENETOKEN_BLOCKER"; blockerDef.nameToken = "GENETIC_EMPTY_TOKEN"; blockerDef.pickupToken = "GENETIC_EMPTY_TOKEN"; blockerDef.descriptionToken = "GENETIC_EMPTY_TOKEN"; blockerDef.loreToken = "GENETIC_EMPTY_TOKEN"; blockerDef.pickupIconSprite = null; blockerDef.pickupModelPrefab = null; blockerDef.tags = (ItemTag[])(object)new ItemTag[2] { (ItemTag)13, (ItemTag)12 }; Reflection.SetFieldValue<ItemTier>((object)blockerDef, "deprecatedTier", (ItemTier)5); blockerDef.hidden = true; blockerDef.canRemove = false; ContentAddition.AddItemDef(blockerDef); } } public enum GeneStat { MaxHealth, MoveSpeed, AttackSpeed, AttackDamage } public enum GeneMod { Plus1, Minus1 } public class MasterGeneBehaviour { public BodyIndex bodyIndex; public Dictionary<GeneStat, float> templateGenes; public event EventHandler MaGBPostCreationEvent; public event EventHandler MaGBPostMutationEvent; public void Init() { templateGenes = new Dictionary<GeneStat, float>(); foreach (GeneStat value in Enum.GetValues(typeof(GeneStat))) { templateGenes.Add(value, 1f); } this.MaGBPostCreationEvent?.Invoke(this, new EventArgs()); } public void MutateFromChildren() { List<MonsterGeneBehaviour> list = GeneEngineDriver.deadGenes.Where((MonsterGeneBehaviour x) => x.bodyIndex == bodyIndex && x.score > 0f).ToList(); foreach (GeneStat value in Enum.GetValues(typeof(GeneStat))) { float num = 0f; float num2 = 0f; foreach (MonsterGeneBehaviour item in list) { num2 += item.currentGenes[value] * item.score; num += item.score; } if (num > 0f) { templateGenes[value] = (float)decimal.Round((decimal)(num2 / num), 2); } } this.MaGBPostMutationEvent?.Invoke(this, new EventArgs()); } } public class MonsterGeneBehaviour : MonoBehaviour { public BodyIndex bodyIndex; public Dictionary<GeneStat, float> currentGenes; public CharacterBody characterBody; public float timeAlive; public float timeEngaged; public float damageDealt; public float score; public event EventHandler MoGBPostMutationEvent; public event EventHandler MoGBPostScoringEvent; public void Awake() { //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) characterBody = ((Component)this).gameObject.GetComponent<CharacterBody>(); bodyIndex = characterBody.bodyIndex; InitializeCurrentGenes(); GeneEngineDriver.livingGenes.Add(this); } public void Update() { timeAlive += Time.deltaTime; if (!characterBody.outOfCombat) { timeEngaged += Time.deltaTime; } } public void MutateFromMaster() { CopyFromMaster(); MutateSelf(); } public void CopyFromMaster() { MasterGeneBehaviour masterGeneBehaviour = GeneEngineDriver.masterGenes.Find((MasterGeneBehaviour x) => x.bodyIndex == bodyIndex); AdaptToNewGenes(masterGeneBehaviour.templateGenes); } public void MutateSelf() { Dictionary<GeneStat, float> attempt = GenerateMutationAttempt(); attempt = CorrectOvermutation(attempt); AdaptToNewGenes(attempt); this.MoGBPostMutationEvent?.Invoke(this, new EventArgs()); } private Dictionary<GeneStat, float> CorrectOvermutation(Dictionary<GeneStat, float> attempt) { while (CalculateGeneProduct(attempt) > ConfigManager.geneProductLimit.Value) { attempt[attempt.Aggregate((KeyValuePair<GeneStat, float> x, KeyValuePair<GeneStat, float> y) => (!(x.Value > y.Value)) ? y : x).Key] -= 0.05f; } return attempt; } private float CalculateGeneProduct(Dictionary<GeneStat, float> testValues) { float num = 1f; foreach (float value in testValues.Values) { num *= value; } return num; } public void LogDebugInfo() { GeneticsArtifactPlugin.geneticLogSource.LogInfo((object)(Stage.instance.sceneDef.baseSceneName + " " + ((Object)characterBody).name + " " + currentGenes[GeneStat.MaxHealth] + " " + currentGenes[GeneStat.MoveSpeed] + " " + currentGenes[GeneStat.AttackSpeed] + " " + currentGenes[GeneStat.AttackDamage])); } private void InitializeCurrentGenes() { currentGenes = new Dictionary<GeneStat, float>(); foreach (GeneStat value in Enum.GetValues(typeof(GeneStat))) { currentGenes.Add(value, 1f); } } public void AdaptToNewGenes(Dictionary<GeneStat, float> newGenes) { foreach (KeyValuePair<ItemDef, int> item in GeneTokenCalc.GetTokensToAdd(currentGenes, newGenes)) { characterBody.inventory.GiveItem(item.Key, item.Value); } currentGenes = newGenes; } private Dictionary<GeneStat, float> GenerateMutationAttempt() { Dictionary<GeneStat, float> dictionary = new Dictionary<GeneStat, float>(); float num = ConfigManager.geneVarianceLimit.Value * (float)((!(Stage.instance.sceneDef.baseSceneName == "artifactworld")) ? 1 : 5); foreach (GeneStat key in currentGenes.Keys) { float num2 = currentGenes[key]; if (ConfigManager.enableGeneLimitOverrides.Value && GeneEngineDriver.geneLimitOverrides.ContainsKey(key)) { dictionary.Add(key, (float)decimal.Round((decimal)Mathf.Clamp(Random.Range(num2 * (1f - num), num2 * (1f + num)), GeneEngineDriver.geneLimitOverrides[key].Item1, GeneEngineDriver.geneLimitOverrides[key].Item2), 2)); } else { dictionary.Add(key, (float)decimal.Round((decimal)Mathf.Clamp(Random.Range(num2 * (1f - num), num2 * (1f + num)), ConfigManager.geneFloor.Value, ConfigManager.geneCap.Value), 2)); } } return dictionary; } private void OnDestroy() { ScoreMe(); GeneEngineDriver.livingGenes.Remove(this); GeneEngineDriver.deadGenes.Add(this); } public float ScoreMe() { score = 0f; if (timeAlive > 0f && timeEngaged > 0f) { float num = timeEngaged / timeAlive; score = damageDealt * num; } this.MoGBPostScoringEvent?.Invoke(this, new EventArgs()); return score; } } [BepInPlugin("com.RicoValdezio.ArtifactOfGenetics", "Genetics", "4.5.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [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 class GeneticsArtifactPlugin : BaseUnityPlugin { public const string ModVer = "4.5.3"; public const string ModName = "Genetics"; public const string ModGuid = "com.RicoValdezio.ArtifactOfGenetics"; public static GeneticsArtifactPlugin Instance; public static ManualLogSource geneticLogSource; public static AssetBundle geneticAssetBundle; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } geneticLogSource = ((BaseUnityPlugin)Instance).Logger; geneticAssetBundle = AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("GeneticsArtifact.ArtifactResources.genetics")); ConfigManager.Init(((BaseUnityPlugin)this).Config); ArtifactOfGenetics.Init(); GeneTokens.Init(); GeneTokenCalc.RegisterHooks(); GeneEngineDriver.RegisterHooks(); foreach (PluginInfo value in Chainloader.PluginInfos.Values) { if (value.Metadata.GUID.Equals("com.rune580.riskofoptions")) { RiskOfOptionsCompat.Init(); break; } } } }