Decompiled source of OdinsOtti v1.0.0

OdinSOtti.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace OdinSOtti;

public static class ContextManager
{
	private static HashSet<string> s_fleeBlacklistSet = null;

	public static void RefreshFleeBlacklist()
	{
		s_fleeBlacklistSet = new HashSet<string>();
		string fleeBlacklist = SyncedConfig.FleeBlacklist;
		if (string.IsNullOrEmpty(fleeBlacklist))
		{
			return;
		}
		string[] array = fleeBlacklist.Split(new char[1] { ',' });
		foreach (string text in array)
		{
			string text2 = text.Trim().ToLower();
			if (!string.IsNullOrEmpty(text2))
			{
				s_fleeBlacklistSet.Add(text2);
			}
		}
	}

	public static bool IsAvoidanceActive(Character enemy)
	{
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)enemy == (Object)null)
		{
			return false;
		}
		if (enemy.IsTamed())
		{
			return false;
		}
		if (s_fleeBlacklistSet == null)
		{
			RefreshFleeBlacklist();
		}
		string item = Utils.GetPrefabName(((Component)enemy).gameObject).ToLower();
		if (s_fleeBlacklistSet.Contains(item))
		{
			return false;
		}
		if (SyncedConfig.DungeonsExcluded && (enemy.InInterior() || ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).InInterior())))
		{
			return false;
		}
		if (SyncedConfig.RaidsExcluded && (Object)(object)RandEventSystem.instance != (Object)null && RandEventSystem.instance.GetCurrentRandomEvent() != null)
		{
			return false;
		}
		if (SyncedConfig.ActiveBossesExcluded)
		{
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if ((Object)(object)allCharacter != (Object)null && allCharacter.IsBoss())
				{
					float num = Vector3.Distance(((Component)enemy).transform.position, ((Component)allCharacter).transform.position);
					if (num < 100f)
					{
						return false;
					}
				}
			}
		}
		return true;
	}
}
[HarmonyPatch]
public static class MonsterAIPatch
{
	[HarmonyPatch(typeof(Character), "GetHoverText")]
	public static class Character_GetHoverText_Patch
	{
		public static void Postfix(Character __instance, ref string __result)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || !OdinOttiPlugin.ShowDebugHud.Value)
			{
				return;
			}
			if (__instance.IsTamed())
			{
				if (ThreatManager.IsCombatTamed(__instance))
				{
					__result += "\n[Odin's Otti] Tamed Companion | System: Exempt";
				}
				else
				{
					__result += "\n[Odin's Otti] Tamed Livestock | System: Exempt";
				}
				return;
			}
			float num = ThreatManager.CalculateEnemyGroupCourage(__instance);
			float multiplayerRange = SyncedConfig.MultiplayerRange;
			float num2 = 0f;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer != (Object)null && Vector3.Distance(((Component)__instance).transform.position, ((Component)allPlayer).transform.position) <= multiplayerRange)
				{
					num2 += ThreatManager.CalculatePlayerThreat(allPlayer);
				}
			}
			float num3 = ThreatManager.CalculateGroupTamedThreat(((Component)__instance).transform.position, __instance);
			float num4 = num2 + num3;
			float bossAndBiomeMultiplier = ThreatManager.GetBossAndBiomeMultiplier(Player.m_localPlayer, __instance);
			float num5 = num4 * bossAndBiomeMultiplier;
			float num6 = ((num > 0f) ? (num5 / num) : 0f);
			string text = (ContextManager.IsAvoidanceActive(__instance) ? "Active" : "Suspended (Dungeon/Raid/Boss/Blacklist)");
			__result += $"\n[Odin's Otti] Courage: {num:F1} | Threat: {num5:F1} (Player: {num2 * bossAndBiomeMultiplier:F1}, Pet: {num3 * bossAndBiomeMultiplier:F1}) | Ratio: {num6:F2} (Thresh: {SyncedConfig.ThreatThreshold:F1}) | System: {text}";
		}
	}

	[HarmonyPatch(typeof(Humanoid), "SetupEquipment")]
	public static class Humanoid_SetupEquipment_Patch
	{
		public static void Postfix(Humanoid __instance)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if ((Object)(object)val != (Object)null)
			{
				ThreatManager.ClearPlayerCache(val);
			}
		}
	}

	[HarmonyPatch(typeof(Skills), "RaiseSkill")]
	public static class Skills_RaiseSkill_Patch
	{
		public static void Postfix(Skills __instance)
		{
			Player componentInParent = ((Component)__instance).GetComponentInParent<Player>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				ThreatManager.ClearPlayerCache(componentInParent);
			}
		}
	}

	[HarmonyPatch(typeof(Character), "OnDamaged")]
	public static class Character_OnDamaged_Patch
	{
		public static void Postfix(Character __instance, HitData hit)
		{
			if (!((Object)(object)__instance == (Object)null) && hit != null)
			{
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker != (Object)null)
				{
					ProvocationManager.ProvokeGroup(attacker, __instance);
				}
			}
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class MonsterAI_UpdateAI_Patch
	{
		private static readonly MethodInfo s_fleeMethod = typeof(BaseAI).GetMethod("Flee", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		public static bool Prefix(MonsterAI __instance, float dt)
		{
			//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_0064: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_025f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!ProvocationManager.IsProvoked(component) && ((BaseAI)__instance).IsAlerted())
			{
				Faction faction = component.GetFaction();
				Vector3 position = ((Component)component).transform.position;
				foreach (Character allCharacter in Character.GetAllCharacters())
				{
					if ((Object)(object)allCharacter != (Object)null && (Object)(object)allCharacter != (Object)(object)component && !allCharacter.IsPlayer() && !allCharacter.IsTamed() && allCharacter.GetFaction() == faction && ProvocationManager.IsProvoked(allCharacter) && Vector3.Distance(((Component)allCharacter).transform.position, position) <= 20f)
					{
						ProvocationManager.SetProvoked(component, provoked: true);
						break;
					}
				}
			}
			if (ProvocationManager.IsProvoked(component))
			{
				if (((BaseAI)__instance).IsAlerted())
				{
					ProvocationManager.SetFleeing(component, fleeing: false);
					return true;
				}
				ProvocationManager.SetProvoked(component, provoked: false);
			}
			if (!ContextManager.IsAvoidanceActive(component))
			{
				ProvocationManager.SetFleeing(component, fleeing: false);
				return true;
			}
			if (((BaseAI)__instance).IsSleeping())
			{
				ProvocationManager.SetFleeing(component, fleeing: false);
				return true;
			}
			float num = ThreatManager.CalculateEnemyGroupCourage(component);
			float num2 = ThreatManager.CalculateGroupPlayerThreat(((Component)component).transform.position, component);
			float num3 = ((num > 0f) ? (num2 / num) : 0f);
			if (num3 > SyncedConfig.ThreatThreshold)
			{
				Player closestPlayer = GetClosestPlayer(((Component)component).transform.position, SyncedConfig.MultiplayerRange);
				if ((Object)(object)closestPlayer != (Object)null)
				{
					if (((Character)closestPlayer).IsCrouching() && !((BaseAI)__instance).IsAlerted())
					{
						ProvocationManager.SetFleeing(component, fleeing: false);
						return true;
					}
					if (s_fleeMethod != null)
					{
						s_fleeMethod.Invoke(__instance, new object[2]
						{
							dt,
							((Component)closestPlayer).transform.position
						});
					}
					ProvocationManager.SetFleeing(component, fleeing: true);
					return false;
				}
			}
			ProvocationManager.SetFleeing(component, fleeing: false);
			return true;
		}

		private static Player GetClosestPlayer(Vector3 position, float maxRange)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Player result = null;
			float num = maxRange;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer != (Object)null)
				{
					float num2 = Vector3.Distance(position, ((Component)allPlayer).transform.position);
					if (num2 <= num)
					{
						num = num2;
						result = allPlayer;
					}
				}
			}
			return result;
		}
	}

	[HarmonyPatch(typeof(BaseAI), "FindClosestEnemy")]
	public static class BaseAI_FindClosestEnemy_Patch
	{
		private static readonly FieldInfo s_characterField = typeof(BaseAI).GetField("m_character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		public static void Postfix(BaseAI __instance, ref Character __result)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__result == (Object)null) && !ThreatManager.s_huntModeActive && !(s_characterField == null))
			{
				Character val = (Character)s_characterField.GetValue(__instance);
				if (!((Object)(object)val == (Object)null) && ThreatManager.IsCombatTamed(val) && ProvocationManager.IsFleeing(__result) && !ProvocationManager.IsProvoked(__result))
				{
					__result = null;
				}
			}
		}
	}
}
[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
public static class ZNet_OnNewConnection_Patch
{
	public static void Postfix(ZNet __instance, ZNetPeer peer)
	{
		if (peer != null && peer.m_rpc != null)
		{
			peer.m_rpc.Register<ZPackage>("OdinOttiSyncConfig", (Action<ZRpc, ZPackage>)RPC_OdinOttiSyncConfig);
		}
	}

	private static void RPC_OdinOttiSyncConfig(ZRpc rpc, ZPackage pkg)
	{
		if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
		{
			return;
		}
		try
		{
			float threshold = pkg.ReadSingle();
			float range = pkg.ReadSingle();
			float spawnerRange = pkg.ReadSingle();
			float spawnerMult = pkg.ReadSingle();
			float chaosBoost = pkg.ReadSingle();
			float skillThresh = pkg.ReadSingle();
			float staticWeight = pkg.ReadSingle();
			float skillWeapon = pkg.ReadSingle();
			float skillDefense = pkg.ReadSingle();
			float biomeMult = pkg.ReadSingle();
			float bossMult = pkg.ReadSingle();
			bool dungeons = pkg.ReadBool();
			bool raids = pkg.ReadBool();
			bool bosses = pkg.ReadBool();
			string tamed = pkg.ReadString();
			string blacklist = pkg.ReadString();
			SyncedConfig.OverrideServerConfig(threshold, range, spawnerRange, spawnerMult, chaosBoost, skillThresh, staticWeight, skillWeapon, skillDefense, biomeMult, bossMult, dungeons, raids, bosses, tamed, blacklist);
			OdinOttiPlugin.Log.LogInfo((object)"[Odin's Otti] Successfully synchronized configuration from server!");
		}
		catch (Exception ex)
		{
			OdinOttiPlugin.Log.LogError((object)("[Odin's Otti] Failed to deserialize server configuration sync: " + ex.Message));
		}
	}
}
[HarmonyPatch(typeof(ZNet), "SendPeerInfo")]
public static class ZNet_SendPeerInfo_Patch
{
	public static void Postfix(ZNet __instance, ZRpc rpc)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		if (__instance.IsServer() || __instance.IsDedicated())
		{
			ZPackage val = new ZPackage();
			val.Write(OdinOttiPlugin.ThreatThreshold.Value);
			val.Write(OdinOttiPlugin.MultiplayerRange.Value);
			val.Write(OdinOttiPlugin.SpawnerDefenseRange.Value);
			val.Write(OdinOttiPlugin.SpawnerDefenseMultiplier.Value);
			val.Write(OdinOttiPlugin.ChaosCourageBoost.Value);
			val.Write(OdinOttiPlugin.SkillThreshold.Value);
			val.Write(OdinOttiPlugin.StaticThreatWeight.Value);
			val.Write(OdinOttiPlugin.SkillWeaponWeight.Value);
			val.Write(OdinOttiPlugin.SkillDefenseWeight.Value);
			val.Write(OdinOttiPlugin.BiomeTierDifferenceMultiplier.Value);
			val.Write(OdinOttiPlugin.BossDefeatedMultiplier.Value);
			val.Write(OdinOttiPlugin.DungeonsExcluded.Value);
			val.Write(OdinOttiPlugin.RaidsExcluded.Value);
			val.Write(OdinOttiPlugin.ActiveBossesExcluded.Value);
			val.Write(OdinOttiPlugin.TamedCombatCompanions.Value);
			val.Write(OdinOttiPlugin.FleeBlacklist.Value);
			rpc.Invoke("OdinOttiSyncConfig", new object[1] { val });
			OdinOttiPlugin.Log.LogInfo((object)("[Odin's Otti] Sent server configuration to peer: " + rpc.GetSocket().GetHostName()));
		}
	}
}
[HarmonyPatch(typeof(ZNet), "OnDestroy")]
public static class ZNet_OnDestroy_Patch
{
	public static void Postfix()
	{
		SyncedConfig.ResetConfigToLocal();
		OdinOttiPlugin.Log.LogInfo((object)"[Odin's Otti] Disconnected from server. Resetting to local configuration.");
	}
}
[HarmonyPatch(typeof(Tameable), "TamingUpdate")]
public static class Tameable_TamingUpdate_Patch
{
	public static bool Prefix(Tameable __instance)
	{
		if ((Object)(object)__instance == (Object)null)
		{
			return true;
		}
		Character component = ((Component)__instance).GetComponent<Character>();
		if ((Object)(object)component != (Object)null && ProvocationManager.IsFleeing(component))
		{
			return false;
		}
		return true;
	}
}
[BepInPlugin("com.drakosdj.valheim.odinsotti", "Odin's Otti", "1.0.0")]
public class OdinOttiPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "com.drakosdj.valheim.odinsotti";

	public const string PluginName = "Odin's Otti";

	public const string PluginVersion = "1.0.0";

	public static ManualLogSource Log;

	public static ConfigEntry<float> ThreatThreshold;

	public static ConfigEntry<float> MultiplayerRange;

	public static ConfigEntry<float> SpawnerDefenseRange;

	public static ConfigEntry<float> SpawnerDefenseMultiplier;

	public static ConfigEntry<float> ChaosCourageBoost;

	public static ConfigEntry<float> SkillThreshold;

	public static ConfigEntry<float> StaticThreatWeight;

	public static ConfigEntry<float> SkillWeaponWeight;

	public static ConfigEntry<float> SkillDefenseWeight;

	public static ConfigEntry<float> BiomeTierDifferenceMultiplier;

	public static ConfigEntry<float> BossDefeatedMultiplier;

	public static ConfigEntry<bool> DungeonsExcluded;

	public static ConfigEntry<bool> RaidsExcluded;

	public static ConfigEntry<bool> ActiveBossesExcluded;

	public static ConfigEntry<bool> ShowDebugHud;

	public static ConfigEntry<KeyboardShortcut> HuntModeHotkey;

	public static ConfigEntry<string> TamedCombatCompanions;

	public static ConfigEntry<float> DebugHudX;

	public static ConfigEntry<float> DebugHudY;

	public static ConfigEntry<string> FleeBlacklist;

	private Harmony harmony;

	private GameObject debugHudObject;

	private void Awake()
	{
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Expected O, but got Unknown
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ThreatThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ThreatThreshold", 1.5f, "Flee when player threat / enemy threat ratio is above this value.");
		MultiplayerRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MultiplayerRange", 100f, "Radius (meters) to search for other players to sum threat.");
		SpawnerDefenseRange = ((BaseUnityPlugin)this).Config.Bind<float>("Spawner", "SpawnerDefenseRange", 20f, "Distance within which enemies will defend their biomes' spawners.");
		SpawnerDefenseMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Spawner", "SpawnerDefenseMultiplier", 1.5f, "Courage multiplier when defending a spawner.");
		ChaosCourageBoost = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ChaosCourageBoost", 1.2f, "Courage multiplier applied when hostile third-party factions are nearby.");
		SkillThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Skills", "SkillThreshold", 0.3f, "Weapon skill threshold (percentage relative to highest) to be included in threat calculation.");
		StaticThreatWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "StaticThreatWeight", 0.5f, "Weight of gear/skills static threat (0.0 to 1.0). Dynamic threat weight is 1 - StaticThreatWeight.");
		SkillWeaponWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "SkillWeaponWeight", 0.8f, "Weight of weapon skills in static threat calculation.");
		SkillDefenseWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "SkillDefenseWeight", 0.2f, "Weight of defense/movement skills in static threat calculation.");
		BiomeTierDifferenceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "BiomeTierDifferenceMultiplier", 0.2f, "Multiplier increase/decrease in threat per biome tier difference.");
		BossDefeatedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Threat", "BossDefeatedMultiplier", 0.15f, "Threat multiplier added per globally defeated boss.");
		DungeonsExcluded = ((BaseUnityPlugin)this).Config.Bind<bool>("Exclusions", "DungeonsExcluded", true, "Disable the system when player is inside instanced dungeons/interiors.");
		RaidsExcluded = ((BaseUnityPlugin)this).Config.Bind<bool>("Exclusions", "RaidsExcluded", true, "Disable the system when a raid is active in the area.");
		ActiveBossesExcluded = ((BaseUnityPlugin)this).Config.Bind<bool>("Exclusions", "ActiveBossesExcluded", true, "Disable the system when an active boss is in the vicinity.");
		ShowDebugHud = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ShowDebugHud", true, "Display player threat in the corner and enemy courage on hover.");
		HuntModeHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Tamed", "HuntModeHotkey", new KeyboardShortcut((KeyCode)0, (KeyCode[])(object)new KeyCode[0]), "Hotkey to toggle tamed animals' Hunt Mode. In Hunt Mode, tamed companions will hunt fleeing targets independently.");
		TamedCombatCompanions = ((BaseUnityPlugin)this).Config.Bind<string>("Tamed", "TamedCombatCompanions", "Wolf, Lox, Askvin", "Comma-separated list of tamed creature prefab names that are considered combat companions (will add to player threat and hunt). All other tamed creatures default to livestock.");
		DebugHudX = ((BaseUnityPlugin)this).Config.Bind<float>("Debug", "DebugHudX", -280f, "Screen X position. Positive values are from the left edge; negative values are offsets from the right edge.");
		DebugHudY = ((BaseUnityPlugin)this).Config.Bind<float>("Debug", "DebugHudY", 420f, "Screen Y position. Positive values are from the top edge; negative values are offsets from the bottom edge.");
		FleeBlacklist = ((BaseUnityPlugin)this).Config.Bind<string>("General", "FleeBlacklist", "Deathsquito, SeekerBrood, Volture, Skeleton, StoneGolem, Ghost, Wraith, Blob, Oozer, Surtling", "Comma-separated list of creature prefab names that are blacklisted and will never flee from players.");
		harmony = new Harmony("com.drakosdj.valheim.odinsotti");
		harmony.PatchAll();
		debugHudObject = new GameObject("OdinOttiDebugHUD");
		debugHudObject.AddComponent<OdinOttiDebugHUD>();
		Object.DontDestroyOnLoad((Object)(object)debugHudObject);
		Log.LogInfo((object)"Odin's Otti Mod initialized successfully!");
	}

	private void OnDestroy()
	{
		if ((Object)(object)debugHudObject != (Object)null)
		{
			Object.Destroy((Object)(object)debugHudObject);
		}
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
public class OdinOttiDebugHUD : MonoBehaviour
{
	private GUIStyle style;

	private Texture2D backgroundTexture;

	private void Start()
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		style = new GUIStyle();
		style.fontSize = 18;
		style.normal.textColor = Color.yellow;
		style.fontStyle = (FontStyle)1;
		backgroundTexture = new Texture2D(1, 1);
		backgroundTexture.SetPixel(0, 0, new Color(0.1f, 0.1f, 0.1f, 0.6f));
		backgroundTexture.Apply();
	}

	private void OnDestroy()
	{
		if ((Object)(object)backgroundTexture != (Object)null)
		{
			Object.Destroy((Object)(object)backgroundTexture);
		}
	}

	private void Update()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		KeyboardShortcut value = OdinOttiPlugin.HuntModeHotkey.Value;
		if (((KeyboardShortcut)(ref value)).IsDown())
		{
			ThreatManager.s_huntModeActive = !ThreatManager.s_huntModeActive;
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage((MessageType)1, string.Format("Odin's Otti - Hunt Mode: {0}", ThreatManager.s_huntModeActive ? "ON" : "OFF"), 0, (Sprite)null, false);
			}
		}
	}

	private void OnGUI()
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		if (!OdinOttiPlugin.ShowDebugHud.Value)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			float num = ThreatManager.CalculatePlayerThreat(localPlayer);
			float num2 = ThreatManager.CalculateGroupTamedThreat(((Component)localPlayer).transform.position);
			float num3 = num + num2;
			string text = string.Format("Player Threat: {0:F1}\nCompanion Threat: {1:F1}\nTotal Group Threat: {2:F1}\nHunt Mode: {3}", num, num2, num3, ThreatManager.s_huntModeActive ? "ON" : "OFF");
			float num4 = OdinOttiPlugin.DebugHudX.Value;
			float num5 = OdinOttiPlugin.DebugHudY.Value;
			if (num4 < 0f)
			{
				num4 = (float)Screen.width + num4;
			}
			if (num5 < 0f)
			{
				num5 = (float)Screen.height + num5;
			}
			if ((Object)(object)backgroundTexture != (Object)null)
			{
				GUI.DrawTexture(new Rect(num4 - 10f, num5 - 10f, 290f, 110f), (Texture)(object)backgroundTexture);
			}
			GUI.Label(new Rect(num4, num5, 270f, 90f), text, style);
		}
	}
}
public static class ProvocationManager
{
	private static readonly HashSet<Character> s_provokedCharacters = new HashSet<Character>();

