Decompiled source of BiomeDifficultyProgression v1.6.0

plugins/BiomeDifficultyProgression.dll

Decompiled a week ago
using 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;
	}
}