Decompiled source of VikingNPC v0.3.2

Norsemen.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyProduct("Norsemen")]
[assembly: AssemblyCompany("RustyMods")]
[assembly: AssemblyFileVersion("0.3.2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("Norsemen")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")]
[assembly: AssemblyConfiguration("")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.2.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<44f17f13-2ded-43f7-a0fc-d603b1ea77d6>Embedded]
	internal sealed class <44f17f13-2ded-43f7-a0fc-d603b1ea77d6>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[<44f17f13-2ded-43f7-a0fc-d603b1ea77d6>Embedded]
	[CompilerGenerated]
	internal sealed class <3530c945-4eb1-4ca2-af3d-2dda293a1c8f>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <3530c945-4eb1-4ca2-af3d-2dda293a1c8f>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <3530c945-4eb1-4ca2-af3d-2dda293a1c8f>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[<44f17f13-2ded-43f7-a0fc-d603b1ea77d6>Embedded]
	[CompilerGenerated]
	internal sealed class <76271666-bebe-4094-881a-4286fd275e00>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <76271666-bebe-4094-881a-4286fd275e00>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Norsemen
{
	[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(0)]
	[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
	public class VikingAI : MonsterAI
	{
		[HarmonyPatch(typeof(TreeBase), "RPC_Damage")]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		private static class TreeBase_RPC_Damage_Patch
		{
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static void Postfix(TreeBase __instance, HitData hit)
			{
				if (__instance.m_nview.IsOwner() && hit.GetAttacker() is Viking && hit.GetTotalDamage() <= 0f)
				{
					__instance.Shake();
				}
			}
		}

		[HarmonyPatch(typeof(FishingFloat), "GetOwner")]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		private static class FishingFloat_GetOwner_Patch
		{
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static void Postfix(FishingFloat __instance, ref Character __result)
			{
				if ((Object)(object)__result != (Object)null)
				{
					return;
				}
				long @long = __instance.m_nview.GetZDO().GetLong(ZDOVars.s_rodOwner, 0L);
				foreach (Viking instance in Viking.instances)
				{
					if (((ZDOID)(ref ((Character)instance).m_nview.GetZDO().m_uid)).UserID != @long)
					{
						continue;
					}
					__result = (Character)(object)instance;
					break;
				}
			}
		}

		public Emotion m_behaviour = Emotion.Aggressive;

		public Movement m_moveType = Movement.Patrol;

		public float m_behaviourUpdateTimer;

		public float m_blockTimer;

		private float m_blockCheckInterval = 2f;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public TreeBase m_tree;

		private float m_dodgeTimer = 0f;

		private float m_dodgeCooldown = 5f;

		private float m_dodgeCheckInterval = 0.2f;

		private float m_dodgeCheckTimer = 0f;

		private float m_dodgeDistance = 15f;

		private float m_dodgeThreatDistance = 5f;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public Fish m_fish;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public ItemData m_bait;

		public Biome m_currentBiome;

		public float m_biomeTimer;

		public float m_lastMoveAwayFromMountainTimer;

		public bool m_haveNonMountainPosition;

		public Vector3 m_moveAwayFromMountainPosition;

		public float m_lastMoveAwayFromTar;

		public bool m_haveNonTarPosition;

		public Vector3 m_moveAwayFromTarPosition;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public Player m_followPlayer;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public MineRock m_mineRock;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public MineRock5 m_mineRock5;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public Destructible m_destructible;

		public Vector3 m_lastMineRock5Point;

		public float m_shipAttachTimer;

		public float m_crouchTimer;

		private float m_crouchCheckInterval = 2f;

		private float m_workTargetSearchTimer;

		private float m_workTargetSearchInterval = 30f;

		private bool hasWorkTarget;

		public Viking m_viking = null;

		public float m_lastWorkActionTime;

		public float m_workInterval = 10f;

		public float m_lastResourceGainedTime;

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public bool UpdateAttack(float dt, ItemData itemData, bool doAttack, bool canHearTarget, bool canSeeTarget, bool isTamed)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if (itemData == null)
			{
				return false;
			}
			AiTarget aiTargetType = itemData.m_shared.m_aiTargetType;
			AiTarget val = aiTargetType;
			if ((int)val != 0)
			{
				if (val - 1 <= 1)
				{
					return UpdateFriendAttack(dt, itemData, doAttack, isTamed);
				}
				return false;
			}
			return UpdateEnemyAttack(dt, itemData, doAttack, canHearTarget, canSeeTarget, isTamed);
		}

		private bool UpdateEnemyAttack(float dt, ItemData itemData, bool doAttack, bool canHearTarget, bool canSeeTarget, bool isTamed)
		{
			if ((Object)(object)base.m_targetStatic != (Object)null)
			{
				return HandleStaticTarget(dt, itemData, doAttack, isTamed);
			}
			if ((Object)(object)base.m_targetCreature != (Object)null)
			{
				return HandleCreatureTarget(dt, itemData, doAttack, canHearTarget, canSeeTarget, isTamed);
			}
			return false;
		}

		public static float GetWeaponRange(ItemData itemData)
		{
			//IL_0007: 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_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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			SkillType skillType = itemData.m_shared.m_skillType;
			SkillType val = skillType;
			if (val - 8 <= 2 || (int)val == 14)
			{
				return Random.Range(15f, 30f);
			}
			return itemData.m_shared.m_attack.m_attackRange;
		}

		private bool HandleStaticTarget(float dt, ItemData itemData, bool doAttack, bool isTamed)
		{
			//IL_000d: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = base.m_targetStatic.FindClosestPoint(((Component)this).transform.position);
			float num = Vector3.Distance(val, ((Component)this).transform.position);
			bool flag = num < GetWeaponRange(itemData);
			bool flag2 = ((BaseAI)this).CanSeeTarget(base.m_targetStatic);
			if (flag && flag2)
			{
				Vector3 center = base.m_targetStatic.GetCenter();
				((BaseAI)this).LookAt(center);
				if ((double)itemData.m_shared.m_aiAttackMaxAngle == 0.0)
				{
					ZLog.LogError((object)("AI Attack Max Angle for " + itemData.m_shared.m_name + " is 0!"));
				}
				bool flag3 = ((BaseAI)this).IsLookingAt(center, itemData.m_shared.m_aiAttackMaxAngle, itemData.m_shared.m_aiInvertAngleCheck);
				if (flag3 && doAttack)
				{
					DoWeaponAttack(null, isFriend: false);
					return true;
				}
				((BaseAI)this).StopMoving();
				return true;
			}
			if (isTamed && m_moveType == Movement.Guard)
			{
				return false;
			}
			((BaseAI)this).MoveTo(dt, val, 0f, ((BaseAI)this).IsAlerted());
			((BaseAI)this).ChargeStop();
			return true;
		}

		private bool HandleCreatureTarget(float dt, ItemData itemData, bool doAttack, bool canHearTarget, bool canSeeTarget, bool isTamed)
		{
			if (canHearTarget || canSeeTarget || (((BaseAI)this).HuntPlayer() && base.m_targetCreature.IsPlayer()))
			{
				return HandleDetectedCreature(dt, itemData, doAttack, canSeeTarget, isTamed);
			}
			return HandleLostCreature(dt, isTamed);
		}

		private bool HandleDetectedCreature(float dt, ItemData itemData, bool doAttack, bool canSeeTarget, bool isTamed)
		{
			//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_001f: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			base.m_beenAtLastPos = false;
			base.m_lastKnownTargetPos = ((Component)base.m_targetCreature).transform.position;
			float num = Vector3.Distance(base.m_lastKnownTargetPos, ((Component)this).transform.position) - base.m_targetCreature.GetRadius();
			float num2 = base.m_alertRange * base.m_targetCreature.GetStealthFactor();
			if (canSeeTarget && num < num2)
			{
				((BaseAI)this).SetAlerted(true);
			}
			float weaponRange = GetWeaponRange(itemData);
			bool flag = num < weaponRange;
			bool flag2 = !flag || !canSeeTarget || !((BaseAI)this).IsAlerted();
			if (flag2 && isTamed && m_moveType == Movement.Guard)
			{
				return true;
			}
			if (flag2)
			{
				Vector3 val = CalculateInterceptPosition(num);
				((BaseAI)this).MoveTo(dt, val, 0f, ((BaseAI)this).IsAlerted());
				if ((double)base.m_timeSinceAttacking > 15.0)
				{
					base.m_unableToAttackTargetTimer = 15f;
				}
				return true;
			}
			((BaseAI)this).StopMoving();
			bool flag3 = ((BaseAI)this).IsAlerted();
			if (flag && canSeeTarget && flag3)
			{
				if (((MonsterAI)this).PheromoneFleeCheck(base.m_targetCreature))
				{
					((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position);
					base.m_updateTargetTimer = Random.Range(base.m_fleePheromoneMin, base.m_fleePheromoneMax);
					base.m_targetCreature = null;
				}
				else
				{
					((BaseAI)this).LookAt(base.m_targetCreature.GetTopPoint());
					bool flag4 = ((BaseAI)this).IsLookingAt(base.m_lastKnownTargetPos, itemData.m_shared.m_aiAttackMaxAngle, itemData.m_shared.m_aiInvertAngleCheck);
					if (doAttack && flag4)
					{
						DoWeaponAttack(base.m_targetCreature, isFriend: false);
						return true;
					}
				}
			}
			else if (flag3)
			{
				UpdateDodge(dt, base.m_targetCreature);
			}
			return false;
		}

		private Vector3 CalculateInterceptPosition(float distanceToTarget)
		{
			//IL_0007: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = base.m_targetCreature.GetVelocity();
			Vector3 val = velocity * base.m_interceptTime;
			Vector3 val2 = base.m_lastKnownTargetPos;
			if ((double)distanceToTarget > (double)((Vector3)(ref val)).magnitude / 4.0)
			{
				val2 += val;
			}
			return val2;
		}

		private bool HandleLostCreature(float dt, bool isTamed)
		{
			//IL_0067: 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)
			((BaseAI)this).ChargeStop();
			bool flag = !isTamed || m_moveType == Movement.Patrol;
			if (base.m_beenAtLastPos)
			{
				if (flag)
				{
					((BaseAI)this).RandomMovement(dt, base.m_lastKnownTargetPos, false);
				}
				if ((double)base.m_timeSinceAttacking > 15.0)
				{
					base.m_unableToAttackTargetTimer = 15f;
				}
				return true;
			}
			if (flag && ((BaseAI)this).MoveTo(dt, base.m_lastKnownTargetPos, 0f, ((BaseAI)this).IsAlerted()))
			{
				base.m_beenAtLastPos = true;
				return true;
			}
			return false;
		}

		private bool UpdateFriendAttack(float dt, ItemData itemData, bool doAttack, bool isTamed)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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)
			Character val = (((int)itemData.m_shared.m_aiTargetType == 1) ? ((BaseAI)this).HaveHurtFriendInRange(((BaseAI)this).m_viewRange) : ((BaseAI)this).HaveFriendInRange(((BaseAI)this).m_viewRange));
			bool flag = !isTamed || m_moveType == Movement.Patrol;
			if ((Object)(object)val == (Object)null)
			{
				if (flag)
				{
					((BaseAI)this).RandomMovement(dt, ((Component)this).transform.position, true);
				}
				return false;
			}
			float num = Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position);
			float weaponRange = GetWeaponRange(itemData);
			if (num < weaponRange)
			{
				if (doAttack)
				{
					((BaseAI)this).StopMoving();
					((BaseAI)this).LookAt(((Component)val).transform.position);
					DoWeaponAttack(val, isFriend: true);
					return true;
				}
				if (flag)
				{
					((BaseAI)this).RandomMovement(dt, ((Component)val).transform.position, false);
					return true;
				}
			}
			else if (flag)
			{
				((BaseAI)this).MoveTo(dt, ((Component)val).transform.position, 0f, ((BaseAI)this).IsAlerted());
				return true;
			}
			return false;
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public bool DoWeaponAttack(Character target, bool isFriend)
		{
			ItemData currentWeapon = ((Humanoid)m_viking).GetCurrentWeapon();
			if (currentWeapon == null || !((BaseAI)this).CanUseAttack(currentWeapon))
			{
				return false;
			}
			bool flag = !string.IsNullOrEmpty(currentWeapon.m_shared.m_secondaryAttack.m_attackAnimation) && Random.value > 0.5f;
			if (!((Character)m_viking).StartAttack(target, flag))
			{
				return false;
			}
			base.m_timeSinceAttacking = 0f;
			return true;
		}

