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 BiomeDifficultyProgression v1.6.0
plugins/BiomeDifficultyProgression.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("BiomeDifficultyProgression")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BiomeDifficultyProgression")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("78588f74-9b2d-4a5e-b1d1-3c436e80467a")] [assembly: AssemblyFileVersion("1.6.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.6.0.0")] namespace BiomeDifficultyProgression; [BepInPlugin("BiomeDifficultyProgression", "Biome Difficulty Progression", "1.6.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class BiomeDifficultyProgression : BaseUnityPlugin { public enum ModifierType { BASE_DAMAGE, FINAL_DAMAGE, HEALTH } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class Character_ApplyDamage_Patch { public static void Prefix(HitData hit) { Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker == (Object)null) && !(attacker is Player) && (Configs.enable_modifiers_for_tamed_creatures.Value || !attacker.IsTamed())) { string biomeName; float modifier = GetModifier(ModifierType.FINAL_DAMAGE, attacker, out biomeName); if (modifier != 1f) { hit.ApplyModifier(modifier); } } } } [HarmonyPatch(typeof(Character), "SetupMaxHealth", null)] [HarmonyPriority(0)] private static class Character_SetupMaxHealth_Patch { private static void Postfix(Character __instance) { ApplyModifier(ModifierType.HEALTH, __instance); } } [HarmonyPatch(typeof(Humanoid), "GiveDefaultItems", null)] public static class Humanoid_GiveDefaultItems_Patch { public static void Postfix(Humanoid __instance, Inventory ___m_inventory) { ApplyModifier(ModifierType.BASE_DAMAGE, (Character)(object)__instance, ___m_inventory); } } public const string PluginVersion = "1.6.0"; private Harmony harmony = new Harmony("BiomeDifficultyProgression"); public static Dictionary<string, CustomModifier> CustomModifiers = new Dictionary<string, CustomModifier>(); private void Awake() { Configs.SetupConfigs(((BaseUnityPlugin)this).Config); harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "BiomeDifficultyProgression"); UpdateCustomModifiers(); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } } public static void UpdateCustomModifiers() { CustomModifiers.Clear(); if (Configs.custom_modifiers.Value == null || Configs.custom_modifiers.Value.Length <= 0) { return; } string[] array = Configs.custom_modifiers.Value.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Trim().Split(new char[1] { ':' }); if (array2.Length != 4) { ZLog.LogError((object)"BiomeDifficultyProgression: Custom Modifiers not in the expected format. Please see the documentation and adhere to the correct format."); CustomModifiers.Clear(); return; } string text = array2[0].Trim(); int result = 0; int result2 = 0; int result3 = 0; bool flag = int.TryParse(array2[1].Trim(), out result) && int.TryParse(array2[2].Trim(), out result2) && int.TryParse(array2[3].Trim(), out result3); if (text.Length == 0 || !flag || CustomModifiers.ContainsKey(text)) { ZLog.LogError((object)"BiomeDifficultyProgression: Custom Modifiers not in the expected format. Please see the documentation and adhere to the correct format."); CustomModifiers.Clear(); return; } if (result <= 0 || result3 <= 0 || result2 <= 0) { ZLog.LogError((object)"BiomeDifficultyProgression: Base damage, final damage and health modifiers in custom modifiers cannot be equal or lower than 0."); CustomModifiers.Clear(); return; } CustomModifiers.Add(text, new CustomModifier((float)result / 100f, (float)result2 / 100f, (float)result3 / 100f)); } ZLog.Log((object)"BiomeDifficultyProgression: Custom modifiers updated successfully."); } public static void ApplyModifier(ModifierType modifierType, Character character, Inventory inventory = null) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) if (character is Player || (!Configs.enable_modifiers_for_tamed_creatures.Value && character.IsTamed())) { return; } switch (modifierType) { case ModifierType.HEALTH: { string biomeName2; float modifier2 = GetModifier(ModifierType.HEALTH, character, out biomeName2); if (modifier2 != 1f) { character.SetMaxHealth(character.GetMaxHealth() * modifier2); if (Configs.enable_debug_logs.Value) { ZLog.Log((object)$"BiomeDifficultyProgression: Creature Updated - Name: {character.m_name}, ZDO ID: {character.GetZDOID()}, Biome: {biomeName2}, Level: {character.GetLevel()}, Max Health: {character.GetMaxHealth()}, Base Health: {Mathf.RoundToInt(modifier2 * 100f)}%"); } } break; } case ModifierType.BASE_DAMAGE: { if (inventory == null || inventory.NrOfItems() <= 0) { break; } string biomeName; float modifier = GetModifier(ModifierType.BASE_DAMAGE, character, out biomeName); if (modifier == 1f) { break; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.IsWeapon()) { allItem.m_shared.m_damages.m_blunt *= modifier; allItem.m_shared.m_damages.m_pierce *= modifier; allItem.m_shared.m_damages.m_slash *= modifier; allItem.m_shared.m_damages.m_fire *= modifier; allItem.m_shared.m_damages.m_frost *= modifier; allItem.m_shared.m_damages.m_lightning *= modifier; allItem.m_shared.m_damages.m_poison *= modifier; allItem.m_shared.m_damages.m_spirit *= modifier; } } if (Configs.enable_debug_logs.Value) { ZLog.Log((object)$"BiomeDifficultyProgression: Creature Updated - Name: {character.m_name}, ZDO ID: {character.GetZDOID()}, Biome: {biomeName}, Level: {character.GetLevel()}, Base Damage: {Mathf.RoundToInt(modifier * 100f)}%"); } break; } } } public unsafe static float GetModifier(ModifierType modifierType, Character character, out string biomeName) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_00ab: Unknown result type (might be due to invalid IL or missing references) biomeName = "N/A"; float num = 1f; string prefabName = Utils.GetPrefabName(((Component)character).gameObject); if (CustomModifiers.ContainsKey(prefabName)) { switch (modifierType) { case ModifierType.BASE_DAMAGE: num = CustomModifiers[prefabName].BaseDamageModifier; break; case ModifierType.FINAL_DAMAGE: num = CustomModifiers[prefabName].FinalDamageModifier; break; case ModifierType.HEALTH: num = CustomModifiers[prefabName].HealthModifier; break; } } else { Biome key = Heightmap.FindBiome(((Component)character).transform.position); if (Configs.BiomeInfoDictionary.ContainsKey(key)) { biomeName = ((object)(*(Biome*)(&key))/*cast due to .constrained prefix*/).ToString(); Configs.BiomeInfo biomeInfo = Configs.BiomeInfoDictionary[key]; if (modifierType == ModifierType.BASE_DAMAGE && biomeInfo.base_damage_modifier.Value != 100) { num = (float)biomeInfo.base_damage_modifier.Value / 100f; } else { switch (modifierType) { case ModifierType.FINAL_DAMAGE: num = (float)biomeInfo.final_damage_modifier.Value / 100f; break; case ModifierType.HEALTH: if (biomeInfo.health_modifier.Value != 100) { num = (float)biomeInfo.health_modifier.Value / 100f; } break; } } } } switch (modifierType) { case ModifierType.BASE_DAMAGE: if (Configs.dungeon_base_damage_modifier.Value != 100 && character.InInterior() && !character.IsBoss()) { num *= (float)Configs.dungeon_base_damage_modifier.Value / 100f; } if (Configs.global_base_damage_modifier.Value != 100) { num *= (float)Configs.global_base_damage_modifier.Value / 100f; } break; case ModifierType.FINAL_DAMAGE: if (character.InInterior() && !character.IsBoss()) { num *= (float)Configs.dungeon_final_damage_modifier.Value / 100f; } num *= (float)Configs.global_final_damage_modifier.Value / 100f; break; case ModifierType.HEALTH: if (Configs.dungeon_health_modifier.Value != 100 && character.InInterior() && !character.IsBoss()) { num *= (float)Configs.dungeon_health_modifier.Value / 100f; } if (Configs.global_health_modifier.Value != 100) { num *= (float)Configs.global_health_modifier.Value / 100f; } break; } return num; } } public static class Configs { public class BiomeInfo { public ConfigEntry<int> base_damage_modifier; public ConfigEntry<int> final_damage_modifier; public ConfigEntry<int> health_modifier; } public static readonly string[] BIOMES_TO_BE_IGNORED = new string[2] { "None", "All" }; public static Dictionary<Biome, BiomeInfo> BiomeInfoDictionary = new Dictionary<Biome, BiomeInfo>(); public static ConfigEntry<bool> enable_debug_logs; public static ConfigEntry<bool> enable_modifiers_for_tamed_creatures; public static ConfigEntry<int> dungeon_base_damage_modifier; public static ConfigEntry<int> dungeon_final_damage_modifier; public static ConfigEntry<int> dungeon_health_modifier; public static ConfigEntry<int> global_base_damage_modifier; public static ConfigEntry<int> global_final_damage_modifier; public static ConfigEntry<int> global_health_modifier; public static ConfigEntry<string> custom_modifiers; public static void SetupConfigs(ConfigFile config) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Expected O, but got Unknown //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Expected O, but got Unknown //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Expected O, but got Unknown //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = true }; enable_debug_logs = config.Bind<bool>("0 - General", GenerateConfigKey("enable_debug_logs"), false, "Enables debug logs."); enable_modifiers_for_tamed_creatures = config.Bind<bool>("0 - General", GenerateConfigKey("enable_modifiers_for_tamed_creatures"), false, "Enables modifiers for tamed creatures."); string[] names = Enum.GetNames(typeof(Biome)); for (int i = 0; i < names.Length; i++) { if (!BIOMES_TO_BE_IGNORED.Contains(names[i])) { BiomeInfo biomeInfo = new BiomeInfo(); biomeInfo.base_damage_modifier = config.Bind<int>("1 - Biome Modifiers", GenerateConfigKey(string.Format("{0}_{1}", names[i], "base_damage_modifier"), "%"), 100, new ConfigDescription("Determines the base damage modifier (before resistances, armor and blocking), as a percentage, applied to all creatures that are spawned in this biome.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); biomeInfo.final_damage_modifier = config.Bind<int>("1 - Biome Modifiers", GenerateConfigKey(string.Format("{0}_{1}", names[i], "final_damage_modifier"), "%"), 100, new ConfigDescription("Determines the final damage modifier (after resistances, armor and blocking), as a percentage, applied to all creatures that are spawned in this biome.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); biomeInfo.health_modifier = config.Bind<int>("1 - Biome Modifiers", GenerateConfigKey(string.Format("{0}_{1}", names[i], "health_modifier"), "%"), 100, new ConfigDescription("Determines the health modifier, as a percentage, applied to all creatures that are spawned in this biome.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); BiomeInfo value = biomeInfo; BiomeInfoDictionary.Add((Biome)Enum.Parse(typeof(Biome), names[i]), value); } } dungeon_base_damage_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("dungeon_base_damage_modifier", "%"), 100, new ConfigDescription("Determines the base damage modifier (before resistances, armor and blocking), as a percentage, applied to all creatures that are spawned in a dungeon. This modifier stacks (by multiplication) with biome, global, and custom modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); dungeon_final_damage_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("dungeon_final_damage_modifier", "%"), 100, new ConfigDescription("Determines the final damage modifier (after resistances, armor and blocking), as a percentage, applied to all creatures that are spawned in a dungeon. This modifier stacks (by multiplication) with biome, global, and custom modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); dungeon_health_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("dungeon_health_modifier", "%"), 100, new ConfigDescription("Determines the health modifier, as a percentage, applied to all creatures that are spawned in a dungeon. This modifier stacks (by multiplication) with biome, global, and custom modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); global_base_damage_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("global_base_damage_modifier", "%"), 100, new ConfigDescription("Determines the base damage modifier (before resistances, armor and blocking), as a percentage, applied to all creatures that are spawned in any biome. This modifier stacks (by multiplication) with biome, dungeon, and custom modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); global_final_damage_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("global_final_damage_modifier", "%"), 100, new ConfigDescription("Determines the final damage modifier (after resistances, armor and blocking), as a percentage, applied to all creatures that are spawned in any biome. This modifier stacks (by multiplication) with biome, dungeon, and custom modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); global_health_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("global_health_modifier", "%"), 100, new ConfigDescription("Determines the health modifier, as a percentage, applied to all creatures that are spawned in any biome. This modifier stacks (by multiplication) with biome, dungeon, and custom modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val })); custom_modifiers = config.Bind<string>("3 - Custom Modifiers", GenerateConfigKey("custom_modifiers"), "", new ConfigDescription("Determines damage and health modifiers for specific creatures, overriding the default biome modifiers.\nFormat: creature_prefab:base_damage_in_percentage:final_damage_in_percentage:health_in_percentage\nExample: Greydwarf:200:150:300,Goblin:300:200:500.\nBase damage is applied before resistances, armor and blocking; final damage is applied afterwards.\nGlobal and dungeon modifiers multiply the corresponding custom modifiers.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, CustomDrawer = TextAreaDrawer } })); custom_modifiers.SettingChanged += Custom_modifiers_SettingChanged; } public static string GenerateConfigKey(string key) { return GenerateConfigKey(key, null); } public static string GenerateConfigKey(string key, string unit) { key = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(key.Replace('_', ' ').ToLower()); if (unit != null) { key += $" ({unit})"; } return key; } private static void Custom_modifiers_SettingChanged(object sender, EventArgs e) { BiomeDifficultyProgression.UpdateCustomModifiers(); } private static void TextAreaDrawer(ConfigEntryBase entry) { GUILayout.ExpandHeight(true); GUILayout.ExpandWidth(true); entry.BoxedValue = GUILayout.TextArea((string)entry.BoxedValue, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true) }); } } public struct CustomModifier { public float BaseDamageModifier; public float FinalDamageModifier; public float HealthModifier; public CustomModifier(float baseDamageModifier, float healthModifier) : this(baseDamageModifier, 1f, healthModifier) { } public CustomModifier(float baseDamageModifier, float finalDamageModifier, float healthModifier) { BaseDamageModifier = baseDamageModifier; FinalDamageModifier = finalDamageModifier; HealthModifier = healthModifier; } }