	private static readonly HashSet<Character> s_fleeingCharacters = new HashSet<Character>();

	public static bool IsProvoked(Character c)
	{
		if ((Object)(object)c == (Object)null)
		{
			return false;
		}
		return s_provokedCharacters.Contains(c);
	}

	public static void SetProvoked(Character c, bool provoked)
	{
		if (!((Object)(object)c == (Object)null))
		{
			if (provoked)
			{
				s_provokedCharacters.Add(c);
			}
			else
			{
				s_provokedCharacters.Remove(c);
			}
		}
	}

	public static bool IsFleeing(Character c)
	{
		if ((Object)(object)c == (Object)null)
		{
			return false;
		}
		return s_fleeingCharacters.Contains(c);
	}

	public static void SetFleeing(Character c, bool fleeing)
	{
		if (!((Object)(object)c == (Object)null))
		{
			if (fleeing)
			{
				s_fleeingCharacters.Add(c);
			}
			else
			{
				s_fleeingCharacters.Remove(c);
			}
		}
	}

	public static void ClearAll()
	{
		s_provokedCharacters.Clear();
		s_fleeingCharacters.Clear();
	}

	public static void ProvokeGroup(Character attacker, Character victim)
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)victim == (Object)null || (Object)(object)attacker == (Object)null || (!attacker.IsPlayer() && !attacker.IsTamed()))
		{
			return;
		}
		s_provokedCharacters.Add(victim);
		s_fleeingCharacters.Remove(victim);
		float num = 25f;
		Vector3 position = ((Component)victim).transform.position;
		Faction faction = victim.GetFaction();
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if ((Object)(object)allCharacter != (Object)null && (Object)(object)allCharacter != (Object)(object)victim && !allCharacter.IsPlayer() && !allCharacter.IsTamed() && allCharacter.GetFaction() == faction && Vector3.Distance(((Component)allCharacter).transform.position, position) <= num)
			{
				s_provokedCharacters.Add(allCharacter);
				s_fleeingCharacters.Remove(allCharacter);
			}
		}
	}
}
public static class SyncedConfig
{
	private static bool s_isConfigSynced = false;

