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 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; } } } }