		public bool UpdateAvoidFire(float dt, bool isTamed)
		{
			if (m_viking.IsHoldingTorch())
			{
				return false;
			}
			if (isTamed && m_moveType == Movement.Guard)
			{
				return false;
			}
			if ((((BaseAI)this).m_afraidOfFire || ((BaseAI)this).m_avoidFire) && ((BaseAI)this).AvoidFire(dt, base.m_targetCreature, ((BaseAI)this).m_afraidOfFire))
			{
				return true;
			}
			return false;
		}

		public bool UpdateBaseAI(float dt)
		{
			if (!((BaseAI)this).m_nview.IsValid())
			{
				return false;
			}
			if (!((BaseAI)this).m_nview.IsOwner())
			{
				((BaseAI)this).m_alerted = ((BaseAI)this).m_nview.GetZDO().GetBool(ZDOVars.s_alert, false);
				return false;
			}
			if ((double)((BaseAI)this).m_jumpInterval > 0.0)
			{
				((BaseAI)this).m_jumpTimer = ((BaseAI)this).m_jumpTimer + dt;
			}
			if ((double)((BaseAI)this).m_randomMoveUpdateTimer > 0.0)
			{
				((BaseAI)this).m_randomMoveUpdateTimer = ((BaseAI)this).m_randomMoveUpdateTimer - dt;
			}
			((BaseAI)this).UpdateRegeneration(dt);
			((BaseAI)this).m_timeSinceHurt = ((BaseAI)this).m_timeSinceHurt - dt;
			return true;
		}

		public void SetEmotion(int state)
		{
			if (state != (int)m_behaviour)
			{
				m_behaviour = (Emotion)state;
				((BaseAI)this).m_nview.GetZDO().Set(VikingVars.behaviour, state, false);
			}
		}

		public void SetMovement(int state)
		{
			if (state != (int)m_moveType)
			{
				m_moveType = (Movement)state;
				((BaseAI)this).m_nview.GetZDO().Set(VikingVars.patrol, state, false);
			}
		}