	private static float s_syncedThreshold;

	private static float s_syncedRange;

	private static float s_syncedSpawnerRange;

	private static float s_syncedSpawnerMult;

	private static float s_syncedChaosBoost;

	private static float s_syncedSkillThresh;

	private static float s_syncedStaticWeight;

	private static float s_syncedSkillWeapon;

	private static float s_syncedSkillDefense;

	private static float s_syncedBiomeMult;

	private static float s_syncedBossMult;

	private static bool s_syncedDungeonsExcluded;

	private static bool s_syncedRaidsExcluded;

	private static bool s_syncedActiveBossesExcluded;

	private static string s_syncedTamedCompanions;

	private static string s_syncedFleeBlacklist;

	public static float ThreatThreshold => s_isConfigSynced ? s_syncedThreshold : OdinOttiPlugin.ThreatThreshold.Value;

	public static float MultiplayerRange => s_isConfigSynced ? s_syncedRange : OdinOttiPlugin.MultiplayerRange.Value;

	public static float SpawnerDefenseRange => s_isConfigSynced ? s_syncedSpawnerRange : OdinOttiPlugin.SpawnerDefenseRange.Value;

	public static float SpawnerDefenseMultiplier => s_isConfigSynced ? s_syncedSpawnerMult : OdinOttiPlugin.SpawnerDefenseMultiplier.Value;

