Decompiled source of Wildling v1.1.1

WildlingMod.dll

Decompiled 5 months 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 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]++;
		}
	}

	public class SE_Hidden : SE_Stats
	{
		private static string hiddenBuff = "";

		public SE_Hidden()
		{
			((Object)this).name = (((StatusEffect)this).m_name = "Hidden");
			((StatusEffect)this).m_tooltip = "When you are couching and not moving, enemies are less likely to notice or continue hunting you. You can only hide if you are not too close, depending on your hiding ability. The Hidden status means you are sufficiently far away from all nearby enemies.";
			((StatusEffect)this).m_icon = WUTIL.GetIcon(m_hiddenIcon);
			((StatusEffect)this).m_ttl = 0f;
		}

		public override bool CanAdd(Character character)
		{
			return character.IsPlayer();
		}

		public override bool IsDone()
		{
			if (!((StatusEffect)this).m_character.IsCrouching())
			{
				m_hidden = false;
			}
			return !m_hidden;
		}

		public override string GetIconText()
		{
			float num = 0.1f * (float)(int)(1000f * Wildling.HideClothingBuff);
			hiddenBuff = ((num == 0f) ? "" : (((num < 0f) ? "" : "+") + num + "%"));
			return hiddenBuff;
		}

		public override string GetTooltipString()
		{
			if (hiddenBuff == "")
			{
				return ((StatusEffect)this).m_tooltip;
			}
			return ((StatusEffect)this).m_tooltip + " Your clothing is affecting your ability to hide in this environment.\nHiding: <color=grey>" + hiddenBuff + "</color>";
		}
	}

	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 * Wildling.HideClothingBuff + 0.5f);
						}
					}
					else if ((int)faction == 5)
					{
						if ((int)Wildling.BiomeClothingBuff == 4)
						{
							__result = !WUTIL.TestLuck(3f * Wildling.HideClothingBuff + 0.5f);
						}
					}
					else if ((int)faction == 7 && (int)Wildling.BiomeClothingBuff == 16)
					{
						__result = !WUTIL.TestLuck(3f * Wildling.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.SnakeBodyPiece(((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))
				{
					Unalert(component);
				}
			}
			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 (Wildling.m_weaponObjective1)
			{
				Quest.CheckObjective(2, set: false);
			}
			if (Wildling.m_justThrewPebble)
			{
				Wildling.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 float m_greydwarfReputaion = 1000000f;

	public static float m_holdingRabbitFootLuck = 0f;

	public static string m_lastCreatureSeen = "";

	public static string m_lastDroppedItem = "";

	public static string m_hiddenIcon = "StoneFloorSewers";

	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_hidden = 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 = 40f;

	private const float c_minConsumeRange = 1f;

	private const float c_consumeRunRangeFactor = 0.2f;

	private const float c_consumeSearchFrequency = 0.1f;

	private const float c_loseScentFrequency = 0.01f;

	private const float c_attactorStrength = 0.7f;

	private const float c_extraFoodRange = 4f;

	private const float c_fishFoodRange = 4f;

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

	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_animalBondedTime = 1024f;

	private const float c_goblinBribePickupTime = 10f;

	private const float c_goblinBribePickupRange = 10f;

	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,180;Fish,240" },
		{ "Boar", "Truffle,90;DeerBait,120" },
		{ "Ygnie", "Acorn,20" },
		{ "Wolf", "WolfBait,120;RabbitMeat,120" },
		{ "Fenring", "DeadRat,10" },
		{ "Fenringlin", "DeadRat,10" }
	};

	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("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 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_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Invalid comparison between Unknown and I4
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_03be: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Invalid comparison between Unknown and I4
		//IL_044d: 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_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_0343: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_0362: 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_04f3: Invalid comparison between Unknown and I4
		//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f7: Invalid comparison between Unknown and I4
		//IL_0552: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b2: Invalid comparison between Unknown and I4
		//IL_062a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0672: Unknown result type (might be due to invalid IL or missing references)
		//IL_0897: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_08bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c4: 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)
		{
			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(source))
		{
			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) || IsBonded(source))
		{
			return false;
		}
		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_hidden = 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_hidden = false;
			return isEnemy;
		}
		if (flag3)
		{
			if (CheckHiddenChased(source, num3))
			{
				isEnemy = false;
			}
		}
		else
		{
			m_hidden = 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_hidden = 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 (Wildling.HideClothingBuff >= 0.04f)
			{
				return true;
			}
		}
		else
		{
			m_hidden = false;
		}
		return m_hidden;
	}

	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_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected I4, but got Unknown
		float num = 1f;
		Faction faction = character.GetFaction();
		Faction val = faction;
		switch (val - 1)
		{
		case 2:
			num = 2f;
			break;
		case 3:
		case 4:
		case 5:
			num = 4f;
			break;
		case 6:
			num = 8f;
			break;
		case 0:
			num = 0f;
			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_035c: 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)
		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;
			if (Riding.IsRiding(component) || IsBonded(component) || WUTIL.TestLuck(chance))
			{
				if (Unalert(component) || WUTIL.ActorName(component) == "Neck")
				{
					WUTIL.CreateAttachedEffect("fx_boar_pet", ((Component)component).transform, 0f, 0f, 0.5f);
				}
				else
				{
					StopHunt(component);
					WUTIL.CreateAttachedEffect("fx_wolf_pet", ((Component)component).transform);
				}
			}
			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 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";
		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 "run";
				}
				text2 = "Happy";
			}
			else
			{
				if (asSpeed)
				{
					return ((Object)(object)component == (Object)null) ? "stop" : "march";
				}
				text = "Unhappy, ";
			}
		}
		if (animalFedTime > 10f)
		{
			if (!float.TryParse(GetConsumeTarget(character, 0, foodTime: true), out var result))
			{
				WDBUG.Log("Could not get foodTime for " + WUTIL.ActorName(character));
				result = 60f;
			}
			if (asSpeed)
			{
				return (animalFedTime < 0.9f * result) ? "run" : "sprint";
			}
			text2 = ((animalFedTime <= result) ? "Happy" : "Enamored");
		}
		return text + text2 + (showFoodTime ? (" " + (int)animalFedTime) : "");
	}

	public static bool IsHungry(Character character)
	{
		if ((Object)(object)((Component)character).GetComponent<Tameable>() != (Object)null && !((Component)character).GetComponent<Tameable>().IsHungry())
		{
			return true;
		}
		return GetAnimalFedTime(character) <= 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;
		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 == 10 || 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 = true;
				}
				else if (text6.StartsWith("Trophy") || text6 == "WitheredBone")
				{
					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");
		}
	}

	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_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Invalid comparison between Unknown and I4
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Invalid comparison between Unknown and I4
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Invalid comparison between Unknown and I4
		Faction faction = character.GetFaction();
		if ((int)faction == 1 || (int)faction == 8 || (int)faction == 6)
		{
			return "";
		}
		string text = GetClan(character);
		string text2 = WUTIL.ActorName(character);
		if (text == "Animal")
		{
			string text3 = "Pet" + text2;
			text = ((text2 == "Pixie" || text2 == "Ygnie") ? "" : ((character.IsTamed() && 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 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 >= 127)
		{
			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.instance.IsDaylight() ? 0.8f : 1f);
		float num2 = 0.5f * (Wildling.SkillFactor((SkillType)0) + num + Wildling.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_hidden || WUTIL.TestLuck()))
		{
			if (!flag2 && distanceFactor < 0.7f + Wildling.HideClothingBuff + num)
			{
				flag = true;
			}
		}
		else if (flag && !m_hidden)
		{
			Quest.ShowMainTutorial(4);
			StatusEffect val = (StatusEffect)(object)(SE_Hidden)(object)ScriptableObject.CreateInstance(typeof(SE_Hidden));
			m_hidden = 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_hidden = 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_0079: Unknown result type (might be due to invalid IL or missing references)
		if (!World.PlayerInInterior() && !character.IsFlying() && (!ElderWand.IsPowered() || !ElderWand.ObeysElderWand(character)) && !Riding.IsRiding(character) && !(MapMarker.CharacterSenseCooldown(character) > 0f))
		{
			string markerName = GetMarkerName(character);
			if (!(markerName == "") && MapMarker.DetectScent(character.GetHoverName(), ((Component)character).transform.position, distFactor, markerName, 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.ShowMainTutorial(8);
			}
			position += Vector3.up;
			if (text == "insult")
			{
				Wildling.RaisePrimarySkill(1f, "insult gift " + hoverName, 5f, (SkillType)0);
				WUTIL.PlaySfx(GetClanSpeechSfx(character, 3), position);
				character.GetBaseAI().Alert();
				WUTIL.CustomLog("Offering " + WUTIL.ItemName(item.m_itemData, goName: false) + " to a Greydwarf did not go down well!", "#F44");
				return;
			}
			int clanRank = GetClanRank(character);
			Wildling.RaisePrimarySkill(1f * (float)(clanRank + 1), $"barter gift {hoverName} at rank: {clanRank}", 5f, (SkillType)0);
			WUTIL.CreateHeadEffect("vfx_creature_soothed", character);
			StopHunt(character);
			if (text == "")
			{
				if (WasRecentlySeen(hoverName))
				{
					WUTIL.Message(hoverName + " seemed to like your gift.", center: false);
				}
				List<string> list = new List<string>();
				for (int i = 0; i < 2 + WUTIL.DieRoll(3); i++)
				{
					string clanSpeechSfx = GetClanSpeechSfx(character, -1);
					if (!list.Contains(clanSpeechSfx))
					{
						WUTIL.PlaySfx(clanSpeechSfx, position, 0.1f * (float)i);
						list.Add(clanSpeechSfx);
					}
				}
				return;
			}
			WUTIL.PlaySfx(GetClanSpeechSfx(character, WUTIL.DieRoll(2)), position);
			List<string> list2 = new List<string> { "sfx_barley_hit", "sfx_hit", "sfx_greydwarf_throw", "sfx_neck_hit" };
			string sfx_name = list2[WUTIL.DieRoll(list2.Count)];
			int number = 1;
			int num3 = text.IndexOf(':');
			if (num3 > 0)
			{
				number = int.Parse(text.Substring(num3 + 1));
				text = text.Remove(num3);
			}
			WDBUG.Log(hoverName + " should gift " + number + "x " + text, WDBUG.Level.Barter);
			ItemData val2 = WUTIL.DropItemOutside(text, position, sfx_name, number);
			if (val2 != null)
			{
				string msg = hoverName + " traded " + WUTIL.ItemName(val2, goName: false) + " for " + text2;
				WUTIL.CustomLog(msg, BarterLogColor(text), text2 != "Guck");
				if (WasRecentlySeen(hoverName))
				{
					WUTIL.Message(msg, center: true, MapMarker.GetCharacterIcon(character));
				}
				Quest.SetAchievement("BarterDreamState", (hoverName == "Greyling") ? 3 : 4, bit: false, if_lower: true);
				CheckObjectives(text);
				if (text == "KnifeCopper")
				{
					Quest.AdvanceAchievement(text);
					val2.m_quality = Mathf.Min(Quest.GetAchievement(text), 4);
				}
			}
		}
		else
		{
			WDBUG.Log("No player to nearby to accept " + text, WDBUG.Level.Barter);
		}
	}

	private static string BarterLogColor(string item)
	{
		if (item == "Guck")
		{
			return "#8C4";
		}
		int num = "CarrotSeeds,BeechSeeds,FirCone,FineWood,RoundLog".IndexOf(item);
		return (num >= 0) ? "#FC8" : (m_gdTrophyItems.Contains(item) ? "#FDA" : "#CCA");
	}

	private static void AddPickupItemToMonster(Character character, string itemName)
	{
		BaseAI baseAI = character.GetBaseAI();
		MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
		if (!Object.op_Implicit((Object)(object)val))
		{
			return;
		}
		if (itemName == "")
		{
			if (val.m_consumeItems.Count > 0)
			{
				WDBUG.Log("Clearing " + WUTIL.ActorName(character) + " grab list", WDBUG.Level.Barter);
				val.m_consumeItems.Clear();
				val.m_onConsumedItem = null;
			}
			return;
		}
		GameObject prefab = WUTIL.GetPrefab(itemName);
		ItemDrop val2 = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null);
		if ((Object)(object)val2 == (Object)null)
		{
			WDBUG.Log("AddPickupItemToMonster failed - " + itemName + " is not an ItemDrop");
			return;
		}
		if (!val.m_consumeItems.Contains(val2))
		{
			val.m_consumeItems.Add(val2);
		}
		int num = 0;
		if (val.m_onConsumedItem != null)
		{
			Delegate[] invocationList = val.m_onConsumedItem.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action<ItemDrop>