		public void UpdateBehaviour(float dt)
		{
			m_behaviourUpdateTimer += dt;
			if (!(m_behaviourUpdateTimer < 1f))
			{
				m_behaviourUpdateTimer = 0f;
				SetEmotion(((BaseAI)this).m_nview.GetZDO().GetInt(VikingVars.behaviour, 0));
				SetMovement(((BaseAI)this).m_nview.GetZDO().GetInt(VikingVars.patrol, 0));
			}
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public void UpdateBlock(float dt, Character target, bool canSeeTarget)
		{
			m_blockTimer += dt;
			if (m_blockTimer > m_blockCheckInterval)
			{
				m_blockTimer = 0f;
				UpdateBlockDecision(target, canSeeTarget);
			}
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public void UpdateBlockDecision(Character target, bool canSeeTarget)
		{
			//IL_008f: 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)
			if (!((BaseAI)this).IsAlerted())
			{
				m_viking.SetBlocking(block: false);
				return;
			}
			if ((Object)(object)target == (Object)null)
			{
				m_viking.SetBlocking(block: false);
				return;
			}
			if (((Character)m_viking).GetHealthPercentage() < 0.25f)
			{
				m_viking.SetBlocking(block: true);
				return;
			}
			if (target.IsFlying())
			{
				m_viking.SetBlocking(block: false);
				return;
			}
			float num = Vector3.Distance(((Component)target).transform.position, ((Component)this).transform.position);
			bool flag = ((Object)(object)target.m_baseAI != (Object)null && target.m_baseAI.IsAlerted()) || target.IsPlayer();
			if (canSeeTarget)
			{
				if (num < 10f)
				{
					if (flag)
					{
						m_viking.SetBlocking(Random.value > 0.8f);
					}
					else
					{
						m_viking.SetBlocking(Random.value > 0.5f);
					}
				}
				else if (target.m_baseAI.IsCharging() || target.IsDrawingBow())
				{
					m_viking.SetBlocking(Random.value > 0.6f);
				}
				else
				{
					m_viking.SetBlocking(Random.value > 0.25f);
				}
			}
			else
			{
				m_viking.SetBlocking(block: false);
			}
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public void UpdateChargeAttack(float dt, bool hasItem, bool hasTarget, bool doAttack, ItemData itemData)
		{
			bool flag = hasItem && hasTarget && doAttack;
			bool flag2 = !((BaseAI)this).m_character.InAttack();
			bool flag3 = itemData?.m_shared.m_attack != null && !itemData.m_shared.m_attack.IsDone() && !string.IsNullOrEmpty(itemData.m_shared.m_attack.m_drawAnimationState);
			if ((((BaseAI)this).IsCharging() || flag) && flag2 && flag3)
			{
				((BaseAI)this).ChargeStart(itemData?.m_shared.m_attack.m_drawAnimationState);
			}
		}

		public bool UpdateLogging(float dt, ItemData axe, bool isFollowing)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_tree == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)m_tree).gameObject == (Object)null)
			{
				ResetWorkTargets();
				return false;
			}
			if (isFollowing)
			{
				float num = Vector3.Distance(((Component)m_tree).transform.position, ((Component)this).transform.position);
				if (num > 20f)
				{
					ResetWorkTargets();
					return false;
				}
			}
			if (!((BaseAI)this).MoveTo(dt, ((Component)m_tree).transform.position, axe.m_shared.m_attack.m_attackRange, false))
			{
				return true;
			}
			((BaseAI)this).StopMoving();
			((BaseAI)this).LookAt(((Component)m_tree).transform.position);
			DoChopping(axe, m_tree);
			m_lastWorkActionTime = Time.time;
			((BaseAI)this).m_nview.GetZDO().Set(VikingVars.lastWorkTime, ZNet.instance.GetTime().Ticks);
			return true;
		}

		public void DoChopping(ItemData axe, TreeBase tree)
		{
			if (m_viking.StartWork(axe) && (Object)(object)tree.m_logPrefab != (Object)null)
			{
				TreeLog component = tree.m_logPrefab.GetComponent<TreeLog>();
				if ((Object)(object)component != (Object)null)
				{
					if ((Object)(object)component.m_subLogPrefab != (Object)null)
					{
						component = component.m_subLogPrefab.GetComponent<TreeLog>();
					}
					List<DropData> drops = component.m_dropWhenDestroyed.m_drops;
					AddResources(drops);
				}
			}
			if (!((Object)(object)tree.m_logPrefab != (Object)null))
			{
				return;
			}
			TreeLog component2 = tree.m_logPrefab.GetComponent<TreeLog>();
			if ((Object)(object)component2 != (Object)null)
			{
				if ((Object)(object)component2.m_subLogPrefab != (Object)null)
				{
					component2 = component2.m_subLogPrefab.GetComponent<TreeLog>();
				}
				List<DropData> drops2 = component2.m_dropWhenDestroyed.m_drops;
				AddResources(drops2);
			}
		}

		public bool UpdateCircleTarget(float dt, bool isTamed)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (isTamed && m_moveType == Movement.Guard)
			{
				return false;
			}
			if ((double)base.m_circleTargetInterval > 0.0 && Object.op_Implicit((Object)(object)base.m_targetCreature))
			{
				base.m_pauseTimer += dt;
				if ((double)base.m_pauseTimer > (double)base.m_circleTargetInterval)
				{
					if ((double)base.m_pauseTimer > (double)base.m_circleTargetInterval + (double)base.m_circleTargetDuration)
					{
						base.m_pauseTimer = Random.Range(0f, base.m_circleTargetInterval / 10f);
					}
					((BaseAI)this).RandomMovementArroundPoint(dt, ((Component)base.m_targetCreature).transform.position, base.m_circleTargetDistance, ((BaseAI)this).IsAlerted());
					return true;
				}
			}
			return false;
		}

		public bool UpdateCirculate(float dt, bool hasItem, bool doAttack, bool isTamed)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if (isTamed && m_moveType == Movement.Guard)
			{
				return false;
			}
			bool flag = (((BaseAI)this).m_character.IsFlying() ? base.m_circulateWhileChargingFlying : base.m_circulateWhileCharging);
			if (flag && hasItem && !doAttack && !((BaseAI)this).m_character.InAttack())
			{
				if ((Object)(object)base.m_targetCreature != (Object)null)
				{
					((BaseAI)this).RandomMovementArroundPoint(dt, ((Component)base.m_targetCreature).transform.position, ((BaseAI)this).m_randomMoveRange, ((BaseAI)this).IsAlerted());
					return true;
				}
				if ((Object)(object)base.m_targetStatic != (Object)null)
				{
					((BaseAI)this).RandomMovementArroundPoint(dt, ((Component)base.m_targetStatic).transform.position, ((BaseAI)this).m_randomMoveRange, ((BaseAI)this).IsAlerted());
					return true;
				}
			}
			return false;
		}

		public bool UpdateConsume(float dt, Viking character, bool hasTarget, bool isTamed)
		{
			if (base.m_consumeItems == null || base.m_consumeItems.Count == 0)
			{
				return false;
			}
			if (!((BaseAI)this).IsAlerted() && !hasTarget && UpdateConsumeSearch(character, isTamed, dt))
			{
				return true;
			}
			return false;
		}

		public bool IsFoodItem(ItemData item)
		{
			return base.m_consumeItems.Exists([<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)] (ItemDrop i) => i.m_itemData.m_shared.m_name == item.m_shared.m_name);
		}

		public bool EatInventoryFood(Viking viking)
		{
			Inventory inventory = ((Humanoid)viking).GetInventory();
			List<ItemData> allItemsOfType = inventory.GetAllItemsOfType((ItemType)2, false);
			ItemData val = null;
			if (allItemsOfType.Count > 0)
			{
				foreach (ItemData item in allItemsOfType)
				{
					if (IsFoodItem(item))
					{
						val = item;
						break;
					}
				}
			}
			if (val == null)
			{
				return false;
			}
			viking.OnConsumedItem(val);
			inventory.RemoveItem(val, 1);
			return true;
		}

		public bool UpdateConsumeSearch(Viking viking, bool isTamed, float dt)
		{
			//IL_00be: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			base.m_consumeSearchTimer += dt;
			if (base.m_consumeSearchTimer > base.m_consumeSearchInterval)
			{
				base.m_consumeSearchTimer = 0f;
				if (!viking.IsHungry())
				{
					return false;
				}
				if (isTamed && EatInventoryFood(viking))
				{
					return false;
				}
				if (isTamed && m_moveType == Movement.Guard)
				{
					return false;
				}
				base.m_consumeTarget = ((MonsterAI)this).FindClosestConsumableItem(base.m_consumeSearchRange);
				if (!Object.op_Implicit((Object)(object)base.m_consumeTarget))
				{
					return false;
				}
				if (!((BaseAI)this).MoveTo(dt, ((Component)base.m_consumeTarget).transform.position, base.m_consumeRange, false))
				{
					return true;
				}
				((BaseAI)this).LookAt(((Component)base.m_consumeTarget).transform.position);
				if (!((BaseAI)this).IsLookingAt(((Component)base.m_consumeTarget).transform.position, 20f, false) || !base.m_consumeTarget.RemoveOne())
				{
					return true;
				}
				viking.OnConsumedItem(base.m_consumeTarget);
				base.m_consumeTarget = null;
				return false;
			}
			return false;
		}

		public void UpdateTargets(Viking viking, bool isTamed, float dt, out bool canHearTarget, out bool canSeeTarget)
		{
			base.m_unableToAttackTargetTimer -= dt;
			base.m_updateTargetTimer -= dt;
			if ((double)base.m_updateTargetTimer <= 0.0 && !((BaseAI)this).m_character.InAttack())
			{
				UpdateTargetSearch(isTamed);
			}
			if ((Object)(object)base.m_targetCreature != (Object)null && isTamed)
			{
				CheckTamedTargetDistance();
			}
			ValidateCurrentTarget();
			UpdateTargetSensing(dt, out canHearTarget, out canSeeTarget);
			CheckGiveUpChase(dt);
		}

		private void UpdateTargetSearch(bool isTamed)
		{
			//IL_0008: 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)
			base.m_updateTargetTimer = (Player.IsPlayerInRange(((Component)this).transform.position, 50f) ? 2f : 6f);
			if (isTamed && m_behaviour == Emotion.Passive)
			{
				base.m_targetCreature = null;
			}
			else
			{
				Character val = ((BaseAI)this).FindEnemy();
				if (Object.op_Implicit((Object)(object)val))
				{
					base.m_targetCreature = val;
					base.m_targetStatic = null;
				}
			}
			bool hasPlayerTarget = (Object)(object)base.m_targetCreature != (Object)null && base.m_targetCreature.IsPlayer();
			bool flag = (Object)(object)base.m_targetCreature != (Object)null && (double)base.m_unableToAttackTargetTimer > 0.0 && !((BaseAI)this).HavePath(((Component)base.m_targetCreature).transform.position);
			bool flag2 = base.m_attackPlayerObjects && (!((BaseAI)this).m_aggravatable || ((BaseAI)this).IsAggravated()) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)25);
			bool flag3 = ((Object)(object)base.m_targetCreature == (Object)null || flag) && !isTamed;
			if (flag2 && flag3)
			{
				FindStaticTargets(hasPlayerTarget);
			}
		}

		private void FindStaticTargets(bool hasPlayerTarget)
		{
			//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_0056: Unknown result type (might be due to invalid IL or missing references)
			StaticTarget val = ((BaseAI)this).FindClosestStaticPriorityTarget();
			if ((Object)(object)val != (Object)null)
			{
				base.m_targetStatic = val;
				base.m_targetCreature = null;
			}
			bool flag = false;
			if ((Object)(object)base.m_targetStatic != (Object)null)
			{
				Vector3 val2 = base.m_targetStatic.FindClosestPoint(((Component)((BaseAI)this).m_character).transform.position);
				flag = ((BaseAI)this).HavePath(val2);
			}
			if (((Object)(object)base.m_targetStatic == (Object)null || !flag) && ((BaseAI)this).IsAlerted() && hasPlayerTarget)
			{
				StaticTarget val3 = ((BaseAI)this).FindRandomStaticTarget(10f);
				if ((Object)(object)val3 != (Object)null)
				{
					base.m_targetStatic = val3;
					base.m_targetCreature = null;
				}
			}
		}

		private void CheckTamedTargetDistance()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)base.m_targetCreature == (Object)null)
			{
				return;
			}
			float alertRange = base.m_alertRange;
			Vector3 val = default(Vector3);
			if (((BaseAI)this).GetPatrolPoint(ref val))
			{
				if (Vector3.Distance(((Component)base.m_targetCreature).transform.position, val) > alertRange)
				{
					base.m_targetCreature = null;
				}
			}
			else if ((Object)(object)base.m_follow != (Object)null && Vector3.Distance(((Component)base.m_targetCreature).transform.position, base.m_follow.transform.position) > alertRange)
			{
				base.m_targetCreature = null;
			}
		}

		private void ValidateCurrentTarget()
		{
			if (!((Object)(object)base.m_targetCreature == (Object)null))
			{
				if (base.m_targetCreature.IsDead())
				{
					base.m_targetCreature = null;
				}
				else if (!((BaseAI)this).IsEnemy(base.m_targetCreature))
				{
					base.m_targetCreature = null;
				}
				else if (((BaseAI)this).m_skipLavaTargets && base.m_targetCreature.AboveOrInLava())
				{
					base.m_targetCreature = null;
				}
			}
		}

		private void UpdateTargetSensing(float dt, out bool canHearTarget, out bool canSeeTarget)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			canHearTarget = false;
			canSeeTarget = false;
			if (!hasWorkTarget && (Object)(object)base.m_targetCreature != (Object)null)
			{
				canHearTarget = ((BaseAI)this).CanHearTarget(base.m_targetCreature);
				canSeeTarget = ((BaseAI)this).CanSeeTarget(base.m_targetCreature);
				if (canSeeTarget | canHearTarget)
				{
					base.m_timeSinceSensedTargetCreature = 0f;
				}
				if (base.m_targetCreature.IsPlayer())
				{
					base.m_targetCreature.OnTargeted(canSeeTarget | canHearTarget, ((BaseAI)this).IsAlerted());
				}
				((BaseAI)this).SetTargetInfo(base.m_targetCreature.GetZDOID());
			}
			else
			{
				((BaseAI)this).SetTargetInfo(ZDOID.None);
			}
			base.m_timeSinceSensedTargetCreature += dt;
		}

		private void CheckGiveUpChase(float dt)
		{
			//IL_00aa: 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)
			if (!((BaseAI)this).IsAlerted() && (Object)(object)base.m_targetCreature == (Object)null)
			{
				return;
			}
			base.m_timeSinceAttacking += dt;
			if (!((BaseAI)this).HuntPlayer() || !((Object)(object)base.m_targetCreature != (Object)null) || !base.m_targetCreature.IsPlayer())
			{
				bool flag = (double)base.m_timeSinceSensedTargetCreature > 30.0;
				float num = 60f;
				bool flag2 = base.m_timeSinceAttacking > num;
				bool flag3 = (double)base.m_maxChaseDistance > 0.0 && (double)base.m_timeSinceSensedTargetCreature > 1.0 && Vector3.Distance(((BaseAI)this).m_spawnPoint, ((Component)this).transform.position) > base.m_maxChaseDistance;
				if (flag || (flag2 && flag3))
				{
					((BaseAI)this).SetAlerted(false);
					base.m_targetCreature = null;
					base.m_targetStatic = null;
					base.m_timeSinceAttacking = 0f;
					base.m_updateTargetTimer = 5f;
				}
			}
		}

		public bool UpdateDespawn(float dt, bool canSeeTarget)
		{
			if (((MonsterAI)this).DespawnInDay() && EnvMan.IsDay() && ((Object)(object)base.m_targetCreature == (Object)null || !canSeeTarget))
			{
				((BaseAI)this).MoveAwayAndDespawn(dt, true);
				return true;
			}
			if (((MonsterAI)this).IsEventCreature() && !RandEventSystem.HaveActiveEvent())
			{
				((BaseAI)this).SetHuntPlayer(false);
				if ((Object)(object)base.m_targetCreature == (Object)null && !((BaseAI)this).IsAlerted())
				{
					((BaseAI)this).MoveAwayAndDespawn(dt, false);
					return true;
				}
			}
			return false;
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public bool UpdateDodge(float dt, Character target)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			if (m_dodgeTimer > 0f)
			{
				m_dodgeTimer -= dt;
			}
			m_dodgeCheckTimer -= dt;
			if (m_dodgeCheckTimer > 0f)
			{
				return false;
			}
			m_dodgeCheckTimer = m_dodgeCheckInterval;
			if (m_dodgeTimer > 0f)
			{
				return false;
			}
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			if (!((BaseAI)this).IsAlerted() || !m_viking.CanDodge())
			{
				return false;
			}
			float num = Vector3.Distance(((Component)target).transform.position, ((Component)this).transform.position);
			if (num > m_dodgeDistance)
			{
				return false;
			}
			if (ShouldDodgeTarget(target, num))
			{
				Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position;
				Vector3 dir = CalculateDodgeDirection(((Vector3)(ref val)).normalized, num);
				m_viking.Dodge(dir);
				m_dodgeTimer = m_dodgeCooldown;
				return true;
			}
			return false;
		}

		private bool ShouldDodgeTarget(Character target, float distance)
		{
			if (!target.InAttack() && !target.IsDrawingBow())
			{
				return false;
			}
			float num;
			if (distance < m_dodgeThreatDistance)
			{
				num = Mathf.Lerp(0.8f, 0.6f, distance / m_dodgeThreatDistance);
			}
			else
			{
				float num2 = (distance - m_dodgeThreatDistance) / (m_dodgeDistance - m_dodgeThreatDistance);
				num = Mathf.Lerp(0.6f, 0.1f, num2);
			}
			return Random.value < num;
		}

		private Vector3 CalculateDodgeDirection(Vector3 toTargetNormalized, float distance)
		{
			//IL_0019: 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_001f: 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_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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (distance < m_dodgeThreatDistance)
			{
				return -toTargetNormalized;
			}
			Vector3 val = Vector3.Cross(Vector3.up, toTargetNormalized);
			float num = ((Random.value > 0.5f) ? 1f : (-1f));
			Vector3 val2 = -toTargetNormalized + val * num;
			return ((Vector3)(ref val2)).normalized;
		}

		public bool UpdateFishing(float dt, ItemData fishingRod, bool isFollowing)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_fish == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)m_fish).gameObject == (Object)null)
			{
				ResetWorkTargets();
				return false;
			}
			if (m_bait == null || !((Humanoid)m_viking).GetInventory().ContainsItem(m_bait))
			{
				ResetWorkTargets();
				((Humanoid)m_viking).UnequipItem(fishingRod, true);
				return false;
			}
			if (isFollowing)
			{
				float num = Vector3.Distance(((Component)m_fish).transform.position, ((Component)this).transform.position);
				if (num > 20f)
				{
					ResetWorkTargets();
					return false;
				}
			}
			if (!((BaseAI)this).MoveTo(dt, ((Component)m_fish).transform.position, 15f, false))
			{
				return true;
			}
			((BaseAI)this).StopMoving();
			((BaseAI)this).LookAt(((Component)m_fish).transform.position);
			CastFishingRod(fishingRod, m_fish);
			m_lastWorkActionTime = Time.time;
			((BaseAI)this).m_nview.GetZDO().Set(VikingVars.lastWorkTime, ZNet.instance.GetTime().Ticks);
			return true;
		}

		public void CastFishingRod(ItemData fishingRod, Fish fish)
		{
			if (m_viking.StartWork(fishingRod) && ((Humanoid)m_viking).GetInventory().CanAddItem(fish.m_itemDrop.m_itemData, 1))
			{
				((Humanoid)m_viking).GetInventory().AddItem(((Object)fish.m_itemDrop.m_itemData.m_dropPrefab).name, 1, fish.m_itemDrop.m_itemData.m_quality, 0, 0L, "", false);
				((BaseAI)this).m_nview.GetZDO().Set(VikingVars.lastWorkTargetResource, ((Object)fish.m_itemDrop.m_itemData.m_dropPrefab).name);
			}
		}

		public bool UpdateFlee(float dt, bool isTamed, bool isAlerted)
		{
			if (isTamed && m_moveType == Movement.Guard)
			{
				return false;
			}
			if (UpdateFleeNotAlerted(dt, isAlerted))
			{
				return true;
			}
			if (UpdateFleeLowHealth(dt))
			{
				return true;
			}
			if (UpdateFleeLava(dt))
			{
				return true;
			}
			UpdateBiome(dt);
			if (UpdateFleeMountain(dt, 50f))
			{
				return true;
			}
			if (UpdateFleeTar(dt, 50f))
			{
				return true;
			}
			return false;
		}

		public bool UpdateFleeNotAlerted(float dt, bool isAlerted)
		{
			//IL_006a: 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)
			if (base.m_fleeIfNotAlerted && !((BaseAI)this).HuntPlayer() && Object.op_Implicit((Object)(object)base.m_targetCreature) && !isAlerted && Vector3.Distance(((Component)base.m_targetCreature).transform.position, ((Component)this).transform.position) - base.m_targetCreature.GetRadius() > base.m_alertRange)
			{
				((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position);
				return true;
			}
			return false;
		}

		public bool UpdateFleeLowHealth(float dt)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if ((double)base.m_fleeIfLowHealth > 0.0 && ((BaseAI)this).m_timeSinceHurt < base.m_fleeTimeSinceHurt && (Object)(object)base.m_targetCreature != (Object)null && (double)((BaseAI)this).m_character.GetHealthPercentage() < (double)base.m_fleeIfLowHealth)
			{
				((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position);
				return true;
			}
			return false;
		}

		public bool UpdateFleeLava(float dt)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (base.m_fleeInLava && ((BaseAI)this).m_character.InLava() && ((Object)(object)base.m_targetCreature == (Object)null || base.m_targetCreature.AboveOrInLava()))
			{
				((BaseAI)this).Flee(dt, ((Component)((BaseAI)this).m_character).transform.position - ((Component)((BaseAI)this).m_character).transform.forward);
				return true;
			}
			return false;
		}

		public void UpdateBiome(float dt)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			m_biomeTimer += dt;
			if (!(m_biomeTimer <= 1f))
			{
				m_biomeTimer = 0f;
				m_currentBiome = Heightmap.FindBiome(((Component)this).transform.position);
			}
		}

		public bool UpdateFleeMountain(float dt, float maxRange)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0034: Invalid comparison between Unknown and I4
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Invalid comparison between Unknown and I4
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			if ((int)m_currentBiome != 4)
			{
				return false;
			}
			DamageModifiers damageModifiers = ((Character)m_viking).GetDamageModifiers((WeakSpot)null);
			DamageModifier modifier = ((DamageModifiers)(ref damageModifiers)).GetModifier((DamageType)64);
			if (((int)modifier == 1 || modifier - 3 <= 2) ? true : false)
			{
				return false;
			}
			float num = (m_haveNonMountainPosition ? 2f : 0.5f);
			float num2 = Time.time - m_lastMoveAwayFromMountainTimer;
			if (num2 > num)
			{
				m_lastMoveAwayFromMountainTimer = Time.time;
				m_haveNonMountainPosition = false;
				for (int i = 0; i < 10; i++)
				{
					Vector3 val = ((Component)this).transform.position + Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f) * Vector3.forward * Random.Range(4f, maxRange);
					Biome val2 = Heightmap.FindBiome(val);
					if ((int)val2 != 4)
					{
						val.y = ZoneSystem.instance.GetSolidHeight(val);
						m_moveAwayFromMountainPosition = val;
						m_haveNonMountainPosition = true;
					}
				}
			}
			if (!m_haveNonMountainPosition)
			{
				return false;
			}
			((BaseAI)this).MoveTowards(m_moveAwayFromMountainPosition - ((Component)this).transform.position, true);
			return true;
		}

		public bool UpdateFleeTar(float dt, float maxRange)
		{
			//IL_0118: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)m_viking).GetSEMan().HaveStatusEffect(SEMan.s_statusEffectTared))
			{
				return false;
			}
			float num = (m_haveNonTarPosition ? 2f : 0.5f);
			float num2 = Time.time - m_lastMoveAwayFromTar;
			if (num2 > num)
			{
				m_lastMoveAwayFromTar = Time.time;
				m_haveNonTarPosition = false;
				for (int i = 0; i < 10; i++)
				{
					Vector3 val = ((Component)this).transform.position + Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f) * Vector3.forward * Random.Range(4f, maxRange);
					float liquidLevel = Floating.GetLiquidLevel(val, 1f, (LiquidType)1);
					if (!(val.y < liquidLevel))
					{
						m_moveAwayFromTarPosition = val;
						m_haveNonTarPosition = true;
					}
				}
			}
			if (!m_haveNonTarPosition)
			{
				return false;
			}
			((BaseAI)this).MoveTowards(m_moveAwayFromTarPosition - ((Component)this).transform.position, true);
			return true;
		}

		public bool UpdateFollow(float dt)
		{
			//IL_0007: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Distance(((Component)this).transform.position, base.m_follow.transform.position);
			bool flag = num > 5f;
			if ((Object)(object)m_followPlayer != (Object)null)
			{
				flag |= ((Character)m_followPlayer).IsRunning();
			}
			if (num < 3f)
			{
				return false;
			}
			if (num > 15f)
			{
				if ((Object)(object)m_followPlayer != (Object)null && ((Character)m_followPlayer).IsTeleporting())
				{
					((BaseAI)this).StopMoving();
					return true;
				}
				if (!((Character)m_viking).IsEncumbered())
				{
					TeleportToFollow();
					return true;
				}
			}
			if (((BaseAI)this).IsAlerted())
			{
				return false;
			}
			((BaseAI)this).MoveTo(dt, base.m_follow.transform.position, 0f, flag);
			return true;
		}

		public void TeleportToFollow()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			((Character)m_viking).TeleportTo(base.m_follow.transform.position + base.m_follow.transform.forward * -2f, ((Component)this).transform.rotation, false);
		}

		public bool UpdateHurt(float dt, bool isTamed)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			if (isTamed && m_moveType == Movement.Guard)
			{
				return false;
			}
			bool flag = (double)base.m_timeSinceAttacking > 30.0 && (double)((BaseAI)this).m_timeSinceHurt < 20.0;
			if (base.m_fleeIfHurtWhenTargetCantBeReached && (Object)(object)base.m_targetCreature != (Object)null && flag)
			{
				((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position);
				base.m_lastKnownTargetPos = ((Component)this).transform.position;
				base.m_updateTargetTimer = 1f;
				return true;
			}
			return false;
		}

		public bool UpdateInventory(bool isTamed)
		{
			//IL_0045: 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)
			if (!m_viking.IsInUse())
			{
				return false;
			}
			if (isTamed)
			{
				if (Object.op_Implicit((Object)(object)m_viking.m_currentPlayer))
				{
					((BaseAI)this).LookAt(((Character)m_viking.m_currentPlayer).GetTopPoint());
				}
				((BaseAI)this).StopMoving();
				return true;
			}
			if (Object.op_Implicit((Object)(object)m_viking.m_currentPlayer))
			{
				float value = Random.value;
				float num = 0.1f;
				if (value < num)
				{
					((BaseAI)this).LookAt(((Character)m_viking.m_currentPlayer).GetEyePoint());
				}
				if (((BaseAI)this).CanSeeTarget((Character)(object)m_viking.m_currentPlayer))
				{
					((BaseAI)this).SetAggravated(true, (AggravatedReason)2);
				}
			}
			return false;
		}

		public bool UpdateMineRockMining(float dt, ItemData pickaxe, bool isFollowing)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_mineRock == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)m_mineRock).gameObject == (Object)null)
			{
				ResetWorkTargets();
				return false;
			}
			if (isFollowing)
			{
				float num = Vector3.Distance(((Component)m_mineRock).transform.position, ((Component)this).transform.position);
				if (num > 20f)
				{
					ResetWorkTargets();
					return false;
				}
			}
			if (!((BaseAI)this).MoveTo(dt, ((Component)m_mineRock).transform.position, pickaxe.m_shared.m_attack.m_attackRange, false))
			{
				return true;
			}
			((BaseAI)this).StopMoving();
			((BaseAI)this).LookAt(((Component)m_mineRock).transform.position);
			DoPickaxe(pickaxe, m_mineRock);
			m_lastWorkActionTime = Time.time;
			((BaseAI)this).m_nview.GetZDO().Set(VikingVars.lastWorkTime, ZNet.instance.GetTime().Ticks);
			return true;
		}

		public bool UpdateMineRock5Mining(float dt, ItemData pickaxe, bool isFollowing)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_mineRock5 == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)m_mineRock5).gameObject == (Object)null)
			{
				ResetWorkTargets();
				return false;
			}
			Vector3 closestPoint;
			if (m_lastMineRock5Point != Vector3.zero)
			{
				float num = Vector3.Distance(m_lastMineRock5Point, ((Component)this).transform.position);
				if (num < 10f)
				{
					closestPoint = m_lastMineRock5Point;
				}
				else
				{
					FindNearestPoint(m_mineRock5, out closestPoint);
				}
			}
			else
			{
				FindNearestPoint(m_mineRock5, out closestPoint);
			}
			m_lastMineRock5Point = closestPoint;
			if (isFollowing)
			{
				float num2 = Vector3.Distance(m_lastMineRock5Point, ((Component)this).transform.position);
				if (num2 > 20f)
				{
					ResetWorkTargets();
					return false;
				}
			}
			if (!((BaseAI)this).MoveTo(dt, closestPoint, pickaxe.m_shared.m_attack.m_attackRange, false))
			{
				return true;
			}
			((BaseAI)this).StopMoving();
			((BaseAI)this).LookAt(closestPoint);
			DoPickaxe(pickaxe, m_mineRock5);
			m_lastWorkActionTime = Time.time;
			((BaseAI)this).m_nview.GetZDO().Set(VikingVars.lastWorkTime, ZNet.instance.GetTime().Ticks);
			return true;
		}

		public void FindNearestPoint(MineRock5 mineRock5, out Vector3 closestPoint)
		{
			//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_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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			closestPoint = ((Component)mineRock5).transform.position;
			List<Collider> list = mineRock5.m_hitAreas.Select([<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)] (HitArea x) => x.m_collider).ToList();
			if (list.Count <= 0)
			{
				return;
			}
			float num = float.MaxValue;
			for (int i = 0; i < list.Count; i++)
			{
				Collider val = list[i];
				if (!((Object)(object)val == (Object)null))
				{
					MeshCollider val2 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
					Vector3 val3 = ((val2 == null || val2.convex) ? val.ClosestPoint(((Component)this).transform.position) : val.ClosestPointOnBounds(((Component)this).transform.position));
					float num2 = Vector3.Distance(val3, ((Component)this).transform.position);
					if (num2 < num)
					{
						closestPoint = val3;
						num = num2;
					}
				}
			}
		}

		public bool UpdateDestructibleMining(float dt, ItemData pickaxe, bool isFollowing)
		{
			//IL_00e4: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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)
			if ((Object)(object)m_destructible == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)m_destructible).gameObject == (Object)null)
			{
				ResetWorkTargets();
				return false;
			}
			Vector3 val;
			if ((Object)(object)m_destructible.m_spawnWhenDestroyed != (Object)null)
			{
				Collider componentInChildren = ((Component)m_destructible).GetComponentInChildren<Collider>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					val = ((Component)m_destructible).transform.position;
				}
				else
				{
					MeshCollider val2 = (MeshCollider)(object)((componentInChildren is MeshCollider) ? componentInChildren : null);
					val = ((val2 == null || val2.convex) ? componentInChildren.ClosestPoint(((Component)this).transform.position) : componentInChildren.ClosestPointOnBounds(((Component)this).transform.position));
				}
			}
			else
			{
				val = ((Component)m_destructible).transform.position;
			}
			if (isFollowing)
			{
				float num = Vector3.Distance(val, ((Component)this).transform.position);
				if (num > 20f)
				{
					ResetWorkTargets();
					return false;
				}
			}
			if (!((BaseAI)this).MoveTo(dt, val, pickaxe.m_shared.m_attack.m_attackRange, false))
			{
				return true;
			}
			((BaseAI)this).StopMoving();
			((BaseAI)this).LookAt(((Component)m_destructible).transform.position);
			DoPickaxe(pickaxe, m_destructible);
			m_lastWorkActionTime = Time.time;
			((BaseAI)this).m_nview.GetZDO().Set(VikingVars.lastWorkTime, ZNet.instance.GetTime().Ticks);
			return true;
		}

		public void DoPickaxe(ItemData pickaxe, MineRock mineRock)
		{
			if (m_viking.StartWork(pickaxe))
			{
				List<DropData> drops = mineRock.m_dropItems.m_drops;
				AddResources(drops);
			}
		}

		public void DoPickaxe(ItemData pickaxe, MineRock5 mineRock5)
		{
			if (m_viking.StartWork(pickaxe))
			{
				List<DropData> drops = mineRock5.m_dropItems.m_drops;
				AddResources(drops);
			}
		}

		public void DoPickaxe(ItemData pickaxe, Destructible destructible)
		{
			if (!m_viking.StartWork(pickaxe))
			{
				return;
			}
			List<DropData> list = null;
			if ((Object)(object)destructible.m_spawnWhenDestroyed != (Object)null)
			{
				MineRock5 component = destructible.m_spawnWhenDestroyed.GetComponent<MineRock5>();
				if ((Object)(object)component != (Object)null)
				{
					list = component.m_dropItems.m_drops;
				}
			}
			else
			{
				DropOnDestroyed component2 = ((Component)destructible).GetComponent<DropOnDestroyed>();
				if ((Object)(object)component2 != (Object)null)
				{
					list = component2.m_dropWhenDestroyed.m_drops;
				}
			}
			if (list != null)
			{
				AddResources(list);
			}
		}

		public bool UpdateNoMonsterArea(float dt, bool isTamed)
		{
			//IL_0064: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (isTamed)
			{
				return false;
			}
			if ((Object)(object)base.m_targetCreature != (Object)null)
			{
				if (Object.op_Implicit((Object)(object)EffectArea.IsPointInsideNoMonsterArea(((Component)base.m_targetCreature).transform.position)))
				{
					((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position);
					return true;
				}
			}
			else
			{
				EffectArea val = EffectArea.IsPointCloseToNoMonsterArea(((Component)this).transform.position);
				if ((Object)(object)val != (Object)null)
				{
					((BaseAI)this).Flee(dt, ((Component)val).transform.position);
					return true;
				}
			}
			return false;
		}

		public bool UpdateAttach()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if (!m_viking.m_attached)
			{
				return false;
			}
			if ((Object)(object)m_viking.m_attachPoint != (Object)null)
			{
				((Component)this).transform.position = m_viking.m_attachPoint.position;
				((Component)this).transform.rotation = m_viking.m_attachPoint.rotation;
				Rigidbody componentInParent = ((Component)m_viking.m_attachPoint).GetComponentInParent<Rigidbody>();
				((BaseAI)this).m_body.useGravity = false;
				((BaseAI)this).m_body.linearVelocity = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.GetPointVelocity(((Component)this).transform.position) : Vector3.zero);
				((BaseAI)this).m_body.angularVelocity = Vector3.zero;
				((Character)m_viking).m_maxAirAltitude = ((Component)this).transform.position.y;
				return true;
			}
			((Character)m_viking).AttachStop();
			return false;
		}

		public void UpdateAttachShip(float dt)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			m_shipAttachTimer += dt;
			if (m_shipAttachTimer < 10f)
			{
				return;
			}
			m_shipAttachTimer = 0f;
			if (((Character)m_viking).IsAttachedToShip())
			{
				Player val = default(Player);
				if ((Object)(object)base.m_follow == (Object)null || !base.m_follow.TryGetComponent<Player>(ref val))
				{
					((Character)m_viking).AttachStop();
					return;
				}
				Ship standingOnShip = ((Character)m_viking).GetStandingOnShip();
				if ((Object)(object)standingOnShip == (Object)null || !standingOnShip.IsPlayerInBoat(val))
				{
					((Character)m_viking).AttachStop();
					((Character)m_viking).TeleportTo(((Component)val).transform.position + ((Component)val).transform.forward * 2f, ((Component)this).transform.rotation, false);
				}
			}
			else
			{
				Player val2 = default(Player);
				if ((Object)(object)base.m_follow == (Object)null || !base.m_follow.TryGetComponent<Player>(ref val2))
				{
					return;
				}
				Ship standingOnShip2 = ((Character)val2).GetStandingOnShip();
				if ((Object)(object)standingOnShip2 == (Object)null || !standingOnShip2.IsPlayerInBoat(val2))
				{
					return;
				}
				Chair[] componentsInChildren = ((Component)standingOnShip2).GetComponentsInChildren<Chair>();
				if (componentsInChildren == null)
				{
					return;
				}
				Chair[] array = componentsInChildren;
				foreach (Chair val3 in array)
				{
					Player closestPlayer = Player.GetClosestPlayer(((Component)val3).transform.position, 0.1f);
					Viking nearestViking = Viking.GetNearestViking(((Component)val3).transform.position, 0.1f);
					if (!((Object)(object)closestPlayer != (Object)null) && !((Object)(object)nearestViking != (Object)null))
					{
						((Character)m_viking).AttachStart(val3.m_attachPoint, (GameObject)null, false, false, val3.m_inShip, val3.m_attachAnimation, val3.m_detachOffset, (Transform)null);
						break;
					}
				}
			}
		}

		public bool UpdateSleeping(float dt)
		{
			((MonsterAI)this).UpdateSleep(dt);
			return ((BaseAI)this).IsSleeping();
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public void UpdateCrouch(float dt, Character target, bool canSeeTarget)
		{
			m_crouchTimer += dt;
			if (m_crouchTimer > m_crouchCheckInterval)
			{
				UpdateCrouchDecision(target, canSeeTarget);
				m_crouchTimer = 0f;
			}
			bool flag = m_viking.m_crouchToggled && m_viking.CanCrouch();
			((BaseAI)this).m_animator.SetBool(Player.s_crouching, flag);
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		private void UpdateCrouchDecision(Character target, bool canSeeTarget)
		{
			//IL_007b: 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)
			if ((Object)(object)m_followPlayer != (Object)null && ((Character)m_followPlayer).IsCrouching())
			{
				((Character)m_viking).SetCrouch(true);
				return;
			}
			if ((Object)(object)target == (Object)null)
			{
				((Character)m_viking).SetCrouch(false);
				return;
			}
			if (!((BaseAI)this).IsAlerted())
			{
				((Character)m_viking).SetCrouch(false);
				return;
			}
			float num = Vector3.Distance(((Component)target).transform.position, ((Component)this).transform.position);
			if (canSeeTarget)
			{
				if (num > 20f && num < 40f)
				{
					((Character)m_viking).SetCrouch(Random.value < 0.7f);
				}
				else if (num >= 40f)
				{
					((Character)m_viking).SetCrouch(Random.value < 0.8f);
				}
				else
				{
					((Character)m_viking).SetCrouch(Random.value < 0.2f);
				}
			}
			else
			{
				((Character)m_viking).SetCrouch(Random.value < 0.6f);
			}
		}

		public void OnWorkConfigChanged(object sender, EventArgs args)
		{
			ResetWorkTargets();
		}

		public void ResetWorkTargets()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			m_mineRock = null;
			m_mineRock5 = null;
			m_destructible = null;
			m_tree = null;
			m_lastMineRock5Point = Vector3.zero;
			m_fish = null;
			m_bait = null;
			hasWorkTarget = false;
		}

		public void FindWorkTargets(float dt)
		{
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			if (hasWorkTarget || m_viking.IsInUse())
			{
				return;
			}
			m_workTargetSearchTimer += dt;
			if (m_workTargetSearchTimer < m_workTargetSearchInterval)
			{
				return;
			}
			m_workTargetSearchTimer = 0f;
			bool canMine = m_viking.configs.CanMine;
			bool canLumber = m_viking.configs.CanLumber;
			bool canFish = m_viking.configs.CanFish;
			bool flag = (m_viking.configs.RequireFood || !m_viking.IsHungry()) && (canMine || canLumber || canFish);
			ResetWorkTargets();
			if (!flag || (m_viking.m_pickaxe == null && m_viking.m_axe == null && m_viking.m_fishingRod == null))
			{
				return;
			}
			float num = float.MaxValue;
			float num2 = float.MaxValue;
			float num3 = float.MaxValue;
			float num4 = float.MaxValue;
			float num5 = float.MaxValue;
			MineRock val = null;
			MineRock5 val2 = null;
			TreeBase val3 = null;
			Destructible val4 = null;
			Fish val5 = null;
			List<ZNetView> list = ZNetScene.instance.m_instances.Values.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				ZNetView val6 = list[i];
				float num6 = Vector3.Distance(((Component)this).transform.position, ((Component)val6).transform.position);
				if (num6 > 50f)
				{
					continue;
				}
				if (m_viking.m_pickaxe != null && canMine)
				{
					MineRock component = ((Component)val6).GetComponent<MineRock>();
					if ((Object)(object)component != (Object)null)
					{
						if (m_viking.m_pickaxe.m_shared.m_toolTier >= component.m_minToolTier && component.m_dropItems.m_drops.IsOreVein() && num6 < num)
						{
							num = num6;
							val = component;
						}
						continue;
					}
					MineRock5 component2 = ((Component)val6).GetComponent<MineRock5>();
					if ((Object)(object)component2 != (Object)null)
					{
						if (m_viking.m_pickaxe.m_shared.m_toolTier >= component2.m_minToolTier && component2.m_dropItems.m_drops.IsOreVein() && num6 < num2)
						{
							num2 = num6;
							val2 = component2;
						}
						continue;
					}
					Destructible component3 = ((Component)val6).GetComponent<Destructible>();
					if ((Object)(object)component3 != (Object)null)
					{
						if (m_viking.m_pickaxe.m_shared.m_toolTier < component3.m_minToolTier)
						{
							continue;
						}
						if ((Object)(object)component3.m_spawnWhenDestroyed != (Object)null)
						{
							component2 = component3.m_spawnWhenDestroyed.GetComponent<MineRock5>();
							if (!component2.m_dropItems.m_drops.IsOreVein())
							{
								continue;
							}
							if ((Object)(object)component2 != (Object)null)
							{
								if (num6 < num4)
								{
									val4 = component3;
									num4 = num6;
								}
								continue;
							}
						}
						DropOnDestroyed component4 = ((Component)component3).GetComponent<DropOnDestroyed>();
						if ((Object)(object)component4 != (Object)null)
						{
							if (component4.m_dropWhenDestroyed.m_drops.IsOreVein() && num6 < num4)
							{
								val4 = component3;
								num4 = num6;
							}
							continue;
						}
					}
				}
				if (m_viking.m_axe != null && canLumber)
				{
					TreeBase component5 = ((Component)val6).GetComponent<TreeBase>();
					if ((Object)(object)component5 != (Object)null)
					{
						if (m_viking.m_axe.m_shared.m_toolTier >= component5.m_minToolTier && num6 < num3)
						{
							num3 = num6;
							val3 = component5;
						}
						continue;
					}
				}
				if (!(m_viking.m_fishingRod != null && canFish))
				{
					continue;
				}
				Fish component6 = ((Component)val6).GetComponent<Fish>();
				if (!((Object)(object)component6 != (Object)null))
				{
					continue;
				}
				bool flag2 = false;
				foreach (BaitSetting bait in component6.m_baits)
				{
					if (((Humanoid)m_viking).GetInventory().HaveItem(bait.m_bait.m_itemData.m_shared.m_name, true))
					{
						flag2 = true;
						m_bait = ((Humanoid)m_viking).GetInventory().GetItem(bait.m_bait.m_itemData.m_shared.m_name, -1, false);
						break;
					}
				}
				if (flag2 && num6 < num5)
				{
					num5 = num6;
					val5 = component6;
				}
			}
			float num7 = Mathf.Min(new float[5] { num, num2, num3, num4, num5 });
			if (Math.Abs(num7 - num) < 1f && (Object)(object)val != (Object)null)
			{
				m_mineRock = val;
				hasWorkTarget = true;
				((Humanoid)m_viking).EquipItem(m_viking.m_pickaxe, true);
				NorsemenPlugin.LogDebug("[" + m_viking.GetName() + "] found an ore deposit: " + ((Object)m_mineRock).name);
			}
			else if (Math.Abs(num7 - num2) < 1f && (Object)(object)val2 != (Object)null)
			{
				m_mineRock5 = val2;
				hasWorkTarget = true;
				((Humanoid)m_viking).EquipItem(m_viking.m_pickaxe, true);
				NorsemenPlugin.LogDebug("[" + m_viking.GetName() + "] found an ore deposit: " + ((Object)m_mineRock5).name);
			}
			else if (Math.Abs(num7 - num4) < 1f && (Object)(object)val4 != (Object)null)
			{
				m_destructible = val4;
				hasWorkTarget = true;
				((Humanoid)m_viking).EquipItem(m_viking.m_pickaxe, true);
				NorsemenPlugin.LogDebug("[" + m_viking.GetName() + "] found an ore deposit: " + ((Object)m_destructible).name);
			}
			else if (Math.Abs(num7 - num3) < 1f && (Object)(object)val3 != (Object)null)
			{
				m_tree = val3;
				hasWorkTarget = true;
				((Humanoid)m_viking).EquipItem(m_viking.m_axe, true);
				NorsemenPlugin.LogDebug("[" + m_viking.GetName() + "] found a tree: " + ((Object)m_tree).name);
			}
			else if (Math.Abs(num7 - num5) < 1f && (Object)(object)val5 != (Object)null)
			{
				m_fish = val5;
				hasWorkTarget = true;
				((Humanoid)m_viking).EquipItem(m_viking.m_fishingRod, true);
				NorsemenPlugin.LogDebug("[" + m_viking.GetName() + "] found a fish: " + ((Object)m_fish).name);
			}
		}

		public override void Awake()
		{
			((MonsterAI)this).Awake();
			m_viking = ((Component)this).GetComponent<Viking>();
			bool flag = ((Character)m_viking).IsTamed();
			((BaseAI)this).m_aggravatable = ((BaseAI)this).m_aggravatable && !flag;
		}

		public override bool UpdateAI(float dt)
		{
			if (!UpdateBaseAI(dt))
			{
				return false;
			}
			bool flag = ((Character)m_viking).IsTamed();
			if (flag)
			{
				UpdateBehaviour(dt);
			}
			if (flag)
			{
				UpdateAttachShip(dt);
				if (UpdateAttach())
				{
					return true;
				}
			}
			if (UpdateInventory(flag))
			{
				return true;
			}
			if (!flag && ((BaseAI)this).HuntPlayer())
			{
				((BaseAI)this).SetAlerted(true);
			}
			UpdateTargets(m_viking, flag, dt, out var canHearTarget, out var canSeeTarget);
			if (!flag && UpdateDespawn(dt, canSeeTarget))
			{
				return true;
			}
			if (UpdateFlee(dt, flag, ((BaseAI)this).IsAlerted()))
			{
				return true;
			}
			if (UpdateAvoidFire(dt, flag))
			{
				return true;
			}
			if (UpdateNoMonsterArea(dt, flag))
			{
				return true;
			}
			bool flag2 = (Object)(object)base.m_follow != (Object)null;
			if (flag2 && UpdateFollow(dt))
			{
				return true;
			}
			if (UpdateHurt(dt, flag))
			{
				return true;
			}
			bool flag3 = (Object)(object)base.m_targetStatic != (Object)null || (Object)(object)base.m_targetCreature != (Object)null;
			if (UpdateConsume(dt, m_viking, flag3, flag))
			{
				return true;
			}
			bool flag4 = !flag || m_moveType != Movement.Guard;
			if (!flag3 && flag4)
			{
				FindWorkTargets(dt);
				if (hasWorkTarget && UpdateWork(dt, m_viking.m_pickaxe, m_viking.m_axe, m_viking.m_fishingRod, flag2))
				{
					return true;
				}
			}
			if (UpdateCircleTarget(dt, flag))
			{
				return true;
			}
			ItemData val = ((MonsterAI)this).SelectBestAttack((Humanoid)(object)m_viking, dt);
			bool flag5 = val != null;
			bool flag6 = val != null && Time.time - val.m_lastAttackTime > val.m_shared.m_aiAttackInterval;
			bool flag7 = ((BaseAI)this).m_character.GetTimeSinceLastAttack() >= base.m_minAttackInterval;
			bool doAttack = val != null && flag6 && flag7;
			UpdateChargeAttack(dt, flag5, flag3, doAttack, val);
			if (UpdateCirculate(dt, flag5, doAttack, flag))
			{
				return true;
			}
			UpdateCrouch(dt, base.m_targetCreature, canSeeTarget);
			UpdateBlock(dt, base.m_targetCreature, canSeeTarget);
			if (UpdateAttack(dt, val, doAttack, canHearTarget, canSeeTarget, flag))
			{
				return true;
			}
			if (!flag2 && (!flag || m_moveType == Movement.Patrol))
			{
				((BaseAI)this).IdleMovement(dt);
			}
			else
			{
				((BaseAI)this).StopMoving();
			}
			if (!flag5 || !flag3)
			{
				((BaseAI)this).ChargeStop();
			}
			return true;
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(2)]
		public bool UpdateWork(float dt, ItemData pickaxe, ItemData axe, ItemData fishingRod, bool isFollowing)
		{
			if (m_viking.IsInUse())
			{
				return false;
			}
			if (((BaseAI)this).IsAlerted())
			{
				ResetWorkTargets();
				return false;
			}
			if (pickaxe == null && axe == null && fishingRod == null)
			{
				return false;
			}
			if (m_viking.configs.workRequiresFood.Value != 0 && m_viking.IsHungry() && ((Character)m_viking).IsTamed())
			{
				return false;
			}
			if (!(Time.time - m_lastWorkActionTime > m_workInterval))
			{
				((BaseAI)this).StopMoving();
				return true;
			}
			bool canMine = m_viking.configs.CanMine;
			if (pickaxe != null && canMine)
			{
				if (UpdateMineRockMining(dt, pickaxe, isFollowing))
				{
					return true;
				}
				if (UpdateMineRock5Mining(dt, pickaxe, isFollowing))
				{
					return true;
				}
				if (UpdateDestructibleMining(dt, pickaxe, isFollowing))
				{
					return true;
				}
			}
			bool canLumber = m_viking.configs.CanLumber;
			if (axe != null && canLumber && UpdateLogging(dt, axe, isFollowing))
			{
				return true;
			}
			bool canFish = m_viking.configs.CanFish;
			if (fishingRod != null && canFish && UpdateFishing(dt, fishingRod, isFollowing))
			{
				return true;
			}
			return false;
		}

		public void AddResources(List<DropData> resources)
		{
			//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_0082: Unknown result type (might be due to invalid IL or missing references)
			if (resources.Count <= 0)
			{
				return;
			}
			float num = Time.time - m_lastResourceGainedTime;
			if (!(num < m_viking.configs.WorkResourceInterval))
			{
				DropData val = resources[Random.Range(0, resources.Count)];
				string name = ((Object)val.m_item).name;
				((BaseAI)this).m_nview.GetZDO().Set(VikingVars.lastWorkTargetResource, name);
				if (((Humanoid)m_viking).GetInventory().CanAddItem(val.m_item, 1))
				{
					((Humanoid)m_viking).GetInventory().AddItem(name, 1, 1, 0, 0L, "", false);
					m_lastResourceGainedTime = Time.time;
				}
			}
		}
	}
	public enum Emotion
	{
		Aggressive,
		Passive
	}
	public enum Movement
	{
		Patrol,
		Guard
	}
	[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
	[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(0)]
	public class VikingTomb : MonoBehaviour
	{
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		[HarmonyPatch(typeof(TombStone), "GetHoverText")]
		private static class TombStone_GetHoverText
		{
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static bool Prefix(TombStone __instance, ref string __result)
			{
				VikingTomb vikingTomb = default(VikingTomb);
				if (!((Component)__instance).TryGetComponent<VikingTomb>(ref vikingTomb))
				{
					return true;
				}
				__result = vikingTomb.GetHoverText();
				return false;
			}
		}

		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		[HarmonyPatch(typeof(TombStone), "Interact")]
		private static class TombStone_Interact
		{
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static bool Prefix(TombStone __instance, Humanoid character, bool hold, bool alt, ref bool __result)
			{
				VikingTomb vikingTomb = default(VikingTomb);
				if (!((Component)__instance).TryGetComponent<VikingTomb>(ref vikingTomb))
				{
					return true;
				}
				__result = vikingTomb.Interact(character, hold, alt);
				return false;
			}
		}

		[HarmonyPatch(typeof(Player))]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		private static class Player_GetActionProgress
		{
			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPatch("GetActionProgress")]
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static void Postfix(Player __instance, ref string name, ref float progress, [<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)] ref MinorActionData data)
			{
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && data == null && !((Object)(object)m_currentTomb == (Object)null) && m_currentTomb.IsReviving() && m_currentTomb.m_action != null)
				{
					data = m_currentTomb.m_action;
					name = m_currentTomb.m_action.m_progressText;
					progress = Mathf.Clamp01(m_currentTomb.m_action.m_time / m_currentTomb.m_action.m_duration);
				}
			}
		}

		public static readonly List<VikingTomb> instances = new List<VikingTomb>();

		public ZNetView m_nview = null;

		public TombStone m_tombstone = null;

		public bool m_revived;

		public float m_reviveDuration = 10f;

		public float m_cancelDistance = 10f;

		public float m_revertDistance = 5f;

		public float m_checkInterval = 0.5f;

		public static readonly EffectList reviveEffects = new EffectList();

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public Player m_reviver;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public MinorActionData m_action;

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
		public static VikingTomb m_currentTomb;

		public void Awake()
		{
			instances.Add(this);
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_tombstone = ((Component)this).GetComponent<TombStone>();
		}

		public void OnDestroy()
		{
			instances.Remove(this);
		}

		public void FixedUpdate()
		{
			UpdateRevive();
		}

		public void UpdateRevive()
		{
			//IL_0027: 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)
			if (m_action != null && !((Object)(object)m_reviver == (Object)null))
			{
				float num = Vector3.Distance(((Component)this).transform.position, ((Component)m_reviver).transform.position);
				if (num > m_cancelDistance)
				{
					m_action = null;
					m_currentTomb = null;
					m_reviver = null;
				}
				else if (num > m_revertDistance)
				{
					MinorActionData action = m_action;
					action.m_time -= Time.fixedDeltaTime;
				}
				else
				{
					MinorActionData action2 = m_action;
					action2.m_time += Time.fixedDeltaTime;
				}
			}
		}

		public string GetHoverText()
		{
			if (!m_nview.IsValid())
			{
				return string.Empty;
			}
			if (m_tombstone.m_container.GetInventory().NrOfItems() == 0)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(m_tombstone.m_text + " " + m_tombstone.GetOwnerName());
			bool @bool = m_nview.GetZDO().GetBool(VikingVars.reviving, false);
			if (!@bool)
			{
				stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $piece_container_open");
			}
			string text = (@bool ? "$norseman_cancel" : "$norseman_revive");
			stringBuilder.Append("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] " + text);
			return Localization.instance.Localize(stringBuilder.ToString());
		}

		public void Setup(Viking viking)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = m_nview.GetZDO();
			if (zDO != null)
			{
				zDO.Set(VikingVars.vikingPrefab, ((Object)viking).name.Replace("(Clone)", ""));
				zDO.Set(ZDOVars.s_tamedName, viking.GetText());
				zDO.Set(ZDOVars.s_level, ((Character)viking).GetLevel(), false);
				zDO.Set(ZDOVars.s_hairColor, viking.m_hairColor);
				zDO.Set(ZDOVars.s_modelIndex, ((Humanoid)viking).m_visEquipment.GetModelIndex(), false);
				zDO.Set(ZDOVars.s_hairItem, ((Humanoid)viking).m_hairItem);
				zDO.Set(ZDOVars.s_hairColor, viking.m_hairColor);
				zDO.Set(ZDOVars.s_beardItem, ((Humanoid)viking).m_beardItem);
				zDO.Set(ZDOVars.s_skinColor, viking.m_skinColor);
				zDO.Set(VikingVars.behaviour, (int)viking.m_vikingAI.m_behaviour, false);
				zDO.Set(VikingVars.patrol, (int)viking.m_vikingAI.m_moveType, false);
				zDO.Set(VikingVars.isElf, viking.m_isElf);
			}
		}

		public bool Revive()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_reviver == (Object)null)
			{
				return false;
			}
			string @string = m_nview.GetZDO().GetString(VikingVars.vikingPrefab, "");
			GameObject prefab = ZNetScene.instance.GetPrefab(@string);
			if ((Object)(object)prefab == (Object)null)
			{
				return false;
			}
			string string2 = m_nview.GetZDO().GetString(ZDOVars.s_tamedName, "");
			int @int = m_nview.GetZDO().GetInt(ZDOVars.s_level, 0);
			Vector3 vec = m_nview.GetZDO().GetVec3(ZDOVars.s_hairColor, Vector3.zero);
			int int2 = m_nview.GetZDO().GetInt(ZDOVars.s_modelIndex, 0);
			string string3 = m_nview.GetZDO().GetString(ZDOVars.s_hairItem, "");
			string string4 = m_nview.GetZDO().GetString(ZDOVars.s_beardItem, "");
			Vector3 vec2 = m_nview.GetZDO().GetVec3(ZDOVars.s_skinColor, Vector3.one);
			string string5 = m_nview.GetZDO().GetString(ZDOVars.s_items, "");
			int int3 = m_nview.GetZDO().GetInt(VikingVars.behaviour, 0);
			int int4 = m_nview.GetZDO().GetInt(VikingVars.patrol, 0);
			bool @bool = m_nview.GetZDO().GetBool(VikingVars.isElf, false);
			int stableHashCode = StringExtensionMethods.GetStableHashCode(@string);
			ZDO val = ZDOMan.instance.CreateNewZDO(((Component)this).transform.position, stableHashCode);
			val.SetPrefab(stableHashCode);
			val.Set(VikingVars.isSet, true);
			val.Set(ZDOVars.s_tamedName, string2);
			val.Set(ZDOVars.s_level, @int, false);
			val.Set(ZDOVars.s_hairItem, string3);
			val.Set(ZDOVars.s_beardItem, string4);
			val.Set(ZDOVars.s_skinColor, vec2);
			val.Set(ZDOVars.s_hairColor, vec);
			val.Set(VikingVars.behaviour, int3, false);
			val.Set(VikingVars.patrol, int4, false);
			val.Set(ZDOVars.s_tamed, true);
			val.Set(ZDOVars.s_modelIndex, int2, false);
			val.Set(VikingVars.createTombStone, true);
			val.Set(ZDOVars.s_items, string5);
			val.Set(ZDOVars.s_addedDefaultItems, true);
			val.Set(VikingVars.lastLevelUpTime, ZNet.instance.GetTime().Ticks);
			val.Set(VikingVars.createTombStone, true);
			val.Set(VikingVars.isElf, @bool);
			val.Set(ZDOVars.s_follow, m_reviver.GetPlayerName());
			ZNetScene.instance.CreateObject(val);
			m_tombstone.m_container.GetInventory().RemoveAll();
			m_revived = true;
			m_reviver = null;
			return true;
		}

		public bool IsReviving()
		{
			return ((MonoBehaviour)this).IsInvoking("CheckReviveProgress");
		}

		public void CheckReviveProgress()
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_reviver == (Object)null || m_action == null)
			{
				NorsemenPlugin.LogDebug("Reviver is null or progress action is null, canceling");
				m_nview.GetZDO().Set(VikingVars.reviving, false);
				((MonoBehaviour)this).CancelInvoke("CheckReviveProgress");
			}
			else if (m_action.m_time >= m_action.m_duration)
			{
				((MonoBehaviour)this).CancelInvoke("CheckReviveProgress");
				((MonoBehaviour)this).Invoke("Revive", 1f);
				reviveEffects.Create(((Component)this).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
				m_nview.GetZDO().Set(VikingVars.reviving, false);
				m_action = null;
				m_currentTomb = null;
			}
			else if (m_action.m_time <= 0f)
			{
				((MonoBehaviour)this).CancelInvoke("CheckReviveProgress");
				m_nview.GetZDO().Set(VikingVars.reviving, false);
				m_action = null;
				m_reviver = null;
				m_currentTomb = null;
			}
		}

		public bool Interact(Humanoid character, bool hold, bool alt)
		{
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			if (hold || m_tombstone.m_container.GetInventory().NrOfItems() == 0)
			{
				return false;
			}
			Player val = (Player)(object)((character is Player) ? character : null);
			if (val == null)
			{
				return false;
			}
			bool @bool = m_nview.GetZDO().GetBool(VikingVars.reviving, false);
			if (!m_nview.IsOwner() && @bool)
			{
				((Character)character).Message((MessageType)2, "$msg_inuse", 0, (Sprite)null);
				return false;
			}
			if (alt)
			{
				if ((Object)(object)m_currentTomb != (Object)null)
				{
					((Character)character).Message((MessageType)2, "$norseman_revive_inuse " + m_currentTomb.m_tombstone.GetOwnerName(), 0, (Sprite)null);
					return false;
				}
				if (m_revived)
				{
					return false;
				}
				if (!((MonoBehaviour)this).IsInvoking("CheckReviveProgress"))
				{
					m_nview.ClaimOwnership();
					m_reviver = val;
					m_currentTomb = this;
					m_action = new MinorActionData
					{
						m_duration = m_reviveDuration,
						m_progressText = "$norseman_reviving " + m_tombstone.GetOwnerName(),
						m_type = (ActionType)2
					};
					((MonoBehaviour)this).InvokeRepeating("CheckReviveProgress", 1f, m_checkInterval);
					m_nview.GetZDO().Set(VikingVars.reviving, true);
				}
				else
				{
					m_nview.GetZDO().Set(VikingVars.reviving, false);
					((MonoBehaviour)this).CancelInvoke("CheckReviveProgress");
					m_action = null;
					m_reviver = null;
					m_currentTomb = null;
				}
				return true;
			}
			if (@bool)
			{
				return false;
			}
			return m_tombstone.m_container.Interact(character, false, false);
		}

		public static void RemoveAll()
		{
			int num = 0;
			foreach (VikingTomb instance in instances)
			{
				ZNetScene.instance.Destroy(((Component)instance).gameObject);
				num++;
			}
			NorsemenPlugin.LogDebug($"Removed {num} norsemen tombstones");
		}
	}
	public static class VikingVars
	{
		public static readonly int isSet = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.IsSet");

		public static readonly int lastWorkTime = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.LastWorkTime");

		public static readonly int lastWorkTargetResource = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.LastWorkTargetType");

		public static readonly int createTombStone = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.CreateTombStone");

		public static readonly int vikingPrefab = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.VikingPrefab");

		public static readonly int reviving = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.Reviving");

		public static readonly int lastLevelUpTime = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.TameTime");

		public static readonly int inventoryChanged = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.InventoryChanged");

		public static readonly int behaviour = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.Behaviour");

		public static readonly int patrol = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.Patrol");

		public static readonly int isElf = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.IsElf");

		public static readonly int isPrivate = StringExtensionMethods.GetStableHashCode("RustyMods.Norsemen.IsPrivate");
	}
	[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
	[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(0)]
	public class Viking : Humanoid, Interactable, TextReceiver
	{
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		[HarmonyPatch(typeof(Attack), "HaveAmmo")]
		private static class Attack_HaveAmmo
		{
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static void Postfix(Humanoid character, ref bool __result)
			{
				if (!__result && character is Viking)
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "FindAmmo")]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		private static class Attack_FindAmmo_Patch
		{
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static void Postfix(Humanoid character, ItemData weapon, [<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)] ref ItemData __result)
			{
				if (__result != null || !(character is Viking viking) || string.IsNullOrEmpty(weapon.m_shared.m_ammoType))
				{
					return;
				}
				string ammoType = weapon.m_shared.m_ammoType;
				string text = ammoType;
				if (!(text == "$ammo_arrows"))
				{
					if (text == "$ammo_bolts")
					{
						ItemData val = ((Humanoid)viking).GetInventory().AddItem("BoltBone", 10, 1, 0, 0L, "", false);
						if (val != null)
						{
							__result = val;
						}
					}
				}
				else
				{
					ItemData val2 = ((Humanoid)viking).GetInventory().AddItem("ArrowWood", 10, 1, 0, 0L, "", false);
					if (val2 != null)
					{
						__result = val2;
					}
				}
			}
		}

		[Serializable]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		public class ConditionalItemSet
		{
			[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(new byte[] { 1, 2 })]
			public GameObject[] m_items = Array.Empty<GameObject>();

			[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(1)]
			public string m_requiredDefeatKey = "";

			public float m_weight = 1f;

			public bool HasKey()
			{
				return string.IsNullOrEmpty(m_requiredDefeatKey) || ZoneSystem.instance.GetGlobalKey(m_requiredDefeatKey);
			}
		}

		[Serializable]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		public class ConditionalRandomItem
		{
			[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
			public GameObject m_prefab;

			[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(1)]
			public string m_requiredDefeatKey = "";

			public float m_chance = 0.5f;

			public int m_min = 1;

			public int m_max = 1;

			public bool HasKey()
			{
				return string.IsNullOrEmpty(m_requiredDefeatKey) || ZoneSystem.instance.GetGlobalKey(m_requiredDefeatKey);
			}
		}

		[Serializable]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		public class ConditionalRandomWeapon
		{
			[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(2)]
			public GameObject m_prefab;

			[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(1)]
			public string m_requiredDefeatKey = "";

			public float m_weight;

			public bool HasKey()
			{
				return string.IsNullOrEmpty(m_requiredDefeatKey) || ZoneSystem.instance.GetGlobalKey(m_requiredDefeatKey);
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(0)]
		private static class ObjectDB_Awake
		{
			[<76271666-bebe-4094-881a-4286fd275e00>NullableContext(1)]
			private static void Postfix(ObjectDB __instance)
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Invalid comparison between Unknown and I4
				ItemDrop val = default(ItemDrop);
				foreach (GameObject item in __instance.m_items)
				{
					if (item.TryGetComponent<ItemDrop>(ref val) && (int)val.m_itemData.m_shared.m_itemType == 2 && !((Object)(object)val.m_itemData.m_shared.m_consumeStatusEffect != (Object)null))
					{
						consumableItems.Add(val);
					}
				}
			}
		}

		[<3530c945-4eb1-4ca2-af3d-2dda293a1c8f>Nullable(0)]
		[HarmonyPatch(typeof(SE_Harpooned), "UpdateStatusEffect")]
		private static class SE_Harpooned_UpdateStatusEffect_Patch
		{
			private static bool Prefix(SE_Harpooned __instance, float dt)
			{
				if (!Object.op_Implicit((Object)(object)((StatusEffect)__instance).m_character) || !Object.op_Implicit((Object)(object)__instance.m_attacker) || !(__instance.m_attacker is Viking))
				{
					return true;
				}
				BaseUpdateSE(__instance, dt);
				UpdateSE_Harpooned(__instance, dt);
				return false;
			}

			private static void UpdateSE_Harpooned(SE_Harpooned __instance, float dt)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				Rigidbody val = default(Rigidbody);
				if (!((Component)((StatusEffect)__instance).m_character).TryGetComponent<Rigidbody>(ref val))
				{
					return;
				}
				float num = Vector3.Distance(((Component)__instance.m_attacker).transform.position, ((Component)((StatusEffect)__instance).m_character).transform.position);
				if (!((StatusEffect)__instance).m_character.IsAttached())
				{
					float num2 = Utils.Pull(val, ((Component)__instance.m_attacker).transform.position, m_pullTo, 25f, __instance.m_pullForce, __instance.m_smoothDistance, true, true, __instance.m_forcePower);
					__instance.m_drainStaminaTimer += dt;
					if (__instance.m_drainStaminaTi