	public static float ChaosCourageBoost => s_isConfigSynced ? s_syncedChaosBoost : OdinOttiPlugin.ChaosCourageBoost.Value;

	public static float SkillThreshold => s_isConfigSynced ? s_syncedSkillThresh : OdinOttiPlugin.SkillThreshold.Value;

	public static float StaticThreatWeight => s_isConfigSynced ? s_syncedStaticWeight : OdinOttiPlugin.StaticThreatWeight.Value;

	public static float SkillWeaponWeight => s_isConfigSynced ? s_syncedSkillWeapon : OdinOttiPlugin.SkillWeaponWeight.Value;

	public static float SkillDefenseWeight => s_isConfigSynced ? s_syncedSkillDefense : OdinOttiPlugin.SkillDefenseWeight.Value;

	public static float BiomeTierDifferenceMultiplier => s_isConfigSynced ? s_syncedBiomeMult : OdinOttiPlugin.BiomeTierDifferenceMultiplier.Value;

	public static float BossDefeatedMultiplier => s_isConfigSynced ? s_syncedBossMult : OdinOttiPlugin.BossDefeatedMultiplier.Value;

	public static bool DungeonsExcluded => s_isConfigSynced ? s_syncedDungeonsExcluded : OdinOttiPlugin.DungeonsExcluded.Value;

