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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[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.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BiomeDifficultyProgression;
[BepInPlugin("BiomeDifficultyProgression", "Biome Difficulty Progression", "1.5.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class BiomeDifficultyProgression : BaseUnityPlugin
{
public enum ModifierType
{
DAMAGE,
HEALTH
}
[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.DAMAGE, (Character)(object)__instance, ___m_inventory);
}
}
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()
{
if (Configs.custom_modifiers.Value == null || Configs.custom_modifiers.Value.Length <= 0)
{
return;
}
if (CustomModifiers.Count > 0)
{
CustomModifiers.Clear();
}
string[] array = Configs.custom_modifiers.Value.Split(new char[1] { ',' });
string[] array2 = array;
foreach (string text in array2)
{
string[] array3 = text.Trim().Split(new char[1] { ':' });
if (array3.Length < 3)
{
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 text2 = array3[0].Trim();
int result = 0;
int result2 = 0;
bool flag = int.TryParse(array3[1].Trim(), out result) && int.TryParse(array3[2].Trim(), out result2);
if (text2.Length == 0 || !flag)
{
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 || result2 <= 0)
{
ZLog.LogError((object)"BiomeDifficultyProgression: Damage and health modifiers in custom modifiers cannot be equal or lower than 0.");
CustomModifiers.Clear();
return;
}
CustomModifiers.Add(text2, new CustomModifier((float)result / 100f, (float)result2 / 100f));
}
ZLog.Log((object)"BiomeDifficultyProgression: Custom modifiers updated successfully.");
}
public static float GetModifier(ModifierType modifierType, Character character, out string biomeName)
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: 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.DAMAGE:
num = CustomModifiers[prefabName].DamageModifier;
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)(ref key)).ToString();
Configs.BiomeInfo biomeInfo = Configs.BiomeInfoDictionary[key];
if (modifierType == ModifierType.DAMAGE && biomeInfo.damage_modifier.Value != 100)
{
num = (float)biomeInfo.damage_modifier.Value / 100f;
}
else if (modifierType == ModifierType.HEALTH && biomeInfo.health_modifier.Value != 100)
{
num = (float)biomeInfo.health_modifier.Value / 100f;
}
}
}
switch (modifierType)
{
case ModifierType.DAMAGE:
if (Configs.dungeon_damage_modifier.Value != 100 && character.InInterior() && !character.IsBoss())
{
num *= (float)Configs.dungeon_damage_modifier.Value / 100f;
}
if (Configs.global_damage_modifier.Value != 100)
{
num *= (float)Configs.global_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 void ApplyModifier(ModifierType modifierType, Character character, Inventory inventory = null)
{
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0253: 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.DAMAGE:
{
if (inventory == null || inventory.NrOfItems() <= 0)
{
break;
}
string biomeName;
float modifier = GetModifier(ModifierType.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 static class Configs
{
public class BiomeInfo
{
public ConfigEntry<int> 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_damage_modifier;
public static ConfigEntry<int> dungeon_health_modifier;
public static ConfigEntry<int> global_damage_modifier;
public static ConfigEntry<int> global_health_modifier;
public static ConfigEntry<string> custom_modifiers;
public static void SetupConfigs(ConfigFile config)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Expected O, but got Unknown
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Expected O, but got Unknown
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Expected O, but got Unknown
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Expected O, but got Unknown
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Expected O, but got Unknown
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Expected O, but got Unknown
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_022b: Expected O, but got Unknown
//IL_0271: Unknown result type (might be due to invalid IL or missing references)
//IL_027b: Expected O, but got Unknown
//IL_029b: 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.");
dungeon_damage_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("dungeon_damage_modifier", "%"), 100, new ConfigDescription("Determines the damage modifier, in percentage, applied to all creatures that are spawned in a dungeon. This modifier stacks (by multiplication) with a biome, global and custom modifier.", (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, in percentage, applied to all creatures that are spawned in a dungeon. This modifier stacks (by multiplication) with a biome, global and custom modifier.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val }));
global_damage_modifier = config.Bind<int>("2 - Extra Modifiers", GenerateConfigKey("global_damage_modifier", "%"), 100, new ConfigDescription("Determines the damage modifier, in percentage, applied to all creatures that are spawned in any biome. This modifier stacks (by multiplication) with a biome, dungeon and custom modifier.", (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, in percentage, applied to all creatures that are spawned in any biome. This modifier stacks (by multiplication) with a biome, dungeon and custom modifier.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 10000), new object[1] { val }));
string text = GenerateConfigKey("custom_modifiers");
object[] array = new object[1];
ConfigurationManagerAttributes val2 = new ConfigurationManagerAttributes();
val2.IsAdminOnly = true;
val2.CustomDrawer = TextAreaDrawer;
array[0] = val2;
custom_modifiers = config.Bind<string>("3 - Custom Modifiers", text, "", new ConfigDescription("Determines damage and health modifiers for specific creatures, which will ignore the default modifiers per biome. Format: creature_prefab1:damage_in_percentage:health_in_percentage,creature_prefab2:damage_in_percentage:health_in_percentage - e.g. Greydwarf:200:300,Goblin:300:500", (AcceptableValueBase)null, array));
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.damage_modifier = config.Bind<int>("1 - Biome Modifiers", GenerateConfigKey(string.Format("{0}_{1}", names[i], "damage_modifier"), "%"), 100, new ConfigDescription("Determines the damage modifier, in 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, in 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);
}
}
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 DamageModifier;
public float HealthModifier;
public CustomModifier(float damageModifier, float healthModifier)
{
DamageModifier = damageModifier;
HealthModifier = healthModifier;
}
}