using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
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("Biome Scaling")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Biome Scaling")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("64c3046c-52a6-4407-a8e6-c25981f4a465")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("gaakrin.biomescaling", "Biome Scaling", "1.2.0")]
public class BiomeScaling : BaseUnityPlugin
{
public static Dictionary<Biome, BiomeLimits> Limits;
private void Awake()
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
Limits = new Dictionary<Biome, BiomeLimits>
{
{
(Biome)1,
new BiomeLimits(24f)
},
{
(Biome)8,
new BiomeLimits(42f)
},
{
(Biome)2,
new BiomeLimits(60f)
},
{
(Biome)4,
new BiomeLimits(78f)
},
{
(Biome)16,
new BiomeLimits(96f)
},
{
(Biome)512,
new BiomeLimits(114f)
}
};
Harmony val = new Harmony("gaakrin.biomescaling");
val.PatchAll();
}
}
public static class BiomeHpLimits
{
public static readonly Dictionary<Biome, float> MaxHpByBiome = new Dictionary<Biome, float>
{
{
(Biome)1,
115f
},
{
(Biome)8,
145f
},
{
(Biome)2,
175f
},
{
(Biome)4,
195f
},
{
(Biome)16,
250f
},
{
(Biome)512,
270f
}
};
}
public static class BiomeDamageScaling
{
public static class BiomePriority
{
public static readonly Dictionary<Biome, int> Priority = new Dictionary<Biome, int>
{
{
(Biome)0,
0
},
{
(Biome)256,
0
},
{
(Biome)1,
0
},
{
(Biome)8,
1
},
{
(Biome)2,
2
},
{
(Biome)4,
3
},
{
(Biome)16,
4
},
{
(Biome)512,
5
},
{
(Biome)32,
6
},
{
(Biome)64,
7
}
};
public static Biome GetHigher(Biome a, Biome b)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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_001d: 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)
return (Priority[b] > Priority[a]) ? b : a;
}
}
public static readonly Dictionary<Biome, List<DamageTier>> BiomeTiers = new Dictionary<Biome, List<DamageTier>>
{
{
(Biome)1,
new List<DamageTier>
{
new DamageTier(30f)
}
},
{
(Biome)8,
new List<DamageTier>
{
new DamageTier(50f)
}
},
{
(Biome)2,
new List<DamageTier>
{
new DamageTier(75f)
}
},
{
(Biome)4,
new List<DamageTier>
{
new DamageTier(100f)
}
},
{
(Biome)16,
new List<DamageTier>
{
new DamageTier(125f)
}
},
{
(Biome)512,
new List<DamageTier>
{
new DamageTier(150f)
}
}
};
public static float GetWeapon(Biome biome, float weaponDamage)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if (!BiomeTiers.TryGetValue(biome, out var value))
{
return weaponDamage;
}
foreach (DamageTier item in value)
{
if (weaponDamage >= item.damageLimit)
{
return item.damageLimit;
}
}
return weaponDamage;
}
}
public class BiomeLimits
{
public float maxArmor;
public BiomeLimits(float armor)
{
maxArmor = armor;
}
}
public class DamageTier
{
public float damageLimit;
public DamageTier(float limit)
{
damageLimit = limit;
}
}
public static class EventHelper
{
public static bool IsNearBase(Player player)
{
int value = Traverse.Create((object)player).Field("m_baseValue").GetValue<int>();
return value >= 3;
}
}
public static class NearbyThreatScanner
{
private const float ScanRadius = 50f;
public static Biome GetEffectiveBiome(Player player)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: 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_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: 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_00c6: 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)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
Biome currentBiome = player.GetCurrentBiome();
Vector3 position = ((Component)player).transform.position;
int num = BiomeDamageScaling.BiomePriority.Priority[currentBiome];
Biome result = currentBiome;
foreach (Character allCharacter in Character.GetAllCharacters())
{
if (Vector3.Distance(position, ((Component)allCharacter).transform.position) > 50f)
{
continue;
}
ZNetView component = ((Component)allCharacter).GetComponent<ZNetView>();
if ((Object)(object)component == (Object)null || !component.IsValid())
{
continue;
}
int prefab = component.GetZDO().GetPrefab();
GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab);
if (!((Object)(object)prefab2 == (Object)null))
{
string name = ((Object)prefab2).name;
Biome val = currentBiome;
switch (name)
{
case "Charred_Archer":
val = (Biome)32;
break;
case "Charred_Melee":
val = (Biome)32;
break;
case "Seeker":
val = (Biome)512;
break;
case "Goblin":
val = (Biome)16;
break;
case "Draugr":
val = (Biome)2;
break;
}
if (BiomeDamageScaling.BiomePriority.Priority.TryGetValue(val, out var value) && value > num)
{
num = value;
result = val;
}
}
}
return result;
}
}
[HarmonyPatch(typeof(Attack), "OnAttackTrigger")]
public static class OnAttackTrigger
{
[HarmonyPrefix]
public static void Prefix(Attack __instance)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
Humanoid value = Traverse.Create((object)__instance).Field("m_character").GetValue<Humanoid>();
Player val = (Player)(object)((value is Player) ? value : null);
if ((Object)(object)val == (Object)null || EventHelper.IsNearBase(val))
{
return;
}
ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
if (currentWeapon == null)
{
return;
}
Biome effectiveBiome = NearbyThreatScanner.GetEffectiveBiome(val);
if (BiomeDamageScaling.BiomeTiers.TryGetValue(effectiveBiome, out var _))
{
float totalDamage = ((DamageTypes)(ref currentWeapon.m_shared.m_damages)).GetTotalDamage();
float weapon = BiomeDamageScaling.GetWeapon(effectiveBiome, totalDamage);
if (totalDamage > weapon)
{
float num = weapon / totalDamage;
__instance.m_damageMultiplier *= num;
__instance.m_forceMultiplier *= num;
__instance.m_staggerMultiplier *= num;
__instance.m_attackHitNoise *= num;
}
}
}
}
[HarmonyPatch(typeof(Player), "UpdateFood")]
public static class PlayerHealth_UpdateFood
{
private static Dictionary<Player, Biome> lastBiome = new Dictionary<Player, Biome>();
private static Dictionary<Player, float> lastMaxHP = new Dictionary<Player, float>();
private static Dictionary<Player, float> lastFactor = new Dictionary<Player, float>();
private static void Postfix(Player __instance)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: 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_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0204: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || !((Character)__instance).IsPlayer())
{
return;
}
if (!lastMaxHP.ContainsKey(__instance))
{
lastMaxHP[__instance] = ((Character)__instance).GetMaxHealth();
}
if (!lastBiome.ContainsKey(__instance))
{
lastBiome[__instance] = __instance.GetCurrentBiome();
}
if (!lastFactor.ContainsKey(__instance))
{
lastFactor[__instance] = 1f;
}
lastMaxHP.TryGetValue(__instance, out var value);
lastFactor.TryGetValue(__instance, out var value2);
lastBiome.TryGetValue(__instance, out var value3);
Biome effectiveBiome = NearbyThreatScanner.GetEffectiveBiome(__instance);
if (BiomeHpLimits.MaxHpByBiome.TryGetValue(effectiveBiome, out var value4))
{
if (EventHelper.IsNearBase(__instance))
{
if (((Character)__instance).GetMaxHealth() > value)
{
float maxHealth = ((Character)__instance).GetMaxHealth();
((Character)__instance).SetHealth(maxHealth * value2);
lastMaxHP[__instance] = maxHealth;
lastFactor[__instance] = ((Character)__instance).GetHealth() / ((Character)__instance).GetMaxHealth();
}
}
else if (value3 != effectiveBiome || (!EventHelper.IsNearBase(__instance) && value > value4))
{
((Character)__instance).SetMaxHealth(value4);
((Character)__instance).SetHealth(value4 * value2);
lastMaxHP[__instance] = value4;
lastBiome[__instance] = effectiveBiome;
}
else
{
((Character)__instance).SetMaxHealth(value);
lastMaxHP[__instance] = ((Character)__instance).GetMaxHealth();
lastFactor[__instance] = ((Character)__instance).GetHealth() / ((Character)__instance).GetMaxHealth();
}
}
else if (value3 != effectiveBiome && ((Character)__instance).GetMaxHealth() > value)
{
float maxHealth2 = ((Character)__instance).GetMaxHealth();
((Character)__instance).SetHealth(maxHealth2 * value2);
lastMaxHP[__instance] = maxHealth2;
lastBiome[__instance] = effectiveBiome;
}
else
{
lastMaxHP[__instance] = ((Character)__instance).GetMaxHealth();
lastFactor[__instance] = ((Character)__instance).GetHealth() / ((Character)__instance).GetMaxHealth();
}
}
}
[HarmonyPatch(typeof(Player), "GetBodyArmor")]
public static class Player_GetBodyArmor
{
private static void Postfix(Player __instance, ref float __result)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || !((Character)__instance).IsPlayer() || EventHelper.IsNearBase(__instance))
{
return;
}
Biome effectiveBiome = NearbyThreatScanner.GetEffectiveBiome(__instance);
if (BiomeScaling.Limits.TryGetValue(effectiveBiome, out var value))
{
float maxArmor = value.maxArmor;
if (__result > maxArmor)
{
__result = maxArmor;
}
}
}
}