	public static bool RaidsExcluded => s_isConfigSynced ? s_syncedRaidsExcluded : OdinOttiPlugin.RaidsExcluded.Value;

	public static bool ActiveBossesExcluded => s_isConfigSynced ? s_syncedActiveBossesExcluded : OdinOttiPlugin.ActiveBossesExcluded.Value;

	public static string TamedCombatCompanions => s_isConfigSynced ? s_syncedTamedCompanions : OdinOttiPlugin.TamedCombatCompanions.Value;

	public static string FleeBlacklist => s_isConfigSynced ? s_syncedFleeBlacklist : OdinOttiPlugin.FleeBlacklist.Value;

	public static void OverrideServerConfig(float threshold, float range, float spawnerRange, float spawnerMult, float chaosBoost, float skillThresh, float staticWeight, float skillWeapon, float skillDefense, float biomeMult, float bossMult, bool dungeons, bool raids, bool bosses, string tamed, string blacklist)
	{
		s_syncedThreshold = threshold;
		s_syncedRange = range;
		s_syncedSpawnerRange = spawnerRange;
		s_syncedSpawnerMult = spawnerMult;
		s_syncedChaosBoost = chaosBoost;
		s_syncedSkillThresh = skillThresh;
		s_syncedStaticWeight = staticWeight;
		s_syncedSkillWeapon = skillWeapon;
		s_syncedSkillDefense = skillDefense;
		s_syncedBiomeMult = biomeMult;
		s_syncedBossMult = bossMult;
		s_syncedDungeonsExcluded = dungeons;
		s_syncedRaidsExcluded = raids;
		s_syncedActiveBossesExcluded = bosses;
		s_syncedTamedCompanions = tamed;
		s_syncedFleeBlacklist = blacklist;
		s_isConfigSynced = true;
		ContextManager.RefreshFleeBlacklist();
	}

