Decompiled source of Wildling v1.1.6

WildlingMod.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using HarmonyLib;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ValheimMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimMod")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5bd3bb56-8412-4715-841f-75c0d11515f3")]
[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 WildlingMod;

internal class Alignment
{
	private class ClanMemberData
	{
		public string m_clan;

		public int m_rank;

		public bool m_barter;

		public float m_trust;

		public float m_discoverRadius;

		public ClanMemberData(string clan = "", bool barter = false, float trust = 0.2f, float discoverRadius = 0f)
		{
			if (clan == "")
			{
				clan = "NONE";
			}
			m_clan = clan;
			m_trust = trust;
			m_barter = barter;
			m_discoverRadius = discoverRadius;
			if (!m_clanSize.ContainsKey(clan))
			{
				m_clanSize.Add(clan, 0);
			}
			m_rank = m_clanSize[clan]++;
		}
	}

	private class CharacterOnConsumedItem
	{
		public Character m_character;

		public CharacterOnConsumedItem(Character character)
		{
			m_character = character;
		}

		public void OnConsumedItem(ItemDrop item)
		{
			if (item.m_itemData != null && !((Object)(object)m_character == (Object)null) && !m_character.IsDead())
			{
				try
				{
					PickupItem(item, m_character);
				}
				catch
				{
					WDBUG.Log("CATCH: OnConsumeItem for " + WUTIL.ActorName(m_character));
				}
			}
		}
	}

	[HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[]
	{
		typeof(Character),
		typeof(Character)
	})]
	private class PatchBaseAIFaction
	{
		private static void Postfix(Character a, Character b, ref bool __result)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			__result = IsEnemy(a, b, __result);
			if (__result && ((Object)(object)a == (Object)(object)Player.m_localPlayer || (Object)(object)b == (Object)(object)Player.m_localPlayer) && Vector3.Distance(((Component)a).transform.position, ((Component)b).transform.position) < m_playerNoEnemyRange)
			{
				World.m_locationUnsafe = true;
			}
		}
	}

	[HarmonyPatch(typeof(Projectile), "IsValidTarget")]
	private class PatchProjectileIsValidTarget
	{
		private static void Prefix(IDestructible destr, Character ___m_owner)
		{
			Character val = (Character)(object)((destr is Character) ? destr : null);
			if ((Object)(object)val != (Object)null && (Object)(object)___m_owner != (Object)null && (Object)(object)val != (Object)(object)___m_owner)
			{
				IgnoreNextIsEnemyCheck();
			}
		}
	}

	[HarmonyPatch(typeof(BaseAI), "CanSenseTarget", new Type[] { typeof(Character) })]
	private class PatchBaseAICanSenseTarget
	{
		public static bool Prefix(BaseAI __instance, Character target, Character ___m_character, ref bool __result)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Invalid comparison between Unknown and I4
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Invalid comparison between Unknown and I4
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Invalid comparison between Unknown and I4
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Invalid comparison between Unknown and I4
			//IL_05c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Invalid comparison between Unknown and I4
			//IL_05cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ce: Invalid comparison between Unknown and I4
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Invalid comparison between Unknown and I4
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Invalid comparison between Unknown and I4
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Invalid comparison between Unknown and I4
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Invalid comparison between Unknown and I4
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Invalid comparison between Unknown and I4
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)___m_character == (Object)null || (Object)(object)target == (Object)null)
			{
				return true;
			}
			__result = true;
			string text = WUTIL.ActorName(___m_character);
			if ((Object)(object)target == (Object)(object)Player.m_localPlayer)
			{
				bool flag = AlertedToPlayer(___m_character);
				if ((int)___m_character.GetFaction() == 7 && WUTIL.TestLuck(0.01f * (float)Quest.GetAchievement("DarklingShade")))
				{
					__result = false;
				}
				else if (m_characterDazed.ContainsKey(___m_character) && m_characterDazed[___m_character] >= 100f)
				{
					WDBUG.Log($"{___m_character.GetHoverName()} should not see you for {m_characterDazed[___m_character] - 100f}s!", WDBUG.Level.warn, 1f);
					__result = false;
				}
				else if (Fairy.PinePasteActive(___m_character))
				{
					__result = false;
				}
				else if (text == "Pixie")
				{
					if (___m_character.GetHealthPercentage() < 0.99f || SwampDungeon.AtGreatOak(((Component)___m_character).transform))
					{
						return true;
					}
					Vector3 val = ((Component)___m_character).transform.position - ((Component)target).transform.position;
					float magnitude = ((Vector3)(ref val)).magnitude;
					if (magnitude < 30f)
					{
						if (AlertedToPlayer(___m_character, anyTarget: true) && magnitude < 8f)
						{
							if (Wildling.IsWildling)
							{
								__result = Quest.GetAchievement("BoundYgnie") != 1 && WUTIL.TestLuck();
							}
							else
							{
								Transform transform = ((Component)___m_character).transform;
								transform.position += 10f * ((Vector3)(ref val)).normalized;
								WDBUG.Log("Pixie vanish", WDBUG.Level.Wildlife);
							}
						}
						else if (magnitude < 12f)
						{
							if (Wildling.IsWildling)
							{
								__result = !PlayerHiddenFromTarget(___m_character);
								if (__result)
								{
									FlickTarget(___m_character);
								}
							}
							else
							{
								Transform transform2 = ((Component)___m_character).transform;
								transform2.position += 12f * ((Vector3)(ref val)).normalized;
								FlickTarget(___m_character);
							}
						}
						if (WUTIL.RandomSpin() < 0.2f)
						{
							WUTIL.PlaceObject("ygnie_blind_aoe", ((Component)___m_character).transform.position, 0.5f);
							val = WUTIL.OnCircle(Vector3.zero, 0.5f + WUTIL.RandomSpin());
							val.y = WUTIL.RandomSpin();
							Transform transform3 = ((Component)___m_character).transform;
							transform3.position += val;
							WUTIL.PlaceObject("ygnie_blind_aoe", ((Component)___m_character).transform.position, 0.5f);
						}
					}
				}
				if (__result)
				{
					Faction faction = target.GetFaction();
					if ((int)faction == 3 || (int)faction == 4)
					{
						if (m_holdingDraugrRatTail)
						{
							__result = !WUTIL.TestLuck(0.7f);
						}
						if (__result && (int)Wildling.BiomeClothingBuff == 4)
						{
							__result = !WUTIL.TestLuck(2f * Equipment.HideClothingBuff + 0.5f);
						}
					}
					else if ((int)faction == 5)
					{
						if ((int)Wildling.BiomeClothingBuff == 4)
						{
							__result = !WUTIL.TestLuck(3f * Equipment.HideClothingBuff + 0.5f);
						}
					}
					else if ((int)faction == 7 && (int)Wildling.BiomeClothingBuff == 16)
					{
						__result = !WUTIL.TestLuck(3f * Equipment.HideClothingBuff + 0.5f);
					}
				}
				if (__result && m_holdingRatTail && (text.StartsWith("Skeleton") || text.StartsWith("Draugr") || text == "Ghost"))
				{
					__result = !WUTIL.TestLuck(0.8f);
				}
				if (__result && PlayerHiddenFromTarget(___m_character))
				{
					__result = false;
				}
				else if (!__result && flag && WUTIL.TestLuck(0.2f))
				{
					StopHunt(___m_character);
				}
			}
			else
			{
				string text2 = WUTIL.ActorName(target);
				if (text2 == "Pixie" || text2 == "Ygnie")
				{
					__result = GetClan(___m_character) == "Goblin" || text == "Ghost" || text == "Wraith" || text == "Doxie";
				}
				else if (text2.StartsWith("Rabbit"))
				{
					text2 = text2.Substring(6);
					float num = 0f;
					Biome val2 = Heightmap.FindBiome(((Component)target).transform.position);
					switch (text2)
					{
					case "White":
						num = (((int)val2 == 4) ? 0.95f : 0f);
						break;
					case "Tan":
						num = (((int)val2 == 16) ? 0.95f : 0.2f);
						break;
					case "Grey":
						num = (((int)val2 == 2) ? 0.95f : (((int)val2 == 4) ? 0f : 0.8f));
						break;
					}
					__result = num == 0f || WUTIL.RandomSpin() < num;
				}
			}
			return __result;
		}
	}

	[HarmonyPatch(typeof(Character), "IsTamed", new Type[] { })]
	private class PatchCharacterIsTamed
	{
		public static bool Prefix(Character __instance, ref bool ___m_tamed, ref bool __result)
		{
			if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Tameable>()) || Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Growup>()))
			{
				return true;
			}
			string text = WUTIL.ActorName(__instance);
			if (text == "Ygnie")
			{
				Fairy.YgnieCapture(__instance);
				__result = WUTIL.Timer("ygnie_tamed_cooldown") == 0f;
			}
			else
			{
				__result = Riding.IsRiding(__instance) || IsBeastFriendly(__instance, OrTameable: false);
				if (___m_tamed && !__result)
				{
					WDBUG.Log("Untaming " + text, WDBUG.Level.Taming);
					__instance.SetTamed(false);
					___m_tamed = false;
				}
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(Character), "Awake")]
	private class PatchCharacterAwake
	{
		public static void Postfix(Character __instance)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			Riding.Awake(__instance);
			if (!Fairy.Awoke(__instance) && !World.Unspawn(__instance))
			{
				if ((Object)(object)((Component)__instance).gameObject.GetComponent<Tameable>() == (Object)null)
				{
					__instance.IsTamed();
				}
				if (((Component)__instance).transform.position.y > 5000f)
				{
					bool flag = MountainDungeon.InSnakeBodyRegion(((Component)__instance).transform.position);
					Place.RecustomizeCharacter(__instance, !flag);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Character), "GetHoverName")]
	private class PatchCharacterGetHoverName
	{
		public static void Postfix(Character __instance, ref string __result)
		{
			if ((Object)(object)((Component)__instance).GetComponent<Tameable>() == (Object)null && !((Object)__instance).name.Contains("(Clone"))
			{
				__result = ((Object)__instance).name;
			}
		}
	}

	[HarmonyPatch(typeof(AnimalAI), "UpdateAI")]
	private class PatchAnimalAIUpdateAI
	{
		public static void Postfix(AnimalAI __instance, float dt, ref float ___m_inDangerTimer, ref Character ___m_target)
		{
			Riding.UpdateAI(((Component)__instance).gameObject, dt);
			if ((Object)(object)m_signalUnalert == (Object)(object)__instance)
			{
				m_signalUnalert = null;
				___m_inDangerTimer = __instance.m_timeToSafe;
				___m_target = null;
			}
			else if (((BaseAI)__instance).IsAlerted())
			{
				Character component = ((Component)__instance).gameObject.GetComponent<Character>();
				if (Riding.IsRidingBonded(component))
				{
					___m_inDangerTimer = __instance.m_timeToSafe;
					___m_target = null;
				}
			}
			else
			{
				string text = UpdateConsumeItem((BaseAI)(object)__instance);
				if (text != "" && text != "!")
				{
					FeedAnimal(((Component)__instance).gameObject.GetComponent<Character>(), text);
				}
			}
			TrackScentTypes(((Component)__instance).gameObject.GetComponent<Character>());
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	private class PatchMonsterAIUpdateAI
	{
		private static float m_minFleeDistRun = 0f;

		private static float m_fleeIfLowHealth = -1f;

		public static void Prefix(MonsterAI __instance, ref Character ___m_targetCreature)
		{
			//IL_002f: 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)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer != (Object)null && AutoFlee(__instance))
			{
				___m_targetCreature = (Character)(object)Player.m_localPlayer;
				((Component)__instance).GetComponent<Character>().SetLookDir(((Component)__instance).transform.position - ((Component)___m_targetCreature).transform.position, 0f);
			}
		}

		public static void Postfix(MonsterAI __instance, float dt, ref float ___m_timeSinceSensedTargetCreature, ref Character ___m_targetCreature)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			if (!((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return;
			}
			Riding.UpdateAI(((Component)__instance).gameObject, dt);
			if ((Object)(object)m_signalUnalert == (Object)(object)__instance)
			{
				m_signalUnalert = null;
				___m_timeSinceSensedTargetCreature = 99f;
				___m_targetCreature = null;
			}
			if (m_fleeIfLowHealth >= 0f)
			{
				if (m_fleeIfLowHealth > 99f)
				{
					if (WUTIL.TestLuck())
					{
						((Component)__instance).gameObject.GetComponent<Character>().Damage(new HitData
						{
							m_damage = 
							{
								m_damage = 9999f
							}
						});
					}
					else
					{
						Transform transform = ((Component)__instance).transform;
						transform.position += 100f * Vector3.up;
					}
				}
				else
				{
					__instance.m_fleeIfLowHealth = m_fleeIfLowHealth;
				}
				m_fleeIfLowHealth = -1f;
			}
			TrackScentTypes(((Component)__instance).gameObject.GetComponent<Character>());
		}

		private static bool AutoFlee(MonsterAI monsterAI)
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			Character component = ((Component)monsterAI).gameObject.GetComponent<Character>();
			bool flag = false;
			if (m_characterDazed.ContainsKey(component))
			{
				float num = m_characterDazed[component];
				flag = num < 100f && num > 5f;
			}
			else
			{
				float num2 = 0f;
				if (ElderWand.Turned(component))
				{
					num2 = 3f + component.GetRadius();
				}
				else if (WUTIL.ActorName(component) == "Pixie")
				{
					num2 = 12f;
				}
				if (num2 > 0f)
				{
					num2 -= (float)(((Character)Player.m_localPlayer).IsCrouching() ? 2 : 0);
					if (WUTIL.Timer("flee_dist_update") == 0f)
					{
						m_minFleeDistRun = num2 + (float)WUTIL.DieRoll(9);
						WUTIL.TimerReset("flee_dist_update", WUTIL.RandomSpin(1f, 2.5f));
					}
					float num3 = Vector3.Distance(((Component)component).transform.position, ((Component)Player.m_localPlayer).transform.position);
					if (num3 <= num2)
					{
						((BaseAI)monsterAI).Alert();
					}
					if (num3 < m_minFleeDistRun)
					{
						flag = true;
					}
					else
					{
						if (num3 < m_minFleeDistRun + 6f)
						{
							return false;
						}
						if (num3 > 64f)
						{
							m_fleeIfLowHealth = 100f;
						}
					}
				}
			}
			if (flag && monsterAI.m_fleeIfLowHealth < 2f)
			{
				m_fleeIfLowHealth = monsterAI.m_fleeIfLowHealth;
				monsterAI.m_fleeIfLowHealth = 2f;
			}
			return flag;
		}
	}

	[HarmonyPatch(typeof(BaseAI), "SetAlerted")]
	private class PatchBaseAISetAlerted
	{
		public static void Prefix(BaseAI __instance, ref bool alert)
		{
			if (alert)
			{
				alert = !IsCalmed(((Component)__instance).gameObject.GetComponent<Character>());
			}
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")]
	private class PatchMonsterAIUpdateConsumeItem
	{
		public static void Prefix(ItemDrop ___m_consumeTarget)
		{
			if ((Object)(object)___m_consumeTarget != (Object)null)
			{
				ItemData itemData = ___m_consumeTarget.m_itemData;
				if (itemData == null)
				{
					WDBUG.Log("PatchMonsterAIUpdateConsumeItem detected null ItemData");
				}
				else if ((Object)(object)___m_consumeTarget.m_itemData.m_dropPrefab == (Object)null)
				{
					WUTIL.FixItemPrefab(itemData, "PatchHumanoidDropItem");
				}
			}
		}

		public static void Postfix(MonsterAI __instance, ref bool __result, ItemDrop ___m_consumeTarget)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (__result)
			{
				GameObject gameObject = ((Component)__instance).gameObject;
				string text = WUTIL.GameName(gameObject);
				if (text == "DefiledRoot" && gameObject.transform.localScale.y < 3.5f)
				{
					Humanoid component = gameObject.GetComponent<Humanoid>();
					((Character)component).SetMaxHealth(Mathf.Min(((Character)component).GetMaxHealth() + 2f, 1000f));
					((Character)component).SetHealth(((Character)component).GetHealth() + 2f);
					Transform transform = gameObject.transform;
					transform.localScale += 0.01f * Vector3.one;
					WDBUG.Log($"Growing DefiledRoot to {((Component)__instance).transform.localScale.y} hp: {((Character)component).GetMaxHealth()}", WDBUG.Level.Wildlife);
					Place.Object("digger_undig", ((Component)__instance).transform.position);
				}
			}
			else
			{
				string text2 = UpdateConsumeItem((BaseAI)(object)__instance);
				if (text2 == "!")
				{
					__result = true;
				}
				else if (text2 != "")
				{
					FeedAnimal(((Component)__instance).gameObject.GetComponent<Character>(), text2);
					__result = true;
				}
			}
		}
	}

	[HarmonyPatch(typeof(Tameable), "OnConsumedItem")]
	private class PatchTameableOnConsumedItem
	{
		public static bool Prefix(ItemDrop item, Character ___m_character)
		{
			return (Object)(object)___m_character != (Object)null && (Object)(object)item != (Object)null && item.m_itemData != null;
		}
	}

	[HarmonyPatch(typeof(RandomIdle), "GetRandomIdle")]
	private class PatchRandomIdleGetRandomIdle
	{
		public static void Postfix(ref int __result, Character ___m_character)
		{
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return;
			}
			string text = WUTIL.ActorName(___m_character);
			if (text.StartsWith("Rabbit"))
			{
				if (__result == 9)
				{
					__result = 0;
				}
			}
			else if (text == "Eikthyr")
			{
				WDBUG.Log($"{text} idle: {__result}");
			}
			else if (text == "Deer")
			{
				if (WUTIL.Timer("Deer_consume") > 0f)
				{
					__result = 1;
				}
				else if (Riding.IsRiding(___m_character) && (__result == 1 || IsBonded(___m_character)))
				{
					__result = 0;
				}
			}
		}
	}

	[HarmonyPatch(typeof(Tameable), "IsHungry")]
	private class PatchTameableIsHungry
	{
		public static bool Prefix(Tameable __instance, ref bool __result)
		{
			Character component = ((Component)__instance).gameObject.GetComponent<Character>();
			if (m_characterFoodTime.ContainsKey(component))
			{
				if (WUTIL.ActorName(component) == "Boar")
				{
					__instance.m_commandable = true;
				}
				__result = GetAnimalFedTime(component) <= 10f;
				return false;
			}
			if (__instance.m_commandable && WUTIL.ActorName(component) == "Boar")
			{
				BaseAI baseAI = component.GetBaseAI();
				MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
				if ((Object)(object)val.GetFollowTarget() != (Object)null)
				{
					__instance.Command((Humanoid)(object)Player.m_localPlayer, false);
				}
				__instance.m_commandable = false;
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(CharacterDrop), "OnDeath")]
	private class PatchCharacterDropOnDeath
	{
		public static void Postfix(CharacterDrop __instance)
		{
			ForestDungeon.OnDeath(((Component)__instance).gameObject);
			Loki.OnDeath(((Component)__instance).gameObject);
			Fairy.OnDeath(((Component)__instance).gameObject);
		}
	}

	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	private class PatchCharacterApplyDamage
	{
		public static void Postfix(Character __instance, HitData hit)
		{
			if (!Wildling.IsWildling || !((Object)(object)hit.GetAttacker() == (Object)(object)Player.m_localPlayer) || __instance.GetHealth() > 0f)
			{
				return;
			}
			string text = WUTIL.ActorName(__instance);
			if (text == "Deer")
			{
				if (Wildling.SkillFactor((SkillType)0) > 0.03f)
				{
					Quest.AdvanceAchievement("DeerKilled");
				}
			}
			else if (text == "Greyling")
			{
				if (Wildling.SkillFactor((SkillType)0) > 0.06f)
				{
					Quest.AdvanceAchievement("GreydwarfKilled");
					m_greydwarfReputaion -= 20f;
				}
			}
			else if (text.StartsWith("Greydwarf"))
			{
				if (Wildling.SkillFactor((SkillType)0) > 0.09f)
				{
					Quest.AdvanceAchievement("GreydwarfKilled");
					m_greydwarfReputaion -= 30 * GetClanRank(__instance);
				}
			}
			else if (text.StartsWith("Rat"))
			{
				Quest.AdvanceAchievement("RatsKilled");
			}
			if (Equipment.m_weaponObjectivePass)
			{
				Quest.CheckObjective(2, set: false);
			}
			if (Equipment.m_justThrewPebble)
			{
				Equipment.m_justThrewPebble = false;
				if (Slingshot.m_slingshotPower == 0)
				{
					Quest.AdvanceAchievement("PebbleKilled");
				}
			}
		}
	}

	[HarmonyPatch(typeof(RandomAnimation), "FixedUpdate")]
	private class PatchRandomAnimationFixedUpdate
	{
		public static bool Prefix(RandomAnimation __instance)
		{
			if (Wildling.IsWildling && m_friendlyEikthyr)
			{
				Character component = ((Component)__instance).GetComponent<Character>();
				if ((Object)(object)component != (Object)null && WUTIL.ActorName(component) == "Eikthyr")
				{
					StopHunt(component);
					return false;
				}
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(BaseAI), "IdleMovement")]
	private class PatchBaseAIIdleMovement
	{
		public static bool Prefix(BaseAI __instance)
		{
			return !Quest.IsGathered(((Component)__instance).gameObject.GetComponent<Character>());
		}
	}

	public static int m_treecareReward = 0;

	public static bool m_holdingRatTail = false;

	public static bool m_holdingDraugrRatTail = false;

	public static bool m_friendlyEikthyr = false;

	public static bool m_friendlyElder = false;

	public static bool m_justDropped = false;

	public static bool m_debugIsEnemy = false;

	public static bool m_pixieAttackAdult = false;

	public static bool m_detectScentsInside = true;

	public static float m_greydwarfReputaion = 1000000f;

	public static float m_holdingRabbitFootLuck = 0f;

	public static string m_lastCreatureSeen = "";

	public static string m_lastDroppedItem = "";

	private const float c_mountDistance = 2f;

	private static IDictionary<string, ClanMemberData> m_clanMembers = new Dictionary<string, ClanMemberData>();

	private static IDictionary<string, int> m_clanSize = new Dictionary<string, int>();

	private const float c_clanUnfriendlyCooldown = 5f;

	private const float c_barterDistanceFactor = 0.93f;

	private const float c_gdRecentDropsResetDelay = 120f;

	private const float c_barterReputationMin = -20f;

	private const float c_frientlyReputationMin = -50f;

	private const float c_reputationRecoverRate_GD = 0.1f;

	private const float c_reputationDamageRate_GD = 1f;

	private const float c_reputationMinimum_GD = -1200f;

	private const float c_clanMemberTrustMin = 0.1f;

	private const float c_clanMemberTrustMax = 0.35f;

	private const float c_clanMemberTrustGainPerBarter = 0.005f;

	private const float c_stopHuntMinDF = 0.24f;

	private const float c_unhideUnseenMaxDF = 0.7f;

	private const float c_lookAwayBaseTime = 100f;

	private const float c_nolongerTameTime = 110f;

	private const float c_hiddenMovementFactor = 0.51f;

	private const float c_dazedFleeUntilTime = 5f;

	private const float c_holdingRabbitFootLuck = 0.1f;

	private const float c_luckySeenHidingChance = 0.5f;

	private const float c_luckyUnseenHidingChance = 0.9f;

	private const float c_holdingRatTailProtection = 0.8f;

	private const float c_holdingDraugrRatTailProtection = 0.7f;

	private const float c_pixieJitterRate = 0.2f;

	private const float c_pixieSkipSpeed = 8f;

	private const float c_pixieApproachDistMin = 12f;

	private const float c_pixieApproachDistMax = 30f;

	private const string c_tradeColorQuestTrg = "#8AF";

	private const string c_tradeColorDontcare = "#AA6";

	private const string c_tradeColorCondense = "#CC8";

	private const string c_tradeColorTreecare = "#8C4";

	private const string c_tradeColorExchange = "#CCA";

	private const string c_tradeColorResource = "#FC8";

	private const string c_tradeColorTrophies = "#FDA";

	private const string c_tradeColorInsulted = "#F44";

	private static bool m_ignoreIsEnemyCheck = false;

	private static bool m_wildlingHidden = false;

	private static float m_playerNoEnemyRange = 15f;

	private static BaseAI m_signalUnalert = null;

	private static List<string> m_gdRecentDrops = new List<string>();

	private static Dictionary<string, string> m_scentTypes = new Dictionary<string, string>();

	private static string[] m_gdExchangeItems = "Wood,Raspberry,Mushroom,PebbleRough,Resin,PebbleSmooth,BeechSeeds,Feathers,CarrotSeeds,FirCone,Stone,Blueberries,Coal,Thistle,PineCone,PebbleFine,FineWood,Pukeberries,TurnipSeeds,BirchSeeds,Flint,Dandelion,Carrot,MushroomYellow,OnionSeeds,Acorn,RoundLog,Apples,Cloudberry,MushroomBlue".Split(new char[1] { ',' });

	private static float[] m_gdExchangeItemValues = new float[30]
	{
		0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f,
		1f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f,
		2f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f
	};

	private static string[] m_gdTrophyItems = "BoneFragments,Amber,AmberPearl,QueenBee,Ruby,Crystal,TrophySkeleton,Bloodbag,TrophySkeletonPoison,Ooze,Entrails,Chain,DoxieDust,Root,SurtlingCore,Guck,WitheredBone,TrophyLeech,TrophyBlob,TrophyDraugr,TrophyDraugrFem,TrophyDraugrElite,TrophyWraith,TrophySurtling,TrophyGrowth,TrophyAbomination,TrophyGoblin,TrophyGoblinBrute,TrophyGoblinShaman,TrophyBonemass,TrophyGoblinKing".Split(new char[1] { ',' });

	private static float[] m_gdTrophyItemValues = new float[31]
	{
		0.4f, 0.9f, 1.2f, 1.3f, 1.4f, 1.5f, 2f, 2.2f, 2.25f, 2.3f,
		2.4f, 2.5f, 2.5f, 2.5f, 3f, 3.1f, 3.2f, 3.3f, 3.35f, 3.4f,
		3.5f, 3.6f, 3.7f, 4f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f, 4.6f,
		4.7f
	};

	private static string[] m_gdRewardItems = "BeechSeeds,PineCone,FirCone,Mushroom:3,FineWood,PebbleFine:2,PebbleSmooth:5,Resin:5,Honey:2,Turnip,Cloudberry,Truffle,Onion,Apples:2,Honey:3,Thistle:5,OnionSeeds:3,FineWood:3,RoundLog,Turnip:3,Onion:3,Truffle:3,RoundLog:3,Apples:3,ElderBark,MushroomBlue:3,SilverNecklace,AncientMushroom,KnifeCopper,MeadStaminaMinor,MeadHealthMinor,MeadPoisonResist,MeadStaminaMedium,MeadHealthMedium,MeadFrostResistMeadPoisonResist:5,MeadStaminaMedium:10,MeadHealthMedium:10,MeadFrostResist:10,MeadPoisonResist:10".Split(new char[1] { ',' });

	private static float[] m_gdRewardItemValues = new float[40]
	{
		0.4f, 0.5f, 0.5f, 0.5f, 0.6f, 0.7f, 0.7f, 0.8f, 0.8f, 0.8f,
		0.8f, 0.8f, 1f, 1.1f, 1.2f, 1.25f, 1.3f, 1.3f, 1.3f, 1.35f,
		1.4f, 1.45f, 2f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 3f,
		3.1f, 3.3f, 3.4f, 3.5f, 3.6f, 4f, 4.2f, 4.4f, 4.6f, 4.8f
	};

	private static string[] m_gdInsultItems = "GreydwarfEye,AncientSeed,TrophyGreydwarf,TrophyGreydwarfBrute,TrophyGreydwarfShaman,TrophyEikthyr,TrophyTheElder".Split(new char[1] { ',' });

	private static float[] m_gdInsultItemValues = new float[7] { 0f, 1f, 2f, 2.2f, 2.3f, 2.5f, 3f };

	private const float c_beehiveCheckCooldown = 300f;

	private const float c_consumeSearchRange = 30f;

	private const float c_consumeMinRange = 1f;

	private const float c_consumeRunRangeFactor = 0.2f;

	private const float c_consumeSearchFrequency = 0.2f;

	private const float c_consumeLoseScentChance = 0.01f;

	private const float c_rabbitAttactorStrength = 0.7f;

	private const float c_consumeFishFoodRange = 16f;

	private const float c_consume2ndFoodRange = 4f;

	private const float c_consumeBearBaitPoison = 200f;

	private static Dictionary<string, float> m_consumeRanges = new Dictionary<string, float>
	{
		{ "Bjorn", 1.6f },
		{ "Fenring", 1.2f },
		{ "Fenringlin", 1.2f },
		{ "Deer", 1.9f },
		{ "Boar", 1.4f },
		{ "Wolf", 1.5f },
		{ "Neck", 0.8f }
	};

	private static Dictionary<string, string> m_animalFoods = new Dictionary<string, string>
	{
		{ "RabbitTan", "RabbitBait,6;Carrot,3" },
		{ "RabbitGrey", "RabbitBait,5;Carrot,3" },
		{ "RabbitWhite", "RabbitBait,4;Carrot,3" },
		{ "Deer", "DeerBait,240;Mushroom,180" },
		{ "Neck", "FishRaw,90;Fish,120" },
		{ "Boar", "Truffle,90;DeerBait,120" },
		{ "Ygnie", "Acorn,20" },
		{ "Wolf", "WolfBait,120;RabbitMeat,120" },
		{ "Fenring", "DeadRat,10" },
		{ "Fenringlin", "DeadRat,10" },
		{ "Bjorn", "BearBait,10;Honey,5" }
	};

	private static Dictionary<BaseAI, ItemDrop> m_locatedConsumables = new Dictionary<BaseAI, ItemDrop>();

	private const float c_animalMaxDigest = 3f;

	private const float c_animalFoodTimeLow = 10f;

	private const float c_animalFoodTimeMod = 20f;

	private const float c_animalFoodTimeSnack = 50f;

	private const float c_animalBondedTime = 1024f;

	private const float c_goblinBribePickupTime = 10f;

	private const float c_goblinBribePickupRange = 10f;

	private static Dictionary<Character, float> m_characterFoodTime = new Dictionary<Character, float>();

	private static Dictionary<Character, float> m_animalCalmed = new Dictionary<Character, float>();

	private static Dictionary<Character, float> m_characterDazed = new Dictionary<Character, float>();

	private static Dictionary<Character, float> m_characterStunned = new Dictionary<Character, float>();

	private static Dictionary<Character, float> m_characterBribeAttempt = new Dictionary<Character, float>();

	private static Dictionary<Character, string> m_characterBribeItem = new Dictionary<Character, string>();

	public static void SetupAlignments()
	{
		RegisterClanMember("RabbitTan", "Animal", barter: false, 0.1f);
		RegisterClanMember("RabbitGrey", "Animal", barter: false, 0.1f);
		RegisterClanMember("RabbitWhite", "Animal", barter: false, 0.1f);
		RegisterClanMember("Deer", "Animal", barter: false, 0.1f, 1.008f);
		RegisterClanMember("Rat", "Animal", barter: false, 0.1f);
		RegisterClanMember("Neck", "Animal", barter: false, 0.15f);
		RegisterClanMember("Boar_piggy", "Animal");
		RegisterClanMember("Boar", "Animal");
		RegisterClanMember("Lox_Calf", "Animal");
		RegisterClanMember("Lox", "Animal");
		RegisterClanMember("Wolf_cub", "Animal");
		RegisterClanMember("Wolf", "Animal");
		RegisterClanMember("Bjorn", "Animal");
		RegisterClanMember("Troll", "Troll");
		RegisterClanMember("TrollForest", "Troll");
		RegisterClanMember("Greyling", "Greydwarf", barter: true, 0.3f);
		RegisterClanMember("Greydwarf", "Greydwarf", barter: true, 0.22f);
		RegisterClanMember("Greydwarf_Elite", "Greydwarf", barter: true, 0.18f);
		RegisterClanMember("Greydwarf_Shaman", "Greydwarf", barter: true, 0.18f);
		RegisterClanMember("Greydwarf_Commander", "Greydwarf");
		RegisterClanMember("Greydwarf_Warlock", "Greydwarf");
		RegisterClanMember("TentaRoot", "Greydwarf");
		RegisterClanMember("DefiledRoot", "Greydwarf");
		RegisterClanMember("Goblin", "Goblin");
		RegisterClanMember("GoblinArcher", "Goblin");
		RegisterClanMember("GoblinBrute", "Goblin");
		RegisterClanMember("GoblinShaman", "Goblin");
		RegisterClanMember("Yigath", "Goblin");
		RegisterClanMember("Ngalygoth", "Goblin");
		RegisterClanMember("Uthorax", "Goblin");
	}

	public static void Update(float dt)
	{
		UpdateDigestion(dt);
		UpdateBlinded(dt);
		UpdateStunned(dt);
		UpdateCalmed(dt);
		UpdateBribeAttempt(dt);
		if (m_greydwarfReputaion > 999999f)
		{
			m_greydwarfReputaion = Wildling.GetPlayerData("GDReputation");
		}
		m_greydwarfReputaion -= dt * 0.1f * (float)Math.Sign(m_greydwarfReputaion);
		if (Math.Abs(m_greydwarfReputaion) < dt)
		{
			m_greydwarfReputaion = 0f;
		}
		Wildling.SetPlayerData("GDReputation", m_greydwarfReputaion);
	}

	public static bool ModifyAttack(Attack attack, Character attacker, string weaponName)
	{
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		string text = WUTIL.ActorName(attacker);
		ElderWand.PowerAttacker(attacker, attack);
		switch (text)
		{
		case "Eikthyr":
			if (m_friendlyEikthyr)
			{
				attack.m_attackAnimation = "Eikthyr_antler";
			}
			return false;
		case "gd_king":
			if (m_friendlyElder)
			{
				attack.m_attackAnimation = "gd_king_scream";
			}
			return false;
		case "Ygnie":
			if (IsBribed(attacker, orDazed: true))
			{
				attack.m_projectileBursts = 1;
			}
			else if (WUTIL.TestLuck())
			{
				attack.m_projectileBursts = 3;
			}
			return false;
		case "Neck":
			if (Riding.IsRiding(attacker))
			{
				Riding.ResetNeckXp(attacker, 2);
			}
			break;
		case "Borat":
			if (WasRecentlySeen(text))
			{
				Quest.CheckObjective(38);
				if (attack.m_attackAnimation == "attack_taunt")
				{
					ForestDungeon.RaiseDraugrRats(((Component)attacker).transform.position);
				}
			}
			break;
		case "Greydwarf_Warlock":
			if (attack.m_attackAnimation == "punch")
			{
				Transform attach = attacker.GetVisual().transform.Find("Armature/root/spine1/spine2/spine3/l_shoulder/l_arm1/l_arm2/l_hand/l_middle1/l_middle2/l_middle3");
				WUTIL.CreateAttachedEffect("Greydwarf_Warlock_rootball_fx", attach, -0.5f);
			}
			break;
		default:
			switch (weaponName)
			{
			case "Sparx":
				attack.m_attackAnimation = ((WUTIL.RandomSpin() < 0.5f) ? "attack_cast" : "attack_poke");
				break;
			case "Thorscorn":
				attack.m_attackAnimation = "spear_throw";
				break;
			case "Bowdacious":
				attack.m_attackAnimation = "swing_longsword";
				break;
			}
			break;
		}
		if ((Object)(object)attacker.GetBaseAI().GetTargetCreature() == (Object)(object)Player.m_localPlayer && Fairy.YgnieBlind(attacker))
		{
			attack.Abort();
			return true;
		}
		return false;
	}

	public static bool IsEnemy(Character source, Character target, bool isEnemy)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Invalid comparison between Unknown and I4
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d7: Invalid comparison between Unknown and I4
		//IL_0464: Unknown result type (might be due to invalid IL or missing references)
		//IL_046f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_036e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0528: Unknown result type (might be due to invalid IL or missing references)
		//IL_052a: Invalid comparison between Unknown and I4
		//IL_052c: Unknown result type (might be due to invalid IL or missing references)
		//IL_052e: Invalid comparison between Unknown and I4
		//IL_0589: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e9: Invalid comparison between Unknown and I4
		//IL_0661: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_08f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_08f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_08fb: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)source == (Object)(object)target || source.IsPlayer())
		{
			return isEnemy;
		}
		if (m_ignoreIsEnemyCheck)
		{
			m_ignoreIsEnemyCheck = false;
			return isEnemy;
		}
		Faction faction = source.GetFaction();
		if ((int)faction == 0 || (int)faction == 6)
		{
			return isEnemy;
		}
		if (Quest.GetAchievement("MainTutorial") < 3)
		{
			return isEnemy;
		}
		float num = Vector3.Distance(((Component)source).transform.position, ((Component)target).transform.position);
		string text = WUTIL.ActorName(source);
		string text2 = WUTIL.ActorName(target);
		Player val = (Player)(object)((target is Player) ? target : null);
		bool flag = Wildling.IsWildlingPlayer(val);
		if (m_debugIsEnemy)
		{
			WDBUG.Log("IsEnemy source: " + text + " target: " + text2);
		}
		if (ElderWand.Turned(source))
		{
			return false;
		}
		if (text == "Ygnie")
		{
			return !flag && Fairy.YgnieSeesEnemy(target);
		}
		if (text == "DefiledRoot")
		{
			if (num > 6f && AlertedToPlayer(source))
			{
				StopHunt(source);
			}
			return !flag;
		}
		if (num > 50f)
		{
			SenseCreature(source, AlertDistanceFactor(((Component)source).transform.position));
			return !ElderWand.AffectCharacter(source) && isEnemy;
		}
		if (m_characterDazed.ContainsKey(source))
		{
			return !flag && !(m_characterDazed[source] > 5f) && (source.GetBaseAI().IsAlerted() ? (-0.2f) : 0.1f) + WUTIL.RandomSpin() < AlertDistanceFactor(((Component)source).transform.position);
		}
		if (text == "Fenringlin")
		{
			return WUTIL.RandomSpin() > ((text2 == "Fenring") ? 0.5f : 0.2f) || isEnemy;
		}
		string clan = GetClan(source);
		if ((int)faction == 7 && clan != "Goblin" && ElderWand.IsActive())
		{
			return !target.IsPlayer() && !ElderWand.ObeysElderWand(target) && isEnemy;
		}
		if (!target.IsPlayer())
		{
			if (text2 == "Ygnie" || text2 == "Pixie")
			{
				return text == "Doxie" || text == "Wraith" || text == "Ghost";
			}
			if (ElderWand.IgnoreEnemy(source))
			{
				return false;
			}
			if (Riding.IsRiding(target) || IsBonded(target))
			{
				if (Quest.Protected())
				{
					return false;
				}
				if (faction == target.GetFaction())
				{
					return Vector3.Distance(((Component)source).transform.position, ((Component)target).transform.position) < WUTIL.RandomSpin(0.5f, 2f) && !WUTIL.TestLuck(0.88f);
				}
			}
			return isEnemy;
		}
		if ((Object)(object)target != (Object)(object)Player.m_localPlayer)
		{
			if (flag && ((int)faction == 2 || (m_friendlyEikthyr && text == "Eikthyr") || (m_friendlyElder && text == "gd_king")))
			{
				return false;
			}
			return isEnemy;
		}
		if (text.StartsWith("Rat") && Wildling.RatImmunity())
		{
			return false;
		}
		if (text == "Deathsquito" && Fairy.PinePasteActive())
		{
			if (Vector3.Distance(((Component)source).transform.position, ((Component)target).transform.position) < WUTIL.RandomSpin(2.5f, 3.5f))
			{
				DazeCharacter(source, 5f + WUTIL.RandomSpin(4f, 8f));
			}
			return false;
		}
		if (Riding.IsRiding(source))
		{
			return false;
		}
		if (!isEnemy && IsBeastFamilar(source))
		{
			SenseCreature(source, AlertDistanceFactor(((Component)source).transform.position));
		}
		bool flag2 = !WDBUG.AlignAll;
		if (WUTIL.Timer("SE_DoxieDust") > 0f)
		{
			if (flag2 && (int)faction != 3 && (int)faction != 4)
			{
				return true;
			}
			StopHunt(source);
			return false;
		}
		if (!isEnemy)
		{
			return false;
		}
		if (!flag)
		{
			return (text == "Pixie") ? m_pixieAttackAdult : (!ElderWand.AffectCharacter(source, AlertDistanceFactor(((Component)source).transform.position)));
		}
		float num2 = AlertMovementFactor();
		bool flag3 = ((Character)val).IsCrouching() && num2 <= 0.51f;
		if (!flag3 && !Pocket.IsOpen())
		{
			m_wildlingHidden = true;
		}
		if ((int)faction == 8)
		{
			if ((m_friendlyEikthyr && text == "Eikthyr") || (m_friendlyElder && text == "gd_king"))
			{
				StopHunt(source, tame: true);
				source.GetBaseAI().Alert();
				StunCharacter(source, 5f);
				return false;
			}
			return isEnemy;
		}
		float num3 = AlertDistanceFactor(((Component)source).transform.position);
		SenseCreature(source, num3);
		if (IsBeastFriendly(source, OrTameable: false))
		{
			return false;
		}
		if (source.m_group == "boar")
		{
			MapMarker.CheckTruffleSpawner(((Component)source).transform.position, num3);
		}
		ElderWand.TrackEnemy(source, num3);
		if (ElderWand.AffectCharacter(source, num3))
		{
			return false;
		}
		if (m_friendlyElder && clan == "Greydwarf")
		{
			if (Quest.IsGuide(source))
			{
				WUTIL.Message(source.GetHoverName() + " expects you to follow", center: true, MapMarker.GetCharacterIcon(source), blockNext: false, logOpt: true);
			}
			else if (Quest.GetAchievement("QuestElder") > 7)
			{
				StunCharacter(source);
			}
			return false;
		}
		isEnemy = isEnemy && flag2;
		if (ElderWand.ObeysElderLight(source))
		{
			isEnemy = false;
		}
		float currentTrust = GetCurrentTrust(source);
		if (num3 > DiscoverRadius(source))
		{
			m_wildlingHidden = false;
			return isEnemy;
		}
		if (flag3)
		{
			if (CheckHiddenChased(source, num3))
			{
				isEnemy = false;
			}
		}
		else
		{
			m_wildlingHidden = false;
		}
		if (currentTrust < 0.01f || AlertedToPlayer(source, anyTarget: true))
		{
			return isEnemy;
		}
		if (isEnemy)
		{
			float num4 = 0.5f * WUTIL.RandomSpin() + currentTrust;
			isEnemy = num4 < num3 * num2;
		}
		if (!isEnemy && CanBarter(source, num3))
		{
			if (InPositionToBarter(source))
			{
				bool flag4 = (Object)(object)source == (Object)(object)val.GetHoverCreature();
				WDBUG.Log(text + " in position to barter! In sight: " + flag4, WDBUG.Level.Barter);
				bool flag5 = text == "Greyling";
				if (AssignAllGrabables(source))
				{
					WUTIL.TimerReset("barterListResetCooldown", 10f);
				}
				if (flag4)
				{
					if (m_treecareReward > 0 && !flag5)
					{
						string exchangeItem = GetExchangeItem(source, "treecare", 3);
						Vector3 position = ((Component)source).transform.position + ((Component)source).transform.forward * 2f + Vector3.up;
						ItemData val2 = WUTIL.DropItemOutside(exchangeItem, position, "sfx_greydwarf_elite_alerted", m_treecareReward);
						if (val2 != null)
						{
							string msg = source.GetHoverName() + " rewarded you with " + WUTIL.ItemName(val2, goName: false);
							WUTIL.Message(msg, center: true, MapMarker.GetCharacterIcon(source));
							WUTIL.CustomLog(msg, "#8C4");
							Quest.AdvanceAchievement("Treecare", m_treecareReward);
						}
						m_treecareReward = 0;
					}
					else if (WUTIL.Timer("gd_message_cooldown") == 0f)
					{
						WUTIL.TimerReset("gd_message_cooldown", 6f);
						Sprite characterIcon = MapMarker.GetCharacterIcon(source);
						if (!WUTIL.FlushDelayedMessage(Object.op_Implicit((Object)(object)characterIcon)))
						{
							WUTIL.Message(source.GetHoverName() + (flag5 ? " wants to play." : " is willing to barter."), center: true, characterIcon);
						}
					}
				}
			}
		}
		else if (GetClan(source) == "Greydwarf")
		{
			if (WUTIL.Timer("barterListResetCooldown") == 0f)
			{
				ForgetAllGrabables(source);
				WUTIL.FlushDelayedMessage();
			}
			if (m_greydwarfReputaion < -50f)
			{
				isEnemy = true;
			}
		}
		if (isEnemy)
		{
			AlertClan(source);
		}
		return isEnemy;
	}

	public static bool CheckRecentExchangeDrops(string name, int modify = 0)
	{
		bool flag = m_gdRecentDrops.Contains(name);
		if (flag)
		{
			if (WUTIL.Timer("reset_exchanged_delay") == 0f)
			{
				m_gdRecentDrops.Clear();
				return false;
			}
			if (modify == -1)
			{
				m_gdRecentDrops.Remove(name);
			}
		}
		else
		{
			if (modify == 1)
			{
				m_gdRecentDrops.Add(name);
			}
			WUTIL.TimerReset("reset_exchanged_delay", 120f);
		}
		return flag;
	}

	public static void MoveToTarget(Character character, Vector3 point, bool run)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		if (Pathfinding.instance.GetPath(((Component)character).transform.position, point, list, (AgentType)1, false, true, true))
		{
			while (list.Count > 0)
			{
				if (Utils.DistanceXZ(list[0], ((Component)character).transform.position) > 1f)
				{
					character.GetBaseAI().MoveTowards(list[0] - ((Component)character).transform.position, run);
					break;
				}
				list.RemoveAt(0);
			}
		}
		else
		{
			character.GetBaseAI().MoveTowards(point - ((Component)character).transform.position, run);
		}
	}

	public static bool AlertedToPlayer(Character character, bool anyTarget = false)
	{
		BaseAI baseAI = character.GetBaseAI();
		MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		if (!((BaseAI)val).IsAlerted())
		{
			return false;
		}
		return anyTarget || (Object)(object)((BaseAI)val).GetTargetCreature() == (Object)(object)Player.m_localPlayer;
	}

	public static bool Unalert(Character character, bool unalert = true, float calmTime = 0f)
	{
		bool result = character.GetBaseAI().IsAlerted();
		if (calmTime > 0f)
		{
			CalmAnimal(character, calmTime, calmTime * 2f);
		}
		if (unalert)
		{
			m_signalUnalert = character.GetBaseAI();
		}
		return result;
	}

	public static bool StopHunt(Character character, bool tame = false, bool toggleFollow = false)
	{
		BaseAI baseAI = character.GetBaseAI();
		MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
		if ((Object)(object)val == (Object)null)
		{
			if (tame)
			{
				character.SetTamed(tame);
			}
			return Unalert(character);
		}
		bool flag = ((BaseAI)val).IsAlerted() && (Object)(object)((BaseAI)val).GetTargetCreature() == (Object)(object)Player.m_localPlayer;
		bool tamed = character.IsTamed();
		if (flag || tame)
		{
			val.MakeTame();
		}
		if (!tame)
		{
			character.SetTamed(tamed);
			val.SetFollowTarget((GameObject)null);
		}
		else if (toggleFollow)
		{
			if ((Object)(object)val.GetFollowTarget() == (Object)null)
			{
				((BaseAI)val).ResetPatrolPoint();
				val.SetFollowTarget(((Component)Player.m_localPlayer).gameObject);
				return true;
			}
			val.SetFollowTarget((GameObject)null);
			((BaseAI)val).SetPatrolPoint();
			return false;
		}
		return flag;
	}

	public static void HuntTargetAndAlert(Character character, Character target, bool alert = true)
	{
		if (!Object.op_Implicit((Object)(object)character))
		{
			return;
		}
		BaseAI baseAI = character.GetBaseAI();
		AnimalAI val = (AnimalAI)(object)((baseAI is AnimalAI) ? baseAI : null);
		if ((Object)(object)val != (Object)null)
		{
			if (m_animalCalmed.ContainsKey(character))
			{
				m_animalCalmed.Remove(character);
			}
			character.SetTamed(false);
			((BaseAI)val).Alert();
			return;
		}
		BaseAI baseAI2 = character.GetBaseAI();
		MonsterAI val2 = (MonsterAI)(object)((baseAI2 is MonsterAI) ? baseAI2 : null);
		((BaseAI)val2).ResetPatrolPoint();
		if ((Object)(object)target == (Object)null)
		{
			val2.SetFollowTarget((GameObject)null);
		}
		else
		{
			val2.SetFollowTarget(((Component)target).gameObject);
		}
		if (alert)
		{
			((BaseAI)val2).Alert();
		}
	}

	public static void FlickTarget(Character character, float damage = 0.5f)
	{
		//IL_0014: 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_002e: Expected O, but got Unknown
		if (character.GetHealthPercentage() > 0.99f)
		{
			character.Damage(new HitData
			{
				m_damage = 
				{
					m_damage = 0.5f
				}
			});
		}
	}

	public static void GuardObject(Character character, GameObject target)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		BaseAI obj = ((character != null) ? character.GetBaseAI() : null);
		MonsterAI val = (MonsterAI)(object)((obj is MonsterAI) ? obj : null);
		if (!((Object)(object)target == (Object)null) && !((Object)(object)val == (Object)null))
		{
			val.MakeTame();
			character.SetTamed(false);
			val.SetFollowTarget(target);
			WDBUG.Log($"Guarding {WUTIL.GameName(target)} at pos: {target.transform.position}");
		}
	}

	public static void BribeCharacter(Character character, float duration, bool hire = false)
	{
		if (duration <= 0f)
		{
			DazeCharacter(character, duration);
			return;
		}
		DazeCharacter(character, duration + 100f);
		StopHunt(character, hire, hire);
	}

	public static void ConfuseCharacter(Character character, float duration = 10f)
	{
		//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_0008: 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_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected I4, but got Unknown
		Faction faction = character.GetFaction();
		Faction val = faction;
		switch ((int)val)
		{
		case 0:
		case 1:
		case 3:
		case 8:
			return;
		case 4:
			if (!WUTIL.TestLuck())
			{
				return;
			}
			break;
		}
		WDBUG.Log($"Confuse {character.GetHoverName()} for {duration}s", WDBUG.Level.Chimes);
		StunCharacter(character);
		float num = character.GetRadius();
		if (GetClan(character) == "Goblin" && !m_characterDazed.ContainsKey(character))
		{
			Unalert(character);
			BribeCharacter(character, duration * 3f);
			num *= 0.25f;
		}
		else
		{
			DazeCharacter(character, duration);
			if (IsCalmed(character))
			{
				CalmAnimal(character, 0f);
				character.GetBaseAI().Alert();
			}
			else
			{
				Unalert(character, unalert: true, 3f);
			}
		}
		WUTIL.CreateHeadEffect("chimes_confuse_fx", character, attach: true, num);
	}

	public static bool DazeCharacter(Character character, float duration)
	{
		if (m_characterDazed.ContainsKey(character))
		{
			m_characterDazed[character] = duration;
		}
		else if (duration > 0f)
		{
			m_characterDazed.Add(character, duration);
			return true;
		}
		return false;
	}

	public static void StunCharacter(Character character, float minDuration = 1f, float maxDuration = 3f)
	{
		if (maxDuration <= minDuration)
		{
			m_characterStunned[character] = minDuration;
		}
		else
		{
			m_characterStunned[character] = WUTIL.RandomSpin(minDuration, maxDuration, 0.1f);
		}
		character.GetBaseAI().StopMoving();
	}

	public static void CalmAnimal(Character character, float minDuration = 1f, float maxDuration = 1f)
	{
		if (minDuration <= 0f)
		{
			m_animalCalmed.Remove(character);
		}
		else if (maxDuration <= minDuration)
		{
			m_animalCalmed[character] = minDuration;
		}
		else
		{
			m_animalCalmed[character] = WUTIL.RandomSpin(minDuration, maxDuration, 0.1f);
		}
	}

	public static bool IsCalmed(Character character)
	{
		return !((Object)(object)character == (Object)null) && m_animalCalmed.ContainsKey(character);
	}

	public static bool IsParalyzed(Character character)
	{
		return (Object)(object)character != (Object)null && m_characterStunned.ContainsKey(character);
	}

	public static bool IsBribed(Character character, bool orDazed = false)
	{
		if ((Object)(object)character == (Object)null || !m_characterDazed.ContainsKey(character))
		{
			return false;
		}
		return orDazed || m_characterDazed[character] > 100f;
	}

	public static void IgnoreNextIsEnemyCheck()
	{
		m_ignoreIsEnemyCheck = true;
	}

	public static void SetHidden(bool hidden = true)
	{
		m_wildlingHidden = hidden & Wildling.IsWildling;
	}

	public static void PlayerDroppedItem(ItemData item, int amount = 1)
	{
		//IL_002b: 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)
		//IL_003b: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: 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)
		m_justDropped = true;
		m_lastDroppedItem = WUTIL.ItemName(item);
		CheckRecentExchangeDrops(m_lastDroppedItem, -1);
		Transform transform = ((Component)Player.m_localPlayer).transform;
		Vector3 position = transform.position + 4f * transform.forward;
		float itemCoinValue = Pocket.GetItemCoinValue(item, amount);
		Character val;
		if (itemCoinValue >= 1f)
		{
			val = World.ClosestCharacter(position, "Goblin");
			if ((Object)(object)val != (Object)null)
			{
				if (StopHunt(val))
				{
					val.GetBaseAI().StopMoving();
				}
				AttemptBribe(val, item);
				return;
			}
		}
		val = World.ClosestCharacter(position, "Greydwarf", 3f);
		if ((Object)(object)val == (Object)null)
		{
			val = World.ClosestCharacter(position, "Greyling", 3f);
		}
		if ((Object)(object)val != (Object)null && !GetTakeableItems(val).Contains(m_lastDroppedItem))
		{
			string msg = val.GetHoverName() + " did not seem interested in " + WUTIL.ItemName(item, goName: false);
			WUTIL.DelayedMessage(msg, 5f, MapMarker.GetCharacterIcon(val));
			WUTIL.CustomLog(msg, "#AA6");
			WUTIL.TimerReset("gd_message_cooldown", 3f);
			Quest.HelpWithBarter(GetClanRank(val));
		}
		if (m_lastDroppedItem == "RabbitBait")
		{
			float num = (PlayerIsHiding() ? 25 : 30) + ((!WUTIL.TestLuck()) ? 10 : 0);
			WDBUG.Log($"Dropped rabbit bait, spawn attempt at dist: {num}", WDBUG.Level.Taming);
			World.SpawnLocalRabbit(num, num + 10f, 3f);
		}
	}

	public static bool PlayerIsHiding()
	{
		if (((Character)Player.m_localPlayer).IsCrouching())
		{
			if (Equipment.HideClothingBuff >= 0.04f)
			{
				return true;
			}
		}
		else
		{
			m_wildlingHidden = false;
		}
		return m_wildlingHidden;
	}

	public static bool PlayerHiddenFromTarget(Character target = null)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)target == (Object)null)
		{
			return PlayerIsHiding();
		}
		if (!PlayerIsHiding())
		{
			return false;
		}
		return HiddenAtDistance(AlertDistanceFactor(((Component)target).transform.position));
	}

	public static float CharacterScentPower(Character character)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected I4, but got Unknown
		float num = 1f;
		Faction faction = character.GetFaction();
		Faction val = faction;
		switch ((int)val)
		{
		case 3:
			num = 2f;
			break;
		case 4:
		case 5:
		case 6:
			num = 4f;
			break;
		case 7:
			num = 8f;
			break;
		case 0:
		case 11:
			num = (character.IsTamed() ? 2 : 0);
			break;
		}
		Humanoid component = ((Component)character).GetComponent<Humanoid>();
		return num + (((Object)(object)component == (Object)null) ? 0f : (0.01f * ((Character)component).GetMaxHealth()));
	}

	public static void UpdateLuckyCharms()
	{
		m_holdingRabbitFootLuck = ((WUTIL.GetInventoryItemData("RabbitFoot") == null) ? 0f : 0.1f);
		m_holdingRatTail = WUTIL.GetInventoryItemData("RatTail") != null;
		m_holdingDraugrRatTail = WUTIL.GetInventoryItemData("RatTailDraugr") != null;
	}

	public static float AlertDistanceFactor(Vector3 targetPos)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: 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_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: 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_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = targetPos - ((Component)Player.m_localPlayer).transform.position;
		float num = val.x * val.x + val.y * val.y + val.z * val.z;
		return Mathf.Exp((0f - num) / 400f);
	}

	public static bool WasRecentlySeen(string target, bool reset = false)
	{
		if (target == "")
		{
			return WUTIL.Timer("eyeContactCooldown") > 0f;
		}
		if (target == "Truffle")
		{
			target = "Boar";
		}
		if (reset)
		{
			m_lastCreatureSeen = target;
			WUTIL.TimerReset("eyeContactCooldown", 10f);
			return true;
		}
		return WUTIL.Timer("eyeContactCooldown") > 0f && target == m_lastCreatureSeen;
	}

	public static bool UpdateHoverReport()
	{
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_035d: Unknown result type (might be due to invalid IL or missing references)
		if (!Wildling.IsWildling || TextViewer.instance.IsVisible())
		{
			return false;
		}
		Player localPlayer = Player.m_localPlayer;
		Character hoverCreature = localPlayer.GetHoverCreature();
		if ((Object)(object)hoverCreature == (Object)null || Pocket.LostContact(hoverCreature))
		{
			return false;
		}
		string hoverName = hoverCreature.GetHoverName();
		WasRecentlySeen(hoverName, reset: true);
		string text = "";
		string clan = GetClan(hoverCreature);
		string text2 = ((WUTIL.GameName(((Component)hoverCreature).gameObject) == hoverName) ? ("the " + hoverName) : hoverName);
		if (clan == "Goblin")
		{
			text = Pocket.PickReady(hoverCreature);
			if (text == "yes")
			{
				text = WUTIL.KeyHighlightText("Use") + " to pickpocket " + hoverName;
			}
		}
		else if (clan == "Animal")
		{
			if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)hoverCreature).transform.position) > 2f)
			{
				return false;
			}
			bool flag = hoverCreature.IsTamed();
			if (Quest.Compelled(hoverCreature))
			{
				flag = true;
				text = hoverName + " wants to take you somewhere.";
			}
			else if ((Object)(object)((Component)hoverCreature).GetComponent<Tameable>() != (Object)null)
			{
				text = hoverCreature.GetHoverText();
			}
			else if (flag)
			{
				string tamedStatus = GetTamedStatus(hoverCreature);
				if (tamedStatus == "")
				{
					return false;
				}
				text = hoverName + " (" + tamedStatus + ")";
				if (tamedStatus.StartsWith("Frightened"))
				{
					text = text + "\n" + WUTIL.KeyHighlightText("Use") + " to calm " + text2 + ".";
				}
			}
			if (flag)
			{
				if (Riding.IsRiding(hoverCreature))
				{
					if ((Object)(object)((Component)hoverCreature).gameObject.GetComponent<Tameable>() == (Object)null)
					{
						text = text + "\n" + WUTIL.KeyHighlightText("Use") + " to calm " + text2;
					}
					text = text + "\n(" + WUTIL.KeyHighlightText("Use") + " otherwise to dismount " + text2 + ")";
				}
				else if (Riding.IsRidable(hoverCreature))
				{
					string alt = Localization.instance.Localize(WUTIL.KeyHighlightText("Block", "", braces: false));
					text = text + "\n" + WUTIL.KeyHighlightText("Use", alt) + " to ride " + text2 + ".";
				}
			}
		}
		if (text == "")
		{
			return false;
		}
		((TMP_Text)Hud.instance.m_hoverName).text = text;
		((Graphic)Hud.instance.m_crosshair).color = Color.yellow;
		return true;
	}

	public static bool Interact(GameObject go)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		if (!Wildling.IsWildling || World.PlayerInInterior())
		{
			return false;
		}
		Character component = go.GetComponent<Character>();
		if ((Object)(object)component == (Object)null)
		{
			if ((Object)(object)go.transform.parent != (Object)null)
			{
				go = ((Component)go.transform.parent).gameObject;
			}
			if (WUTIL.GameName(((Object)go).name) == "Beehive")
			{
				if (Vector3.Distance(go.transform.position, ((Component)Player.m_localPlayer).transform.position) >= 2.5f)
				{
					WUTIL.Message("Move closer to check for honey.");
				}
				else
				{
					if (WUTIL.Timer("beehive_interact_cooldown") > 0f)
					{
						return true;
					}
					WUTIL.TimerReset("beehive_interact_cooldown", 2f);
					if (WUTIL.Timer("beehive_check_cooldown") == 0f)
					{
						WUTIL.TimerReset("beehive_check_cooldown", 300f);
						if (WUTIL.TestLuck(0.7f))
						{
							WUTIL.Message("You found honey!");
							Place.Object("Honey", go.transform.position);
							Quest.AdvanceAchievement("HoneyTaken");
							return true;
						}
					}
					WUTIL.Message("You did not find honey.");
				}
				return true;
			}
			return false;
		}
		string clan = GetClan(component);
		if (clan == "Goblin")
		{
			return Pocket.Open(component);
		}
		if (Riding.IsRiding(component))
		{
			if ((Object)(object)Player.m_localPlayer.GetHoverCreature() != (Object)(object)component)
			{
				Riding.Dismount(signal: true);
				return true;
			}
		}
		else if (Riding.IsRidable(component))
		{
			if (WUTIL.GetButton("Block"))
			{
				return Riding.Mount(component);
			}
			if ((Object)(object)((Component)component).GetComponent<Tameable>() == (Object)null && Input.GetKey((KeyCode)304))
			{
				if (IsBonded(component))
				{
					WDBUG.Log("Full bonded Rename not implemented");
					RenameCharacter(component);
				}
				return false;
			}
		}
		if (clan == "Animal" || clan == "Greydwarf")
		{
			float num = (float)(component.GetLevel() / 2) + ((clan == "Animal") ? 1f : (1.5f * (float)GetClanRank(component)));
			float chance = Wildling.SkillFactor((SkillType)0) / 2f + 0.1f - 0.05f * num;
			bool flag = Riding.IsRiding(component) || IsBonded(component);
			if (flag || WUTIL.TestLuck(chance))
			{
				int num2 = WUTIL.DieRoll();
				float num3 = 0.2f + 0.1f * (float)num2;
				if (Unalert(component))
				{
					WUTIL.CreateAttachedEffect("fx_boar_pet", ((Component)component).transform, 0f, 0f, num3);
				}
				else if (WUTIL.ActorName(component) == "Neck")
				{
					if (component.IsSwimming() && GetTamedStatus(component, asSpeed: true) == "stop" && num2 >= 3 && (flag || Flight.GetHeightAboveSolid(((Component)component).transform.position) > 5f))
					{
						SetAnimalFoodTime(component, WUTIL.TestLuck(0.1f) ? (80 + num2) : (3 * num2 - 6));
					}
					WUTIL.CreateAttachedEffect("fx_boar_pet", ((Component)component).transform, 0f, 0f, num3);
				}
				else
				{
					StopHunt(component);
					WUTIL.CreateAttachedEffect("fx_wolf_pet", ((Component)component).transform, 0f, 0f, 2f * num3);
				}
			}
			return (Object)(object)go.GetComponent<Tameable>() == (Object)null;
		}
		if (WUTIL.ActorName(component) == "Ygnie")
		{
			Fairy.YgnieInteract();
		}
		return false;
	}

	public static void SetAnimalFoodTime(Character character, float foodTime)
	{
		m_characterFoodTime[character] = (IsBonded(character) ? (1024f + foodTime) : foodTime);
	}

	public static bool SetBonded(Character character, bool bond = true)
	{
		if (Quest.Protected())
		{
			return false;
		}
		float num = (m_characterFoodTime.ContainsKey(character) ? m_characterFoodTime[character] : 0f);
		if (num >= 1024f)
		{
			if (!bond)
			{
				m_characterFoodTime[character] -= 1024f;
			}
		}
		else if (bond)
		{
			m_characterFoodTime[character] = num + 1024f;
			WUTIL.Message(character.GetHoverName() + " has bonded with you.");
			return true;
		}
		return false;
	}

	public static bool IsBonded(Character character)
	{
		return (Object)(object)character != (Object)null && m_characterFoodTime.ContainsKey(character) && m_characterFoodTime[character] >= 1024f;
	}

	public static float GetAnimalFedTime(Character character, bool unbound = true)
	{
		if ((Object)(object)character != (Object)null && m_characterFoodTime.ContainsKey(character))
		{
			float num = m_characterFoodTime[character];
			return (unbound && num >= 1024f) ? (num - 1024f) : num;
		}
		return 0f;
	}

	public static bool IsBeastFriendly(Character character, bool OrTameable = true)
	{
		return (OrTameable && Object.op_Implicit((Object)(object)((Component)character).GetComponent<Tameable>())) || WUTIL.ActorName(character) == "Ygnie" || IsBonded(character) || Quest.Compelled(character) || GetAnimalFedTime(character) > 0f;
	}

	public static bool IsBeastFamilar(Character character)
	{
		return character.IsTamed() || GetAnimalFedTime(character) > 0f;
	}

	public static string GetTamedStatus(Character character, bool asSpeed = false, bool showFoodTime = false)
	{
		if ((Object)(object)character == (Object)null)
		{
			WDBUG.Log("GetTamedStatuse passed character = null");
			return "";
		}
		if (Quest.Protected())
		{
			return "Compelled";
		}
		float animalFedTime = GetAnimalFedTime(character);
		if (character.GetHoverName() == "Ygnie")
		{
			return (!(animalFedTime > 0f)) ? (asSpeed ? "march" : "") : (asSpeed ? "dart" : "Energized");
		}
		Tameable component = ((Component)character).GetComponent<Tameable>();
		string text = "";
		string text2 = "Hungry";
		bool flag = character.IsRunning();
		if (IsBonded(character))
		{
			if (asSpeed && animalFedTime <= 0f)
			{
				return "march";
			}
			text = "Bonded, ";
		}
		else if (animalFedTime <= 0f)
		{
			if ((Object)(object)component != (Object)null && !component.IsHungry())
			{
				if (asSpeed)
				{
					return flag ? "run" : "walk";
				}
				text2 = "Happy";
			}
			else
			{
				if (asSpeed)
				{
					return ((Object)(object)component == (Object)null) ? "stop" : "march";
				}
				text = "Unhappy, ";
			}
		}
		if (animalFedTime > 10f)
		{
			string consumeTarget = GetConsumeTarget(character, 0, foodTime: true);
			if (!float.TryParse(consumeTarget, out var result))
			{
				WDBUG.Log("Could not get foodTime '" + consumeTarget + "' for " + WUTIL.ActorName(character), WDBUG.Level.warn, 2f);
				result = 60f;
			}
			if (asSpeed)
			{
				return (!flag) ? "walk" : ((animalFedTime < 0.9f * result) ? "run" : "sprint");
			}
			text2 = ((animalFedTime <= result) ? "Happy" : "Enamored");
		}
		return text + text2 + (showFoodTime ? (" " + (int)animalFedTime) : "");
	}

	public static bool IsHungry(Character character, bool orPeckish = false)
	{
		if ((Object)(object)((Component)character).GetComponent<Tameable>() != (Object)null && !((Component)character).GetComponent<Tameable>().IsHungry())
		{
			return orPeckish;
		}
		return GetAnimalFedTime(character) <= (orPeckish ? 50f : 20f);
	}

	public static void RenameCharacter(Character character, string name = "")
	{
		ZNetView component = ((Component)character).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null)
		{
			WDBUG.Log("RenameTamedCharacter did not get ZNetView");
		}
		else if (component.IsValid() && component.IsOwner())
		{
			if (!(name == "?") && name == "")
			{
				name = Game.instance.GetPlayerProfile().GetName() + "'s " + Localization.instance.Localize(character.m_name);
			}
			WDBUG.Log("Naming " + character.GetHoverName() + " to " + name, WDBUG.Level.Taming);
			if (Object.op_Implicit((Object)(object)((Component)character).GetComponent<Tameable>()))
			{
				component.GetZDO().Set("TamedName", name);
			}
			else
			{
				((Object)character).name = name;
			}
		}
	}

	public static string GetClan(Character character)
	{
		ClanMemberData clanMemberData = GetClanMemberData(character);
		return (clanMemberData == null) ? "" : clanMemberData.m_clan;
	}

	public static int GetClanRank(Character character)
	{
		return GetClanMemberData(character)?.m_rank ?? 0;
	}

	public static void AlertClan(Character character, float cooldown = 5f)
	{
		if (character.GetBaseAI().IsAlerted())
		{
			string clan = GetClan(character);
			if (clan != "")
			{
				WUTIL.TimerReset(clan, cooldown);
			}
		}
	}

	public static int NumTraderItems()
	{
		return m_gdExchangeItems.Length - 1;
	}

	public static int NumHunterTrophies()
	{
		return m_gdTrophyItems.Length;
	}

	public static void SummerizeBarterLog(bool replace = false)
	{
		if (replace)
		{
			WUTIL.CustomLog("", "", add: false, remove: true, resort: true);
		}
		int achievement = Quest.GetAchievement("Trader");
		bool flag = Quest.GetAchievement("Barter", 2) > 0 && Wildling.SkillFactor((SkillType)0) <= 16f;
		string text = "";
		string text2 = "Greyling";
		int num = 1;
		int num2 = 2;
		while (num <= m_gdExchangeItems.Length)
		{
			if (num == 10 || num == 20 || num == m_gdExchangeItems.Length)
			{
				if (text != "")
				{
					WUTIL.CustomLog(text2 + " can give you " + WrittenList(text) + ".", "#CC8");
					text = "";
				}
				text2 = ((num == 20 && flag) ? "Greydwarf elite" : "Greydwarf");
			}
			if ((achievement & num2) > 0)
			{
				text = text + ((text == "") ? "" : ", ") + WUTIL.ItemName(m_gdExchangeItems[num]);
			}
			num++;
			num2 <<= 1;
		}
		achievement = Quest.GetAchievement("Hunter");
		string text3 = "";
		string text4 = "";
		string text5 = "";
		bool flag2 = false;
		bool flag3 = false;
		int num3 = 0;
		int num4 = 1;
		while (num3 <= m_gdTrophyItems.Length)
		{
			if ((achievement & num4) > 0)
			{
				string text6 = m_gdTrophyItems[num3];
				if (text6 == "Guck")
				{
					flag2 = true;
				}
				else if (text6 == "SurtlingCore")
				{
					flag3 = Quest.GetAchievement("Barter", 5) > 0;
				}
				if (text6.StartsWith("Trophy"))
				{
					text6 = WUTIL.ItemName(text6);
					int num5 = text6.LastIndexOf(" Trophy");
					text3 = text3 + ((text3 == "") ? "" : ", ") + ((num5 > 0) ? text6.Remove(num5) : text6);
				}
				else if (num3 >= 1 && num3 <= 5)
				{
					text5 = text5 + ((text5 == "") ? "" : ", ") + WUTIL.ItemName(text6);
				}
				else
				{
					text4 = text4 + ((text4 == "") ? "" : ", ") + WUTIL.ItemName(text6);
				}
			}
			num3++;
			num4 <<= 1;
		}
		if (text5 != "")
		{
			WUTIL.CustomLog("Greydwarf seem to like " + WrittenList(text5) + ".", "#FDA");
		}
		if (text4 != "")
		{
			WUTIL.CustomLog("Greydwarf accept " + WrittenList(text4) + " as undead trophies.", "#FDA");
		}
		if (flag2)
		{
			if (Quest.GetAchievement("Treecare") > 0)
			{
				WUTIL.CustomLog("Greydwarf reward you for planting trees and take Guck as evidence of treecare.", "#8C4");
			}
			else
			{
				WUTIL.CustomLog("Greydwarf accept Guck as evidence of treecare.", "#8C4");
			}
		}
		else if (Quest.GetAchievement("Treecare") > 0)
		{
			WUTIL.CustomLog("Greydwarf will reward you for planting saplings.", "#8C4");
		}
		if (text3 != "")
		{
			WUTIL.CustomLog("Greydwarf appreciate enemy " + WrittenList(text3) + " trophies.", "#FDA");
		}
		if (flag3)
		{
			WUTIL.CustomLog("Greydwarf shaman will give you a surtling spike for a surtling core.", "#8AF");
		}
		if (Quest.GetAchievement("Barter", 7) > 0)
		{
			WUTIL.CustomLog("Greydwarf shaman will give you elderberries for Abomination roots.", "#8AF");
		}
	}

	public static string GetMarkerName(Character character)
	{
		//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_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Invalid comparison between Unknown and I4
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Invalid comparison between Unknown and I4
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Invalid comparison between Unknown and I4
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Invalid comparison between Unknown and I4
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Invalid comparison between Unknown and I4
		Faction faction = character.GetFaction();
		if ((int)faction == 1 || (int)faction == 8 || (int)faction == 6)
		{
			WDBUG.Log("Unknown marker faction: " + ((object)(Faction)(ref faction)).ToString());
			return "";
		}
		string text = GetClan(character);
		string text2 = WUTIL.ActorName(character);
		if (text == "Animal")
		{
			string text3 = "Pet" + text2;
			text = ((text2 == "Pixie" || text2 == "Ygnie") ? "" : ((IsBeastFamilar(character) && MapMarker.IsScentMarker(text3)) ? text3 : ((text2 == "Neck") ? text2 : "Animal")));
		}
		else if ((int)faction == 0)
		{
			text = (((Character)Player.m_localPlayer).IsPVPEnabled() ? "Enemy" : "Ally");
		}
		else if ((int)faction == 4)
		{
			text = "Demon";
		}
		else if ((int)faction == 3)
		{
			if (text2.StartsWith("Skeleton"))
			{
				text = "Undead";
			}
			else if (text2.StartsWith("Draugr"))
			{
				text = "Undead1";
			}
			else
			{
				switch (text2)
				{
				default:
					if (!(text2 == "Doxie"))
					{
						text = "Undead3";
						break;
					}
					goto case "Ghost";
				case "Ghost":
				case "Wraith":
				case "Witherin":
					text = "Undead2";
					break;
				}
			}
		}
		else if (text == "")
		{
			text = ((text2 == "Hatchling") ? "" : "Monster");
		}
		return text;
	}

	public static string GetNextMarker(string name)
	{
		if (name == "Deer")
		{
			return "DeerMeat";
		}
		if (name.StartsWith("Rabbit"))
		{
			return "RabbitMeat";
		}
		if (name.StartsWith("Rat"))
		{
			return "RatMeat";
		}
		if (name.StartsWith("Boar"))
		{
			return "BoarMeat";
		}
		if (name.StartsWith("Wolf"))
		{
			return "WolfMeat";
		}
		if (name.StartsWith("Lox"))
		{
			return "LoxMeat";
		}
		if (name.StartsWith("Bjorn"))
		{
			return "BjornMeat";
		}
		return "";
	}

	public static void SummarizeKnownScents(bool replace = true)
	{
		if (replace)
		{
			WUTIL.CustomLog("", "", add: false, remove: true, resort: true);
		}
		string text = "You know the ";
		string text2 = "";
		string text3 = "";
		string text4 = "";
		string text5 = "";
		string text6 = "";
		string text7 = "";
		foreach (string knownScent in MapMarker.GetKnownScents())
		{
			if (!m_scentTypes.ContainsKey(knownScent))
			{
				continue;
			}
			string text8 = (m_scentTypes.ContainsKey(knownScent) ? m_scentTypes[knownScent] : "");
			if (text8 == "Animal" || text8 == "Neck")
			{
				string text9 = ((knownScent.EndsWith("rabbit") || knownScent.EndsWith("bunny")) ? "Rabbit" : knownScent);
				if (!text2.Contains(text9))
				{
					text2 = text2 + ((text2 == "") ? "" : ", ") + text9;
				}
				continue;
			}
			switch (text8)
			{
			case "Greydwarf":
				text7 = text7 + ((text7 == "") ? "" : ", ") + knownScent;
				break;
			default:
				if (!(text8 == "Pixie"))
				{
					if (text8.StartsWith("Undead"))
					{
						string text10 = (knownScent.StartsWith("Draugr") ? "Draugr" : knownScent);
						if (!text3.Contains(text10))
						{
							text3 = text3 + ((text3 == "") ? "" : ", ") + text10;
						}
						break;
					}
					if (text8 == "Monster" || text8 == "Goblin" || text8 == "Monster")
					{
						if (!text5.Contains(knownScent))
						{
							text5 = text5 + ((text5 == "") ? "" : ", ") + knownScent;
						}
						break;
					}
					switch (text8)
					{
					default:
						if (!text8.StartsWith("Pet"))
						{
							goto end_IL_013c;
						}
						break;
					case "Ally":
					case "Enemy":
					case "Ygnie":
						break;
					}
					text6 = text6 + ((text6 == "") ? "" : ", ") + knownScent;
					break;
				}
				goto case "Demon";
			case "Demon":
			case "Undead3":
				{
					text4 = text4 + ((text4 == "") ? "" : ", ") + knownScent;
					break;
				}
				end_IL_013c:
				break;
			}
		}
		if (text6 != "")
		{
			WUTIL.CustomLog(text + "familiar scent of " + WrittenList(text6) + ".");
		}
		if (text2 != "")
		{
			WUTIL.CustomLog(text + "beastly smell of " + WrittenList(text2) + ".");
		}
		if (text7 != "")
		{
			WUTIL.CustomLog(text + "woody smell of " + WrittenList(text7) + ".");
		}
		if (text3 != "")
		{
			WUTIL.CustomLog(text + "ghastly odor of " + WrittenList(text3) + ".");
		}
		if (text5 != "")
		{
			WUTIL.CustomLog(text + "monsterous stench of " + WrittenList(text3) + ".");
		}
		if (text4 != "")
		{
			WUTIL.CustomLog(text + "otherworldly presence of " + WrittenList(text4) + ".");
		}
	}

	public static void CheckObjectives(string itemGiven = "", bool refresh = false)
	{
		if (itemGiven != "")
		{
			int num = Array.IndexOf(m_gdExchangeItems, itemGiven);
			if (num > 0 && Quest.SetAchievement("Trader", num, bit: true))
			{
				WUTIL.PlaySecretFoundSfx();
			}
		}
		if (Quest.CheckObjective(9, set: true, test: true) && Quest.GetAchievement("Treecare") >= 10 && Quest.GetAchievement("Treeportal") > 10)
		{
			Quest.CheckObjective(9, set: false);
		}
		int achievement = Quest.GetAchievement("Barter");
		if (achievement == 0 || achievement >= 255)
		{
			return;
		}
		int achievement2 = Quest.GetAchievement("Trader");
		bool flag = (achievement2 & 0x240) == 576;
		bool flag2 = (achievement2 & 0x4010000) == 67174400;
		int achievement3 = Quest.GetAchievement("BarterDreamState");
		if (flag)
		{
			Quest.CheckObjective(22, set: false);
		}
		else if (achievement3 >= 2)
		{
			Quest.CheckObjective(22, set: true, test: false, refresh);
		}
		if (achievement != 1)
		{
			Quest.CheckObjective(7, set: false);
			if (flag2)
			{
				Quest.CheckObjective(23, set: false);
			}
			else if (achievement3 >= 4 || flag)
			{
				Quest.CheckObjective(23, set: true, test: false, refresh);
			}
			if ((achievement & 0x10) > 0)
			{
				Quest.CheckObjective(24, set: false);
			}
			else if ((achievement & 4) > 0)
			{
				Quest.CheckObjective(24, set: true, test: false, refresh);
			}
			if ((achievement & 0x20) > 0)
			{
				Quest.CheckObjective(25, set: false);
				Quest.CheckObjective(24);
			}
			else if (achievement3 >= 7 || (achievement & 8) > 0)
			{
				Quest.CheckObjective(25, set: true, test: false, refresh);
			}
			if ((achievement & 0x40) > 0)
			{
				Quest.CheckObjective(26, set: false);
			}
			else if (achievement3 >= 8 && (achievement & 8) > 0)
			{
				Quest.CheckObjective(26, set: true, test: false, refresh);
			}
		}
	}

	private static string WrittenList(string csvList)
	{
		int num = csvList.LastIndexOf(',');
		return ((num > 0) ? (csvList.Remove(num) + " and" + csvList.Substring(num + 1)) : csvList).ToLower();
	}

	private static bool HiddenAtDistance(float distanceFactor)
	{
		float num = (EnvMan.IsDaylight() ? 0.8f : 1f);
		float num2 = 0.5f * (Wildling.SkillFactor((SkillType)0) + num + Equipment.HideClothingBuff);
		return distanceFactor < num2;
	}

	private static float GetCurrentBarterLevel(Character character)
	{
		return GetCurrentTrust(character) - 0.3f + Wildling.BarterBuff;
	}

	private static float GetCurrentTrust(Character character)
	{
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Invalid comparison between Unknown and I4
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Invalid comparison between Unknown and I4
		string clan = GetClan(character);
		if (clan == "" || WUTIL.Timer(clan) > 0f)
		{
			return 0f;
		}
		float num = GetClanMemberData(character).m_trust;
		if (clan == "Greydwarf")
		{
			if (m_greydwarfReputaion < -10f)
			{
				return 0f;
			}
			if (m_greydwarfReputaion < 0f)
			{
				num /= 2f;
			}
			else if (m_greydwarfReputaion > 0f)
			{
				float num2 = Mathf.Min(2f, 0.01f * m_greydwarfReputaion);
				num *= 1f + num2;
			}
		}
		num += Wildling.SkillFactor((SkillType)0);
		int achievement = Quest.GetAchievement("DarklingShade");
		Faction faction = character.GetFaction();
		Faction val = faction;
		return ((int)val == 2) ? (num * (1f - 0.01f * (float)achievement)) : (((int)val != 7) ? Mathf.Max(num, 0.005f * (float)achievement) : Mathf.Max(num, 0.01f * (float)achievement));
	}

	private static bool CanBarter(Character character, float distanceFactor)
	{
		if (!(GetClan(character) == "Greydwarf") || GetClanRank(character) > 3)
		{
			return false;
		}
		if (distanceFactor > 0.93f || m_greydwarfReputaion < -20f)
		{
			return false;
		}
		return GetCurrentBarterLevel(character) >= 0f;
	}

	private static void TrackScentTypes(Character character)
	{
		if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)character != (Object)null)
		{
			string hoverName = character.GetHoverName();
			if (!m_scentTypes.ContainsKey(hoverName))
			{
				m_scentTypes.Add(hoverName, GetMarkerName(character));
			}
		}
	}

	private static ClanMemberData GetClanMemberData(Character character)
	{
		string text = WUTIL.ActorName(character);
		if (text != "" && m_clanMembers.ContainsKey(text))
		{
			return m_clanMembers[text];
		}
		return null;
	}

	private static void RegisterClanMember(string name, string clan = "", bool barter = false, float trust = 0.2f, float discoverRadius = 0f)
	{
		if (m_clanMembers.ContainsKey(name))
		{
			WDBUG.Log("Denighed repeat clan registery for " + name + " -> " + clan);
			return;
		}
		m_clanMembers.Add(name, new ClanMemberData(clan, barter, trust, discoverRadius));
		WDBUG.Log($"{name} clan: {clan} rank: {m_clanMembers[name].m_rank} trust: {trust} barter: {barter})", WDBUG.Level.ClanConfig);
	}

	private static bool CheckHiddenChased(Character source, float distanceFactor)
	{
		bool flag = HiddenAtDistance(distanceFactor);
		bool flag2 = source.GetBaseAI().CanSeeTarget((Character)(object)Player.m_localPlayer);
		bool flag3 = AlertedToPlayer(source);
		string hoverName = source.GetHoverName();
		float num = ((hoverName == "Greyling") ? 0.2f : 0f);
		if (GetClan(source) == "Goblin")
		{
			num = 0.005f * (float)Quest.GetAchievement("DarklingShade");
		}
		if (!flag && (m_wildlingHidden || WUTIL.TestLuck()))
		{
			if (!flag2 && distanceFactor < 0.7f + Equipment.HideClothingBuff + num)
			{
				flag = true;
			}
		}
		else if (flag && !m_wildlingHidden)
		{
			Quest.ShowMainTutorial(4);
			StatusEffect val = (StatusEffect)(object)(Wildling.SE_Hidden)(object)ScriptableObject.CreateInstance(typeof(Wildling.SE_Hidden));
			m_wildlingHidden = true;
			((Character)Player.m_localPlayer).GetSEMan().AddStatusEffect(val, false, 0, 0f);
		}
		if (flag)
		{
			if (flag2)
			{
				WDBUG.Log($"Seen hidden by {hoverName} at df: {distanceFactor} alerted: {flag3}", WDBUG.Level.Sense);
				if (!flag3 && distanceFactor > 0.24f && WUTIL.TestLuck())
				{
					Wildling.RaisePrimarySkill(distanceFactor * 1f, "hide close to " + hoverName, 5f, (SkillType)0);
				}
			}
			else if (flag3)
			{
				if (distanceFactor > 0.24f && WUTIL.TestLuck(0.9f))
				{
					StopHunt(source);
					float exp = ((num > 0f || GetClan(source) == "Animal") ? 2f : 5f);
					Wildling.RaisePrimarySkill(exp, "stop hunt of " + hoverName, World.PlayerInInterior() ? 100 : 10, (SkillType)0);
				}
				else
				{
					WDBUG.Log($"Stop hunt failed for {hoverName} at df: {distanceFactor}", WDBUG.Level.Sense);
				}
			}
		}
		m_wildlingHidden = flag;
		return flag;
	}

	private static string GetClanSpeechSfx(Character character, int reaction = 0)
	{
		ClanMemberData clanMemberData = GetClanMemberData(character);
		if (reaction > 3 || clanMemberData == null)
		{
			WDBUG.Log($"Unexpected call to GetClanSpeechSfx({character.GetHoverName()}, {reaction})");
			return "";
		}
		int num = clanMemberData.m_rank;
		if (num < 0 || num > 3)
		{
			WDBUG.Log($"No speech for {character.GetHoverName()} found due to rank {num}");
			return "";
		}
		if (clanMemberData.m_clan != "Greydwarf")
		{
			WDBUG.Log("No speech for " + character.GetHoverName() + " found due to clan");
			return "";
		}
		if (reaction < 0)
		{
			reaction = WUTIL.DieRoll(3);
			num = WUTIL.DieRoll(num + 1);
		}
		List<string> list = new List<string>
		{
			"sfx_greyling_idle", "sfx_greydwarf_idle", "sfx_greydwarf_elite_idle", "sfx_greydwarf_idle", "sfx_greyling_hit", "sfx_greydwarf_hit", "sfx_greydwarf_hit", "sfx_greydwarf_hit", "sfx_greyling_alerted", "sfx_greydwarf_alerted",
			"sfx_greydwarf_elite_alerted", "sfx_greydwarf_alerted", "sfx_greyling_attack", "sfx_greydwarf_attack", "sfx_greydwarf_elite_attack", "sfx_greydwarf_shaman_attack"
		};
		return list[num + reaction * 4];
	}

	private static List<string> GetTakeableItems(Character character)
	{
		return GreydwarfAcceptItems(GetClanRank(character));
	}

	private static string GetExchangeItem(Character character, string item, int rankOverride = 0)
	{
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		ClanMemberData clanMemberData = GetClanMemberData(character);
		if (clanMemberData == null)
		{
			return "";
		}
		float num = 2f * GetCurrentBarterLevel(character);
		if (num < 0f)
		{
			return "";
		}
		Quest.HelpWithBarter();
		WUTIL.FlushDelayedMessage(show: false);
		float num2 = num + WUTIL.RandomSpin(0f, 0.1f + m_holdingRabbitFootLuck);
		int num3 = ((rankOverride > 0) ? rankOverride : clanMemberData.m_rank);
		float num4 = 0.5f - 2f * m_holdingRabbitFootLuck;
		WDBUG.Log($"Barter Rank: {num3} Deficit: {num4} Credit: {num} Stetch: {num2}", WDBUG.Level.Barter);
		CheckRecentExchangeDrops(item, -1);
		string text = GreydwarfExchangeItem(character, item, num4, num2, num3);
		if (!text.StartsWith("Insult:"))
		{
			clanMemberData.m_trust = Mathf.Min(clanMemberData.m_trust + 0.005f, 0.35f);
			m_greydwarfReputaion += 5f;
			CheckRecentExchangeDrops(text, 1);
			Quest.SetAchievement("Barter", num3, bit: true);
			WDBUG.Log("Barter exchange: " + text, WDBUG.Level.Barter);
			return text;
		}
		float num5 = float.Parse(text.Substring(7));
		float num6 = 5f;
		if (num5 >= 3f)
		{
			WUTIL.Message("Your offering really offended the whole clan!");
			num6 = 1000f;
		}
		else if (num5 >= 2f)
		{
			WUTIL.Message("Your offering was deeply insulting!");
			num6 = 100f;
		}
		else if (num5 >= 1f)
		{
			WUTIL.Message("Your offering was not appreciated at all!", center: false);
			num6 = 20f;
		}
		else
		{
			WUTIL.Message("Your offering was not appreciated!", center: false);
		}
		num6 *= 1f;
		m_greydwarfReputaion = Math.Max(m_greydwarfReputaion - num6, -1200f);
		clanMemberData.m_trust = Mathf.Max(clanMemberData.m_trust - num5 * num5 * 0.005f, 0.1f);
		WUTIL.PlaySfx(GetClanSpeechSfx(character, (num5 >= 2f) ? 3 : 2), ((Component)character).transform.position);
		return "insult";
	}

	private static float DiscoverRadius(Character character)
	{
		ClanMemberData clanMemberData = GetClanMemberData(character);
		float num = clanMemberData?.m_discoverRadius ?? 0f;
		if (num <= 0f)
		{
			float radius = character.GetRadius();
			num = 1f - 0.025f * radius * radius * radius;
			if (clanMemberData != null)
			{
				clanMemberData.m_discoverRadius = num;
			}
		}
		return num;
	}

	private static void SenseCreature(Character character, float distFactor)
	{
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		if (character.IsFlying() || (m_detectScentsInside && World.PlayerInInterior()) || (ElderWand.IsPowered() && ElderWand.ObeysElderWand(character)) || Riding.IsRiding(character) || MapMarker.CharacterSenseCooldown(character) > 0f)
		{
			return;
		}
		string markerName = GetMarkerName(character);
		if (markerName == "")
		{
			return;
		}
		string text = WUTIL.ActorName(character);
		string hoverName = character.GetHoverName();
		string nextMarker = (markerName.StartsWith("Pet") ? "" : GetNextMarker(text));
		bool isSmall = text.StartsWith("Rat");
		if ((Object)(object)((Component)character).GetComponent<Growup>() != (Object)null)
		{
			int num = text.IndexOf('_');
			if (num > 0)
			{
				isSmall = true;
				text = text.Remove(num);
			}
		}
		else if (text.StartsWith("Rabbit"))
		{
			hoverName = (text = "Rabbit");
			isSmall = true;
		}
		else if (text.StartsWith("Draugr"))
		{
			text = "Draugr";
			hoverName = Localization.instance.Localize("$enemy_draugr");
		}
		if (MapMarker.DetectScent(text, ((Component)character).transform.position, distFactor, hoverName, markerName, nextMarker, isSmall, CharacterScentPower(character)))
		{
			MapMarker.CharacterSenseCooldown(character, 5);
		}
	}

	private static float AlertMovementFactor()
	{
		//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)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		Vector3 velocity = ((Character)Player.m_localPlayer).GetVelocity();
		float num = velocity.x * velocity.x + 0.25f * (velocity.y * velocity.y) + velocity.z * velocity.z;
		if (((Character)Player.m_localPlayer).IsCrouching())
		{
			num *= 0.25f;
		}
		return 1f - 0.5f * Mathf.Exp(-0.05f * num);
	}

	private static bool InPositionToBarter(Character character)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: 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_0127: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		BaseAI baseAI = character.GetBaseAI();
		MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)localPlayer))
		{
			return false;
		}
		bool flag = true;
		Vector3 val2 = ((Character)localPlayer).m_eye.position - character.m_eye.position;
		float num = Utils.LengthXZ(val2);
		if (num > 0.01f)
		{
			((Vector3)(ref val2)).Normalize();
		}
		if (!((BaseAI)val).CanSeeTarget((Character)(object)localPlayer))
		{
			flag = false;
		}
		if (num > 10f)
		{
			character.SetWalk(true);
			flag = false;
		}
		else
		{
			if (num < 5f)
			{
				character.SetMoveDir(Vector3.zero);
			}
			if (m_justDropped)
			{
				m_justDropped = false;
				WUTIL.TimerReset("witness_barter", 15f);
				if (flag && num < 2f)
				{
					WDBUG.Log($"Yeet! Assumed threw behind ({num} <3)", WDBUG.Level.Barter);
					val2 = -val2;
				}
			}
		}
		character.SetLookDir(val2, 0f);
		return flag;
	}

	private static bool AssignAllGrabables(Character character, bool onlyIfNone = true, bool debug = false)
	{
		BaseAI baseAI = character.GetBaseAI();
		MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
		if (!Object.op_Implicit((Object)(object)val) || (onlyIfNone && val.m_consumeItems.Count > 0))
		{
			return false;
		}
		List<string> takeableItems = GetTakeableItems(character);
		foreach (string item in takeableItems)
		{
			AddPickupItemToMonster(character, item);
		}
		if (debug)
		{
			string text = "";
			foreach (string item2 in takeableItems)
			{
				text = text + " " + item2;
			}
			WDBUG.Log("Assigned grabbles:" + text, WDBUG.Level.Barter);
		}
		return true;
	}

	private static void ForgetAllGrabables(Character character)
	{
		AddPickupItemToMonster(character, "");
	}

	private static void PickupItem(ItemDrop item, Character character)
	{
		//IL_001c: 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_00c3: 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)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: 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)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_038d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0458: Unknown result type (might be due to invalid IL or missing references)
		//IL_0346: Unknown result type (might be due to invalid IL or missing references)
		WUTIL.FlushDelayedMessage(show: false);
		string text = WUTIL.ItemName(item.m_itemData);
		Vector3 position = ((Component)character).transform.position;
		string hoverName = character.GetHoverName();
		if (CheckRecentExchangeDrops(text))
		{
			WDBUG.Log("Ungifting: " + text, WDBUG.Level.Barter);
			CheckRecentExchangeDrops(text, -1);
			WUTIL.PlaySfx(GetClanSpeechSfx(character, WUTIL.DieRoll(2)), position);
			if (WUTIL.TestLuck(0.6f))
			{
				WUTIL.CustomLog(hoverName + " took back " + WUTIL.ItemName(item), "#CC8");
			}
			return;
		}
		string text2 = WUTIL.ItemName(item.m_itemData, goName: false);
		text = GetExchangeItem(character, text);
		Player closestPlayer = Player.GetClosestPlayer(position, 16f);
		if (Object.op_Implicit((Object)(object)closestPlayer))
		{
			if (!Wildling.IsWildlingPlayer(closestPlayer) || (Object)(object)closestPlayer != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Vector3 val = ((Character)closestPlayer).m_eye.position - character.m_eye.position;
			float num = Utils.LengthXZ(val);
			if (num > 0.01f)
			{
				((Vector3)(ref val)).Normalize();
			}
			character.SetLookDir(val, 0f);
			float num2 = 0.5f;
			position = (1f - num2) * ((Component)closestPlayer).transform.position + num2 * position;
			if (num < 14f && WUTIL.Timer("witness_barter") > 0f && (double)Vector3.Dot(-val, ((Character)closestPlayer).GetLookDir()) > 0.9)
			{
				WDBUG.Log("Assumed Wildling witnessed barter", WDBUG.Level.Barter);
				Quest.Sho