	public static void ResetConfigToLocal()
	{
		s_isConfigSynced = false;
		ContextManager.RefreshFleeBlacklist();
	}
}
public static class ThreatManager
{
	public static bool s_huntModeActive = false;

	private static readonly Dictionary<Player, float> s_staticThreatCache = new Dictionary<Player, float>();

	private static HashSet<string> s_combatCompanionsSet = null;

	public static void ClearPlayerCache(Player player)
	{
		if ((Object)(object)player != (Object)null)
		{
			s_staticThreatCache.Remove(player);
		}
	}

	public static void RefreshCombatCompanionsSet()
	{
		s_combatCompanionsSet = new HashSet<string>();
		string tamedCombatCompanions = SyncedConfig.TamedCombatCompanions;
		if (string.IsNullOrEmpty(tamedCombatCompanions))
		{
			return;
		}
		string[] array = tamedCombatCompanions.Split(new char[1] { ',' });
		foreach (string text in array)
		{
			string text2 = text.Trim().ToLower();
			if (!string.IsNullOrEmpty(text2))
			{
				s_combatCompanionsSet.Add(text2);
			}
		}
	}

	public static float CalculatePlayerThreat(Player player)
	{
		if ((Object)(object)player == (Object)null || ((Character)player).InGhostMode())
		{
			return 0f;
		}
		if (!s_staticThreatCache.TryGetValue(player, out var value))
		{
			value = ComputeStaticThreat(player);
			s_staticThreatCache[player] = value;
		}
		float num = ComputeDynamicModifier(player);
		return value * num;
	}

	public static float CalculateGroupPlayerThreat(Vector3 position, Character enemy = null)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		float num = 0f;
		float multiplayerRange = SyncedConfig.MultiplayerRange;
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			if ((Object)(object)allPlayer != (Object)null && Vector3.Distance(position, ((Component)allPlayer).transform.position) <= multiplayerRange)
			{
				num += CalculatePlayerThreat(allPlayer);
			}
		}
		return num + CalculateGroupTamedThreat(position, enemy);
	}

	public static float CalculateGroupTamedThreat(Vector3 position, Character enemy = null)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		float num = 0f;
		float multiplayerRange = SyncedConfig.MultiplayerRange;
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if ((Object)(object)allCharacter != (Object)null && IsCombatTamed(allCharacter) && Vector3.Distance(position, ((Component)allCharacter).transform.position) <= multiplayerRange && (!((Object)(object)enemy != (Object)null) || BaseAI.IsEnemy(enemy, allCharacter)))
			{
				float maxHealth = allCharacter.GetMaxHealth();
				num += maxHealth;
			}
		}
		return num;
	}

	public static float CalculateEnemyGroupCourage(Character enemy)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)enemy == (Object)null)
		{
			return 1f;
		}
		float num = 0f;
		float num2 = 20f;
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if ((Object)(object)allCharacter != (Object)null && !allCharacter.IsPlayer() && !allCharacter.IsTamed() && Vector3.Distance(((Component)enemy).transform.position, ((Component)allCharacter).transform.position) <= num2 && ((Object)(object)allCharacter == (Object)(object)enemy || (!BaseAI.IsEnemy(enemy, allCharacter) && !BaseAI.IsEnemy(allCharacter, enemy))) && (!((Object)(object)allCharacter != (Object)(object)enemy) || !ProvocationManager.IsFleeing(allCharacter)))
			{
				float maxHealth = allCharacter.GetMaxHealth();
				num += maxHealth;
			}
		}
		float num3 = 1f;
		if (IsNearMatchingSpawner(enemy))
		{
			num3 = SyncedConfig.SpawnerDefenseMultiplier;
		}
		float num4 = 1f;
		if (HasThirdPartyChaos(enemy))
		{
			num4 = SyncedConfig.ChaosCourageBoost;
		}
		return num * num3 * num4;
	}

	public static bool IsCombatTamed(Character c)
	{
		if ((Object)(object)c == (Object)null || !c.IsTamed())
		{
			return false;
		}
		if (s_combatCompanionsSet == null)
		{
			RefreshCombatCompanionsSet();
		}
		string item = Utils.GetPrefabName(((Component)c).gameObject).ToLower();
		return s_combatCompanionsSet.Contains(item);
	}

	public static float GetBossAndBiomeMultiplier(Player player, Character enemy)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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)
		if ((Object)(object)player == (Object)null || (Object)(object)enemy == (Object)null)
		{
			return 1f;
		}
		Biome biome = Heightmap.FindBiome(((Component)enemy).transform.position);
		int biomeTier = GetBiomeTier(biome);
		bool flag = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("defeated_eikthyr");
		bool flag2 = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("defeated_gdking");
		bool flag3 = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("defeated_bonemass");
		bool flag4 = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("defeated_moder");
		bool flag5 = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("defeated_yagluth");
		bool flag6 = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("defeated_queen");
		bool flag7 = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey("defeated_fader");
		int num = -1;
		if (flag7)
		{
			num = 6;
		}
		else if (flag6)
		{
			num = 5;
		}
		else if (flag5)
		{
			num = 4;
		}
		else if (flag4)
		{
			num = 3;
		}
		else if (flag3)
		{
			num = 2;
		}
		else if (flag2)
		{
			num = 1;
		}
		else if (flag)
		{
			num = 0;
		}
		float num2 = 1f;
		float bossDefeatedMultiplier = SyncedConfig.BossDefeatedMultiplier;
		if (flag && biomeTier <= 0)
		{
			num2 += bossDefeatedMultiplier;
		}
		if (flag2 && biomeTier <= 1)
		{
			num2 += bossDefeatedMultiplier;
		}
		if (flag3 && biomeTier <= 2)
		{
			num2 += bossDefeatedMultiplier;
		}
		if (flag4 && biomeTier <= 3)
		{
			num2 += bossDefeatedMultiplier;
		}
		if (flag5 && biomeTier <= 4)
		{
			num2 += bossDefeatedMultiplier;
		}
		if (flag6 && biomeTier <= 5)
		{
			num2 += bossDefeatedMultiplier;
		}
		if (flag7 && biomeTier <= 6)
		{
			num2 += bossDefeatedMultiplier;
		}
		int num3 = num - biomeTier;
		float num4 = 1f + (float)num3 * SyncedConfig.BiomeTierDifferenceMultiplier;
		if (num4 < 0.1f)
		{
			num4 = 0.1f;
		}
		return num2 * num4;
	}

	private static float ComputeStaticThreat(Player player)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Invalid comparison between Unknown and I4
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Invalid comparison between Unknown and I4
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		float bodyArmor = ((Character)player).GetBodyArmor();
		List<ItemData> list = ScanHotbarAndQuickslots(player);
		float num = 0f;
		foreach (ItemData item in list)
		{
			float num2 = ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage();
			if (num2 == 0f && ((int)item.m_shared.m_skillType == 9 || (int)item.m_shared.m_skillType == 10))
			{
				num2 = 30f + (float)item.m_shared.m_toolTier * 15f;
			}
			if (num2 > num)
			{
				num = num2;
			}
		}
		if (num < 5f)
		{
			num = 5f;
		}
		float num3 = bodyArmor + num;
		List<SkillType> list2 = new List<SkillType>();
		foreach (ItemData item2 in list)
		{
			if (!list2.Contains(item2.m_shared.m_skillType))
			{
				list2.Add(item2.m_shared.m_skillType);
			}
		}
		if (!list2.Contains((SkillType)11))
		{
			list2.Add((SkillType)11);
		}
		float num4 = 0f;
		Dictionary<SkillType, float> dictionary = new Dictionary<SkillType, float>();
		foreach (SkillType item3 in list2)
		{
			float num5 = (dictionary[item3] = ((Character)player).GetSkills().GetSkillLevel(item3));
			if (num5 > num4)
			{
				num4 = num5;
			}
		}
		float num6 = num4 * (1f - SyncedConfig.SkillThreshold);
		float num7 = 0f;
		int num8 = 0;
		foreach (KeyValuePair<SkillType, float> item4 in dictionary)
		{
			if (item4.Value > 0f && item4.Value >= num6)
			{
				num7 += item4.Value;
				num8++;
			}
		}
		float num9 = ((num8 > 0) ? (num7 / (float)num8) : 0f);
		float skillLevel2 = ((Character)player).GetSkills().GetSkillLevel((SkillType)6);
		float skillLevel3 = ((Character)player).GetSkills().GetSkillLevel((SkillType)102);
		float skillLevel4 = ((Character)player).GetSkills().GetSkillLevel((SkillType)100);
		float num10 = (skillLevel2 + skillLevel3 + skillLevel4) / 3f;
		float num11 = num9 * SyncedConfig.SkillWeaponWeight + num10 * SyncedConfig.SkillDefenseWeight;
		float staticThreatWeight = SyncedConfig.StaticThreatWeight;
		return num3 * staticThreatWeight + num11 * (1f - staticThreatWeight);
	}

	private static float ComputeDynamicModifier(Player player)
	{
		float num = ((Character)player).GetHealth() / ((Character)player).GetMaxHealth();
		float num2 = Mathf.Lerp(0.5f, 1f, num);
		float num3 = player.GetStamina() / ((Character)player).GetMaxStamina();
		float num4 = Mathf.Lerp(0.9f, 1f, num3);
		float num5 = 1f;
		SEMan sEMan = ((Character)player).GetSEMan();
		if (sEMan != null)
		{
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Rested")))
			{
				num5 += 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Eikthyr")))
			{
				num5 += 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("GP_TheElder")))
			{
				num5 += 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Bonemass")))
			{
				num5 += 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Moder")))
			{
				num5 += 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Yagluth")))
			{
				num5 += 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Queen")))
			{
				num5 += 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Wet")))
			{
				num5 -= 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Cold")))
			{
				num5 -= 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Poison")))
			{
				num5 -= 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Burning")))
			{
				num5 -= 0.1f;
			}
			if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("CorpseRun")))
			{
				num5 -= 0.1f;
			}
		}
		if (num5 < 0.1f)
		{
			num5 = 0.1f;
		}
		return num2 * num4 * num5;
	}

	private static List<ItemData> ScanHotbarAndQuickslots(Player player)
	{
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Expected O, but got Unknown
		List<ItemData> list = new List<ItemData>();
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return list;
		}
		for (int i = 0; i < 8; i++)
		{
			ItemData itemAt = inventory.GetItemAt(i, 0);
			if (itemAt != null && IsValidCombatItem(itemAt))
			{
				list.Add(itemAt);
			}
		}
		MonoBehaviour[] components = ((Component)player).GetComponents<MonoBehaviour>();
		foreach (MonoBehaviour val in components)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Type type = ((object)val).GetType();
			if (type == typeof(Player))
			{
				continue;
			}
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.FieldType == typeof(Inventory)))
				{
					continue;
				}
				Inventory val2 = (Inventory)fieldInfo.GetValue(val);
				if (val2 == null || (!val2.GetName().ToLower().Contains("quick") && !val2.GetName().ToLower().Contains("equip")))
				{
					continue;
				}
				foreach (ItemData allItem in val2.GetAllItems())
				{
					if (allItem != null && IsValidCombatItem(allItem) && !list.Contains(allItem))
					{
						list.Add(allItem);
					}
				}
			}
		}
		return list;
	}

	private static bool IsValidCombatItem(ItemData item)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Invalid comparison between Unknown and I4
		if (item == null)
		{
			return false;
		}
		if ((int)item.m_shared.m_skillType == 12)
		{
			return false;
		}
		bool flag = ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage() > 0f;
		bool flag2 = (int)item.m_shared.m_attack.m_attackType != 3;
		return flag || flag2;
	}

	private static bool IsNearMatchingSpawner(Character enemy)
	{
		//IL_0007: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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)
		Collider[] array = Physics.OverlapSphere(((Component)enemy).transform.position, SyncedConfig.SpawnerDefenseRange);
		Biome val = Heightmap.FindBiome(((Component)enemy).transform.position);
		Collider[] array2 = array;
		foreach (Collider val2 in array2)
		{
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			SpawnArea componentInParent = ((Component)val2).GetComponentInParent<SpawnArea>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				Biome val3 = Heightmap.FindBiome(((Component)componentInParent).transform.position);
				if (val3 == val)
				{
					return true;
				}
			}
		}
		return false;
	}

	private static bool HasThirdPartyChaos(Character enemy)
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		float num = 20f;
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return false;
		}
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if ((Object)(object)allCharacter != (Object)null && !allCharacter.IsPlayer() && (Object)(object)allCharacter != (Object)(object)enemy && Vector3.Distance(((Component)enemy).transform.position, ((Component)allCharacter).transform.position) <= num && BaseAI.IsEnemy(enemy, allCharacter) && BaseAI.IsEnemy(allCharacter, (Character)(object)localPlayer))
			{
				return true;
			}
		}
		return false;
	}

	private static int GetBiomeTier(Biome biome)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Invalid comparison between Unknown and I4
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Invalid comparison between Unknown and I4
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected I4, but got Unknown
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Invalid comparison between Unknown and I4
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Invalid comparison between Unknown and I4
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Invalid comparison between Unknown and I4
		if ((int)biome <= 8)
		{
			switch (biome - 1)
			{
			default:
				if ((int)biome != 8)
				{
					break;
				}
				return 1;
			case 0:
				return 0;
			case 1:
				return 2;
			case 3:
				return 3;
			case 2:
				break;
			}
		}
		else
		{
			if ((int)biome == 16)
			{
				return 4;
			}
			if ((int)biome == 32)
			{
				return 5;
			}
			if ((int)biome == 64)
			{
				return 6;
			}
		}
		return 0;
	}
}