Decompiled source of LudvigValheim v1.4.5

plugins/LudvigValheim/LudvigValheim.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LudvigValheim
{
	internal sealed class Companion : MonoBehaviour
	{
		private Plugin plugin;

		private SaveState state;

		private Transform model;

		private Model modelAnimator;

		private MapPin pin;

		private LudvigAudio audio;

		private float phaseTimer;

		private float dialogueTimer;

		private float retryTimer;

		private float chopTimer;

		private float stuckTimer;

		private float enemyScanTimer;

		private float fleeTimer;

		private float ambienceTimer;

		private float combatTimer;

		private float combatHealth = 55f;

		private float combatAttackTimer;

		private float combatFleeReturnTimer;

		private bool combatActive;

		private bool combatFled;

		private Light nightLight;

		private TempoGiganteCar tempoCar;

		private bool tempoDriving;

		private float nextCarRetry;

		private Vector3 lastMovePosition;

		private Vector3 fleeTarget;

		private int lastDialogue = -1;

		private readonly string[] chatter = new string[20]
		{
			"Den busken flyttet på seg. Jeg velger å kalle det vind.", "Du har bygget et fint hus. Har du vurdert en nødutgang til nødutgangen?", "Jeg er ikke redd for mørket. Bare det som har valgt å bo der.", "En øks er et nyttig verktøy. Særlig hvis du slipper å bruke den.", "Du sier det er en fredelig eng. Har du spurt biene?", "Jeg har spart på kreftene hele dagen. Nå har jeg nesten for mange.", "Var det en kvist som knakk? Jeg har et ganske anstrengt forhold til kvister.", "Jeg liker bålet. Det er det eneste her som freser uten å følge etter meg.", "Et troll bruker også skogen. Forskjellen er at skogen merker det.", "Vikingene sier de frykter ingenting. Det må være slitsomt å huske så lite.",
			"Jeg ville tatt snarveien, men den har for mange muligheter.", "En seng ved veggen, takk. Da kan bare halvparten av verden overraske meg.", "Du kan kalle det eventyr. Jeg fører det som uforutsette utgifter.", "Det er stille her. Litt for stille til at jeg tør å kommentere det.", "Hvis denne planen fungerer, foreslår jeg at vi slutter mens vi ligger foran.", "Jeg tok med niste. Så tok jeg en pause. Nå har jeg bare pausen igjen.", "Et gjerde er fint. Et gjerde til er enda finere.", "Jeg løper ikke fra problemer. Jeg flytter bare møtestedet.", "Du skal bygge en båt? Jeg har alltid ment fast grunn er undervurdert.", "Et hjem er der du vet hvem som lager lydene om natten."
		};

		private readonly string[] events = new string[4] { "Det var bare stein og stillhet der ute. Jeg stolte mest på steinen.", "Jeg fant en ekstra åre! Først trodde jeg det var en felle. Det kan det fortsatt være.", "Et greydverg stilte seg i veien. Jeg tok en omvei med svært grundig sikkerhetsmargin.", "Jeg fant en forlatt sekk. Ingen eier, ingen tenner. En sjelden kombinasjon." };

		internal void Init(Plugin owner, SaveState data)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			plugin = owner;
			state = data;
			model = Model.Build(((Component)this).transform, plugin);
			modelAnimator = ((Component)model).GetComponent<Model>();
			pin = new MapPin(plugin);
			audio = ((Component)this).gameObject.AddComponent<LudvigAudio>();
			audio.Init(plugin);
			CreateNightLight();
			SetVisible(state.job.phase != JobPhase.Away);
			lastMovePosition = ((Component)this).transform.position;
			dialogueTimer = Random.Range(8f, 16f);
			EnsureTempoCar();
		}

		private void EnsureTempoCar()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tempoCar != (Object)null || Time.time < nextCarRetry)
			{
				return;
			}
			nextCarRetry = Time.time + 30f;
			try
			{
				Vector3 point = state.home + new Vector3(3.2f, 0f, 1.8f);
				Plugin.Ground(ref point);
				Quaternion rotation = Quaternion.Euler(0f, 25f, 0f);
				tempoCar = TempoGiganteCar.Build(point, rotation, plugin);
				if ((Object)(object)tempoCar != (Object)null)
				{
					tempoCar.SetLights(IsNight());
					((Component)tempoCar).gameObject.SetActive(state.job.phase != JobPhase.Away || !state.tempoAdventure);
				}
			}
			catch (Exception ex)
			{
				tempoCar = null;
				plugin.LogWarning("Tempo Gigante creation failed; Ludvig will continue without the car. " + ex);
			}
		}

		private void MountTempo()
		{
			//IL_004f: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			EnsureTempoCar();
			if (!((Object)(object)tempoCar == (Object)null) && !((Object)(object)model == (Object)null))
			{
				model.SetParent(tempoCar.DriverSeat, false);
				model.localPosition = new Vector3(0f, -0.55f, 0f);
				model.localRotation = Quaternion.identity;
				((Component)this).transform.position = ((Component)tempoCar).transform.position;
				tempoDriving = true;
				tempoCar.SetDriving(driving: true);
			}
		}

		private void DismountTempo()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)model != (Object)null)
			{
				model.SetParent(((Component)this).transform, false);
				model.localPosition = Vector3.zero;
				model.localRotation = Quaternion.identity;
			}
			tempoDriving = false;
			if ((Object)(object)tempoCar != (Object)null)
			{
				tempoCar.SetDriving(driving: false);
			}
		}

		private bool DriveTempo(Vector3 destination, float dt, float speed)
		{
			//IL_001b: 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_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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			EnsureTempoCar();
			if ((Object)(object)tempoCar == (Object)null)
			{
				DismountTempo();
				return Move(destination, dt);
			}
			if (!tempoDriving)
			{
				MountTempo();
			}
			Vector3 val = destination - ((Component)tempoCar).transform.position;
			val.y = 0f;
			if (((Vector3)(ref val)).magnitude < 2.2f)
			{
				return true;
			}
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 point = ((Component)tempoCar).transform.position + normalized * Mathf.Min(((Vector3)(ref val)).magnitude, dt * speed);
			if (Plugin.Ground(ref point))
			{
				((Component)tempoCar).transform.rotation = Quaternion.Slerp(((Component)tempoCar).transform.rotation, Quaternion.LookRotation(normalized), Mathf.Clamp01(dt * 3.8f));
				((Component)tempoCar).transform.position = point;
				((Component)this).transform.position = point;
			}
			tempoCar.Animate(dt, driving: true);
			return false;
		}

		private void CreateNightLight()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Ludvig_NightLantern");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = new Vector3(0.32f, 1.18f, 0.16f);
			nightLight = val.AddComponent<Light>();
			nightLight.type = (LightType)2;
			nightLight.range = 11f;
			nightLight.intensity = 1.45f;
			nightLight.color = new Color(1f, 0.68f, 0.32f);
			nightLight.shadows = (LightShadows)2;
			((Behaviour)nightLight).enabled = false;
		}

		private bool IsNight()
		{
			try
			{
				if ((Object)(object)EnvMan.instance != (Object)null)
				{
					MethodInfo method = typeof(EnvMan).GetMethod("GetDayFraction", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (method != null)
					{
						float num = Convert.ToSingle(method.Invoke(EnvMan.instance, null));
						return num < 0.2f || num > 0.8f;
					}
				}
			}
			catch
			{
			}
			return RenderSettings.ambientIntensity < 0.55f;
		}

		private void UpdateNightLight(float dt)
		{
			bool flag = IsNight();
			if ((Object)(object)nightLight != (Object)null)
			{
				((Behaviour)nightLight).enabled = flag && state.recruited && !tempoDriving;
			}
			if ((Object)(object)tempoCar != (Object)null)
			{
				tempoCar.SetLights(flag);
			}
			ambienceTimer -= dt;
			if (!state.silent && flag && ambienceTimer <= 0f && state.recruited && state.job.phase == JobPhase.Idle && (Object)(object)audio != (Object)null && !audio.IsSpeaking)
			{
				ambienceTimer = Random.Range(75f, 130f);
				Voice("night");
			}
		}

		internal void StartOre(string prefab, string name, int coins, int capacity, bool prepaid = false)
		{
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			if (state.job.phase != JobPhase.Idle)
			{
				return;
			}
			if (Time.time < state.oreCooldownUntil)
			{
				plugin.Say("Jeg må hvile før neste malmtur. Prøv igjen om " + Mathf.CeilToInt(state.oreCooldownUntil - Time.time) + " sekunder.");
				return;
			}
			if (!plugin.ProgressionAllows(prefab))
			{
				plugin.Say("Vi har ikke kommet langt nok i verden til at jeg kan skaffe " + name + " ennå.");
				return;
			}
			if (state.woodPaid || state.woodCargo > 0)
			{
				plugin.Say("Jeg har fortsatt en betalt vedjobb. Ett bekymringsområde av gangen.");
				return;
			}
			if ((Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ObjectDB.instance.GetItemPrefab(prefab) == (Object)null)
			{
				plugin.Say("Den malmtypen finnes ikke i denne spillversjonen. Ingen betaling trukket.");
				return;
			}
			if (!plugin.Save())
			{
				plugin.Say("Jeg får ikke lagret oppdraget. Vi prøver igjen senere.");
				return;
			}
			if (!prepaid && !GameApi.SpendCoins(coins))
			{
				plugin.Say("Du har ikke nok mynter. Jeg tar betalt før jeg går meg vill.");
				Voice("pay_none");
				return;
			}
			state.departure = ((Component)this).transform.position;
			Vector3 val = -((Component)Player.m_localPlayer).transform.forward;
			Vector3 point = ((Component)this).transform.position + val * Mathf.Clamp(plugin.TravelDistance.Value, 8f, 60f);
			bool flag = false;
			for (int i = 0; i < 8; i++)
			{
				if (Plugin.Ground(ref point))
				{
					flag = true;
					break;
				}
				val = Quaternion.Euler(0f, 45f, 0f) * val;
				point = ((Component)this).transform.position + val * Mathf.Clamp(plugin.TravelDistance.Value, 8f, 60f);
			}
			if (!flag)
			{
				point = ((Component)this).transform.position;
			}
			float num;
			switch (prefab)
			{
			default:
				num = 4.5f;
				break;
			case "BlackMetalScrap":
				num = 3.5f;
				break;
			case "SilverOre":
				num = 2.7f;
				break;
			case "IronScrap":
				num = 1.8f;
				break;
			case "CopperOre":
			case "TinOre":
				num = 1f;
				break;
			}
			float num2 = num;
			state.job = Expedition.Start(prefab, name, plugin.Duration.Value * num2, capacity, Random.Range(0, 4), state.waiting);
			state.position = ((Component)this).transform.position;
			state.woodTarget = point;
			phaseTimer = 0f;
			state.oreCooldownUntil = Time.time + 90f * num2;
			plugin.Say("Da er vi enige om " + coins + " mynter. Jeg går etter " + name + ". Hvis noen spør, var dette din idé.");
			if ((Object)(object)audio != (Object)null)
			{
				switch (prefab)
				{
				case "IronScrap":
					Voice("ore_iron");
					break;
				case "CopperOre":
					Voice("ore_copper");
					break;
				case "TinOre":
					Voice("ore_tin");
					break;
				}
			}
			plugin.Save();
		}

		internal void Tick(Player player, float dt)
		{
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)audio != (Object)null)
			{
				audio.TickEnemy(dt);
			}
			UpdateNightLight(dt);
			if ((Object)(object)modelAnimator != (Object)null)
			{
				modelAnimator.Animate(0f, (Object)(object)audio != (Object)null && audio.IsSpeaking, Time.time, tempoDriving);
			}
			if (state.job.phase != JobPhase.Idle)
			{
				TickJob(player, dt);
			}
			else if (combatFled)
			{
				TickCombatReturn(dt);
			}
			else if (combatActive)
			{
				TickCombat(player, dt);
			}
			else
			{
				if (state.recruited && TickDanger(player, dt))
				{
					return;
				}
				SetVisible(visible: true);
				if (!state.recruited)
				{
					return;
				}
				if (state.woodCargo > 0)
				{
					retryTimer -= dt;
					if (retryTimer <= 0f && Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) < 6f)
					{
						retryTimer = 5f;
						state.woodCargo -= GameApi.Deliver("Wood", state.woodCargo);
						plugin.Save();
						if (state.woodCargo == 0)
						{
							plugin.Say("Veden er levert. Jeg har fortsatt flis i selvfølelsen.");
						}
					}
					if (!state.waiting && Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) > 4f)
					{
						Move(((Component)player).transform.position, dt);
					}
					return;
				}
				if (state.woodPaid)
				{
					TickWood(dt);
					return;
				}
				Vector3 val = plugin.RequesterPosition(state.requesterPeer, ((Component)player).transform.position);
				if (!state.waiting && Vector3.Distance(((Component)this).transform.position, val) > plugin.FollowDistance.Value)
				{
					Move(val, dt);
				}
				dialogueTimer -= dt;
				if (!(dialogueTimer <= 0f))
				{
					return;
				}
				dialogueTimer = Random.Range(12f, 24f);
				int num;
				do
				{
					num = Random.Range(0, chatter.Length);
				}
				while (num == lastDialogue);
				lastDialogue = num;
				if (!state.silent && Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) < 25f)
				{
					plugin.Say(chatter[num]);
					if ((Object)(object)audio != (Object)null)
					{
						Voice("idle");
					}
				}
			}
		}

		private void TickJob(Player player, float dt)
		{
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			Expedition job = state.job;
			phaseTimer += dt;
			switch (job.phase)
			{
			case JobPhase.Leaving:
				if (state.tempoAdventure)
				{
					if (DriveTempo(state.woodTarget, dt, 8.5f) || phaseTimer > 12f)
					{
						job.phase = JobPhase.Away;
						phaseTimer = 0f;
						SetVisible(visible: false);
						if ((Object)(object)tempoCar != (Object)null)
						{
							((Component)tempoCar).gameObject.SetActive(false);
						}
						plugin.Save();
					}
				}
				else
				{
					if (!Move(state.woodTarget, dt) && !(phaseTimer > 8f))
					{
						break;
					}
					if (phaseTimer > 8f)
					{
						Vector3 point = state.woodTarget;
						if (Plugin.Ground(ref point))
						{
							((Component)this).transform.position = point;
						}
					}
					job.phase = JobPhase.Away;
					phaseTimer = 0f;
					SetVisible(visible: false);
					plugin.Save();
				}
				break;
			case JobPhase.Away:
				SetVisible(visible: false);
				if (!job.eventReported && job.remaining < Math.Max(10f, plugin.Duration.Value) * 0.6f)
				{
					job.eventReported = true;
					plugin.Say("Rapport fra turen: " + events[job.eventId]);
					plugin.Save();
				}
				if (!job.AdvanceAway(dt))
				{
					break;
				}
				SetVisible(visible: true);
				phaseTimer = 0f;
				if (state.tempoAdventure)
				{
					EnsureTempoCar();
					if ((Object)(object)tempoCar != (Object)null)
					{
						((Component)tempoCar).gameObject.SetActive(true);
						((Component)tempoCar).transform.position = state.woodTarget;
						MountTempo();
					}
				}
				plugin.Save();
				break;
			case JobPhase.Returning:
			{
				SetVisible(visible: true);
				Vector3 destination = plugin.RequesterPosition(state.requesterPeer, state.departure);
				if (!(state.tempoAdventure ? DriveTempo(destination, dt, 8f) : Move(destination, dt)) && !(phaseTimer > 30f))
				{
					break;
				}
				if (phaseTimer > 30f)
				{
					((Component)this).transform.position = state.departure;
					if (state.tempoAdventure && (Object)(object)tempoCar != (Object)null)
					{
						((Component)tempoCar).transform.position = state.departure;
					}
				}
				if (state.tempoAdventure)
				{
					DismountTempo();
					state.tempoAdventure = false;
				}
				job.phase = JobPhase.Delivery;
				phaseTimer = 0f;
				plugin.Say("Tilbake med " + job.cargo + " " + job.displayName + ". Jeg vil ikke snakke om busken på veien.");
				plugin.Save();
				break;
			}
			case JobPhase.Delivery:
			{
				Vector3 val = plugin.RequesterPosition(state.requesterPeer, ((Component)player).transform.position);
				if (!job.resumeWaiting && Vector3.Distance(((Component)this).transform.position, val) > 4f)
				{
					Move(val, dt);
				}
				retryTimer -= dt;
				if (!(retryTimer <= 0f) || !(Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) < 6f))
				{
					break;
				}
				retryTimer = 5f;
				int num = GameApi.Deliver(job.ore, job.cargo);
				job.AcknowledgeDelivery(num);
				plugin.Save();
				if (job.phase == JobPhase.Idle)
				{
					if (!string.IsNullOrEmpty(state.huntSecondaryPrefab) && state.huntSecondaryCargo > 0)
					{
						int num2 = GameApi.Deliver(state.huntSecondaryPrefab, state.huntSecondaryCargo);
						state.huntSecondaryCargo -= num2;
						if (state.huntSecondaryCargo > 0)
						{
							job.phase = JobPhase.Delivery;
							plugin.Say("Jeg har også " + state.huntSecondaryCargo + " ekstra jaktvarer igjen. Lag plass.");
							plugin.Save();
							break;
						}
						state.huntSecondaryPrefab = "";
						state.huntAnimal = "";
					}
					state.waiting = job.resumeWaiting;
					plugin.Say("Alt levert. Nå tar jeg en pause med faglig begrunnelse.");
					plugin.Save();
				}
				else if (num > 0 || phaseTimer < 6f)
				{
					plugin.Say("Jeg beholder " + job.cargo + " " + job.displayName + " til du har plass. Kom nær meg igjen.");
				}
				break;
			}
			}
		}

		internal void StartWood(Player player, int coins, int capacity, bool prepaid = false)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			if (state.job.phase != JobPhase.Idle || state.woodCargo > 0)
			{
				return;
			}
			if (state.woodPaid)
			{
				plugin.Say("Du har allerede betalt. Treet husker det nok også.");
				return;
			}
			TreeBase val = FindTree(((Component)player).transform.position, plugin.TreeSearchRadius.Value);
			if ((Object)(object)val == (Object)null)
			{
				val = FindTree(((Component)player).transform.position, Mathf.Max(plugin.TreeSearchRadius.Value, 120f));
			}
			if ((Object)(object)val == (Object)null)
			{
				plugin.Say("Jeg finner ingen trær her. Jeg går litt lenger ut og leter.");
				state.woodTarget = ((Component)player).transform.position + ((Component)player).transform.forward * 35f;
				Plugin.Ground(ref state.woodTarget);
				state.woodPaid = true;
				state.woodCapacity = capacity;
				state.woodCargo = capacity;
				state.woodHits = 40;
				plugin.Save();
				return;
			}
			if (!plugin.Save())
			{
				plugin.Say("Lagringen svikter. Vi prøver igjen senere.");
				return;
			}
			if (!prepaid && !GameApi.SpendCoins(coins))
			{
				plugin.Say("Du har ikke nok mynter til den vedjobben.");
				Voice("pay_none");
				return;
			}
			state.woodPaid = true;
			state.woodHits = 0;
			state.woodCargo = 0;
			state.woodCapacity = capacity;
			state.woodTarget = ((Component)val).transform.position;
			plugin.Say("Da var betalingen i orden. Jeg hogger det treet. Du tar imot hvis det blir veldig engasjert.");
			if ((Object)(object)audio != (Object)null)
			{
				Voice("wood");
			}
			plugin.Save();
		}

		private void TickWood(float dt)
		{
			//IL_0014: 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_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_00c6: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			chopTimer -= dt;
			TreeBase val = FindTree(state.woodTarget, 1.5f);
			TreeLog val2 = null;
			Collider[] array;
			if ((Object)(object)val == (Object)null)
			{
				float num = 10f;
				array = Physics.OverlapSphere(state.woodTarget, 10f);
				for (int i = 0; i < array.Length; i++)
				{
					TreeLog componentInParent = ((Component)array[i]).GetComponentInParent<TreeLog>();
					if (!((Object)(object)componentInParent == (Object)null))
					{
						float num2 = Vector3.Distance(state.woodTarget, ((Component)componentInParent).transform.position);
						if (num2 < num)
						{
							num = num2;
							val2 = componentInParent;
						}
					}
				}
			}
			Vector3 val3 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : (((Object)(object)val2 != (Object)null) ? ((Component)val2).transform.position : state.woodTarget));
			if ((Object)(object)val != (Object)null || (Object)(object)val2 != (Object)null)
			{
				if (Vector3.Distance(((Component)this).transform.position, val3) > 2.5f)
				{
					Move(val3, dt);
					return;
				}
				if (chopTimer > 0f)
				{
					return;
				}
				chopTimer = 1.5f;
				HitData val4 = new HitData();
				val4.m_damage.m_chop = 35f;
				val4.m_toolTier = 4;
				val4.m_point = val3 + Vector3.up;
				Vector3 val5 = val3 - ((Component)this).transform.position;
				val4.m_dir = ((Vector3)(ref val5)).normalized;
				if ((Object)(object)val != (Object)null)
				{
					val.Damage(val4);
				}
				else
				{
					val2.Damage(val4);
				}
				state.woodHits++;
				if (state.woodHits < 40)
				{
					plugin.Save();
					return;
				}
			}
			if (chopTimer > -3f && state.woodHits < 40)
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Wood");
			HashSet<ItemDrop> hashSet = new HashSet<ItemDrop>();
			array = Physics.OverlapSphere(state.woodTarget, 10f);
			for (int i = 0; i < array.Length; i++)
			{
				ItemDrop componentInParent2 = ((Component)array[i]).GetComponentInParent<ItemDrop>();
				if (!((Object)(object)componentInParent2 == (Object)null) && hashSet.Add(componentInParent2) && !((Object)(object)itemPrefab == (Object)null) && !(componentInParent2.m_itemData.m_shared.m_name != itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name))
				{
					int num3 = Mathf.Max(0, state.woodCapacity - state.woodCargo);
					if (num3 <= 0)
					{
						break;
					}
					int num4 = Mathf.Min(num3, componentInParent2.m_itemData.m_stack);
					state.woodCargo += num4;
					if (num4 >= componentInParent2.m_itemData.m_stack)
					{
						ZNetScene.instance.Destroy(((Component)componentInParent2).gameObject);
						continue;
					}
					ItemData itemData = componentInParent2.m_itemData;
					itemData.m_stack -= num4;
				}
			}
			if (state.woodCargo > state.woodCapacity)
			{
				state.woodCargo = state.woodCapacity;
			}
			if (state.woodCargo < state.woodCapacity)
			{
				TreeBase val6 = FindTree(((Component)this).transform.position, plugin.TreeSearchRadius.Value);
				if ((Object)(object)val6 != (Object)null)
				{
					state.woodTarget = ((Component)val6).transform.position;
					state.woodHits = 0;
					chopTimer = 0f;
					plugin.Say("Jeg har plass til mer ved. Jeg finner et nytt tre.");
					plugin.Save();
					return;
				}
			}
			state.woodPaid = false;
			if ((Object)(object)audio != (Object)null)
			{
				Voice("wood_done");
			}
			plugin.Say((state.woodCargo > 0) ? ("Sekken er full nok. Jeg har " + state.woodCargo + " ved. Kom bort, så leverer jeg.") : "Vedjobben er over. Jeg fant ikke mer som kunne samles inn.");
			plugin.Save();
		}

		internal void StartHunt(string animal, string primaryPrefab, string secondaryPrefab, int coins, int capacity, bool prepaid = false)
		{
			//IL_00ef: 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_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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			if (state.job.phase != JobPhase.Idle || state.woodPaid || state.woodCargo > 0)
			{
				plugin.Say("Jeg må gjøre ferdig den andre jobben først.");
				return;
			}
			if ((Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ObjectDB.instance.GetItemPrefab(primaryPrefab) == (Object)null)
			{
				plugin.Say("Jeg finner ikke riktig jaktutbytte i denne spillversjonen. Ingen betaling trukket.");
				return;
			}
			if (!plugin.Save())
			{
				plugin.Say("Jeg får ikke lagret jaktoppdraget. Ingen betaling trukket.");
				return;
			}
			if (!prepaid && !GameApi.SpendCoins(coins))
			{
				plugin.Say("Du har ikke nok mynter til den jaktturen.");
				Voice("pay_none");
				return;
			}
			state.huntSecondaryPrefab = secondaryPrefab;
			state.huntSecondaryCargo = Mathf.Max(1, capacity / 2);
			state.huntAnimal = animal;
			state.departure = ((Component)this).transform.position;
			Vector3 val = -((Component)Player.m_localPlayer).transform.forward;
			Vector3 point = ((Component)this).transform.position + val * Mathf.Clamp(plugin.TravelDistance.Value, 12f, 70f);
			for (int i = 0; i < 8; i++)
			{
				if (Plugin.Ground(ref point))
				{
					break;
				}
				val = Quaternion.Euler(0f, 45f, 0f) * val;
				point = ((Component)this).transform.position + val * Mathf.Clamp(plugin.TravelDistance.Value, 12f, 70f);
			}
			state.woodTarget = point;
			state.job = Expedition.Start(primaryPrefab, animal, plugin.Duration.Value, capacity, Random.Range(0, 4), state.waiting);
			phaseTimer = 0f;
			plugin.Say("Betaling mottatt. Jeg drar på jakt etter " + animal + ". Jeg foretrekker dyr som ikke jakter tilbake.");
			if ((Object)(object)audio != (Object)null)
			{
				switch (animal)
				{
				case "hjort":
					Voice("hunt_deer");
					break;
				case "villsvin":
					Voice("hunt_boar");
					break;
				case "neck":
					Voice("hunt_neck");
					break;
				default:
					Voice("hunt_start");
					break;
				}
			}
			plugin.Save();
		}

		internal void StartTempoAdventure(int coins, bool prepaid = false)
		{
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			if (state.job.phase != JobPhase.Idle || state.woodPaid || state.woodCargo > 0)
			{
				plugin.Say("Jeg må gjøre ferdig den andre jobben først.");
				return;
			}
			EnsureTempoCar();
			if ((Object)(object)tempoCar == (Object)null)
			{
				plugin.Say("Jeg får ikke startet Tempo Gigante akkurat nå.");
				return;
			}
			if (!prepaid && !GameApi.SpendCoins(coins))
			{
				plugin.Say("Du har ikke nok mynter til eventyret.");
				Voice("pay_none");
				return;
			}
			string[] array = new string[6] { "Wood", "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap" };
			string[] array2 = new string[6] { "blandede ressurser", "kobbermalm", "tinnmalm", "jernskrap", "sølvmalm", "svartmetall" };
			List<int> list = new List<int>();
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)ObjectDB.instance.GetItemPrefab(array[i]) != (Object)null && plugin.ProgressionAllows(array[i]))
				{
					list.Add(i);
				}
			}
			int num = ((list.Count > 0) ? list[Random.Range(0, list.Count)] : 0);
			state.departure = ((Component)tempoCar).transform.position;
			Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.forward : ((Component)this).transform.forward);
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.1f)
			{
				val = Vector3.forward;
			}
			Vector3 point = ((Component)tempoCar).transform.position + ((Vector3)(ref val)).normalized * 38f;
			for (int j = 0; j < 8; j++)
			{
				if (Plugin.Ground(ref point))
				{
					break;
				}
				val = Quaternion.Euler(0f, 45f, 0f) * val;
				point = ((Component)tempoCar).transform.position + ((Vector3)(ref val)).normalized * 38f;
			}
			state.woodTarget = point;
			((Component)this).transform.position = ((Component)tempoCar).transform.position;
			state.job = Expedition.Start(array[num], array2[num], Mathf.Max(150f, plugin.Duration.Value * 4f), Random.Range(12, 31), Random.Range(0, 4), state.waiting);
			state.tempoAdventure = true;
			phaseTimer = 0f;
			MountTempo();
			plugin.Say("Da fyrer jeg opp Tempo Gigante. Jeg kommer tilbake med det jeg finner.");
			Voice("follow");
			plugin.Save();
		}

		private static TreeBase FindTree(Vector3 point, float radius)
		{
			//IL_0004: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			TreeBase result = null;
			float num = radius;
			Collider[] array = Physics.OverlapSphere(point, radius);
			for (int i = 0; i < array.Length; i++)
			{
				TreeBase componentInParent = ((Component)array[i]).GetComponentInParent<TreeBase>();
				if (!((Object)(object)componentInParent == (Object)null))
				{
					float num2 = Vector3.Distance(point, ((Component)componentInParent).transform.position);
					if (num2 < num)
					{
						result = componentInParent;
						num = num2;
					}
				}
			}
			return result;
		}

		internal void StartFight(int coins, float seconds, bool prepaid = false)
		{
			if (state.job.phase != JobPhase.Idle || state.woodPaid || state.woodCargo > 0)
			{
				plugin.Say("Jeg må gjøre ferdig jobben først.");
				return;
			}
			if (combatActive || combatFled)
			{
				plugin.Say(combatFled ? "Jeg gjemmer meg fortsatt. Ti minutter er ti minutter." : "Jeg slåss allerede så godt jeg kan.");
				return;
			}
			if (!prepaid && !GameApi.SpendCoins(coins))
			{
				plugin.Say("Du har ikke nok mynter til livvakttjenesten.");
				Voice("pay_none");
				return;
			}
			combatActive = true;
			combatTimer = Mathf.Max(60f, seconds);
			combatHealth = 55f;
			combatAttackTimer = 0f;
			state.waiting = false;
			plugin.Say("Jaja... jeg blir med og slåss. Men hvis dette blir farlig, så løper jeg først.");
			Voice("follow");
			plugin.Save();
		}

		private void TickCombat(Player player, float dt)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Expected O, but got Unknown
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			combatTimer -= dt;
			combatAttackTimer -= dt;
			if (combatTimer <= 0f)
			{
				combatActive = false;
				plugin.Say("Da var vakta mi over. Jeg har brukt opp motet for i dag.");
				return;
			}
			Character val = null;
			float num = 12f;
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 11f);
			foreach (Collider val2 in array)
			{
				Character val3 = (((Object)(object)val2 == (Object)null) ? null : ((Component)val2).GetComponentInParent<Character>());
				if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)player || val3.IsDead())
				{
					continue;
				}
				string text = ((Object)val3).name.ToLowerInvariant();
				if (text.Contains("grey") || text.Contains("troll") || text.Contains("skeleton") || text.Contains("draugr") || text.Contains("blob") || text.Contains("wolf") || text.Contains("fuling"))
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val3).transform.position);
					if (num2 < num)
					{
						num = num2;
						val = val3;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				if (Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) > 3.2f)
				{
					Move(((Component)player).transform.position - ((Component)player).transform.forward * 2.2f, dt, 4.6f, allowRecovery: true);
				}
			}
			else if (num > 2.2f)
			{
				Move(((Component)val).transform.position, dt, 4.8f, allowRecovery: true);
			}
			else
			{
				if (!(combatAttackTimer <= 0f))
				{
					return;
				}
				combatAttackTimer = 1.25f;
				HitData val4 = new HitData();
				val4.m_damage.m_blunt = 10f;
				val4.m_point = ((Component)val).transform.position + Vector3.up;
				Vector3 val5 = ((Component)val).transform.position - ((Component)this).transform.position;
				val4.m_dir = ((Vector3)(ref val5)).normalized;
				try
				{
					val.Damage(val4);
				}
				catch
				{
				}
				combatHealth -= Random.Range(6f, 13f);
				if (combatHealth <= 15f)
				{
					combatActive = false;
					combatFled = true;
					combatFleeReturnTimer = 600f;
					Vector3 val6 = ((Component)this).transform.position - ((Component)val).transform.position;
					val6.y = 0f;
					if (((Vector3)(ref val6)).sqrMagnitude < 0.1f)
					{
						val6 = -((Component)player).transform.forward;
					}
					fleeTarget = ((Component)this).transform.position + ((Vector3)(ref val6)).normalized * 20f;
					Plugin.Ground(ref fleeTarget);
					plugin.Say("Å nei, nei, nei! Nå holder det! Jeg gjemmer meg og kommer tilbake senere!");
					Voice("enemy");
				}
			}
		}

		private void TickCombatReturn(float dt)
		{
			//IL_0010: 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_0078: 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_003b: 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)
			combatFleeReturnTimer -= dt;
			Move(fleeTarget, dt, 6.2f, allowRecovery: false);
			if (combatFleeReturnTimer > 0f)
			{
				if (Vector3.Distance(((Component)this).transform.position, fleeTarget) < 2f)
				{
					SetVisible(visible: false);
				}
				return;
			}
			combatFled = false;
			combatHealth = 55f;
			SetVisible(visible: true);
			Vector3 point = state.home;
			if (Plugin.Ground(ref point))
			{
				((Component)this).transform.position = point;
			}
			plugin.Say("Jaja... nå har jeg samlet litt mot igjen. Litt.");
			Voice("enemy_safe");
		}

		private bool TickDanger(Player player, float dt)
		{
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_0157: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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)
			enemyScanTimer -= dt;
			if (fleeTimer <= 0f && enemyScanTimer <= 0f)
			{
				enemyScanTimer = 0.6f;
				Transform val = null;
				float num = 10f;
				Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 9f);
				foreach (Collider val2 in array)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					string text = ((Object)((Component)val2).transform.root).name.ToLowerInvariant();
					if (text.Contains("greyling") || text.Contains("greydwarf") || text.Contains("troll") || text.Contains("skeleton"))
					{
						float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
						if (num2 < num)
						{
							num = num2;
							val = ((Component)val2).transform.root;
						}
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					Vector3 val3 = ((Component)this).transform.position - val.position;
					val3.y = 0f;
					if (((Vector3)(ref val3)).sqrMagnitude < 0.1f)
					{
						val3 = -((Component)player).transform.forward;
					}
					fleeTarget = ((Component)this).transform.position + ((Vector3)(ref val3)).normalized * 12f;
					if (!Plugin.Ground(ref fleeTarget))
					{
						fleeTarget = ((Component)player).transform.position;
					}
					fleeTimer = 5f;
					if ((Object)(object)audio != (Object)null)
					{
						Voice("enemy");
					}
					plugin.Say("Å nei! Jeg løper! Du får ta den der!");
				}
			}
			if (fleeTimer > 0f)
			{
				fleeTimer -= dt;
				Move(fleeTarget, dt, 6f, allowRecovery: false);
				return true;
			}
			return false;
		}

		private bool Move(Vector3 destination, float dt)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Distance(((Component)this).transform.position, destination);
			return Move(destination, dt, (num > 10f) ? 5.6f : 3.8f, allowRecovery: true);
		}

		private unsafe bool Move(Vector3 destination, float dt, float speed, bool allowRecovery)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_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_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = destination - ((Component)this).transform.position;
			val.y = 0f;
			if (((Vector3)(ref val)).magnitude < 1.5f)
			{
				stuckTimer = 0f;
				lastMovePosition = ((Component)this).transform.position;
				if ((Object)(object)model != (Object)null)
				{
					model.localPosition = Vector3.zero;
					model.localRotation = Quaternion.identity;
				}
				return true;
			}
			Vector3 val2 = ((Vector3)(ref val)).normalized;
			Vector3 val3 = ((Component)this).transform.position + Vector3.up * 0.85f;
			float num = Mathf.Min(((Vector3)(ref val)).magnitude, dt * speed);
			RaycastHit val4 = default(RaycastHit);
			if (Physics.SphereCast(val3, 0.28f, val2, ref val4, Mathf.Max(0.45f, num + 0.3f), -1, (QueryTriggerInteraction)1))
			{
				Vector3 val5 = Quaternion.Euler(0f, -48f, 0f) * val2;
				Vector3 val6 = Quaternion.Euler(0f, 48f, 0f) * val2;
				bool flag = !Physics.SphereCast(val3, 0.28f, val5, ref val4, 0.85f, -1, (QueryTriggerInteraction)1);
				bool flag2 = !Physics.SphereCast(val3, 0.28f, val6, ref val4, 0.85f, -1, (QueryTriggerInteraction)1);
				if (flag || flag2)
				{
					val2 = ((flag && !flag2) ? val5 : ((flag2 && !flag) ? val6 : ((Vector3.Dot(val5, val) > Vector3.Dot(val6, val)) ? val5 : val6)));
				}
				else
				{
					val2 = Quaternion.Euler(0f, 90f * ((Mathf.Sin(Time.time * 1.7f) >= 0f) ? 1f : (-1f)), 0f) * val2;
					stuckTimer += dt;
				}
			}
			Vector3 point = ((Component)this).transform.position + val2 * num;
			if (Plugin.Ground(ref point))
			{
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(val2), Mathf.Clamp01(dt * 8f));
				((Component)this).transform.position = point;
				float num2 = Time.time * Mathf.Lerp(9f, 13f, Mathf.InverseLerp(2f, 6f, speed));
				float num3 = Mathf.Abs(Mathf.Sin(num2));
				model.localPosition = new Vector3(0f, 0.055f * num3, 0f);
				model.localRotation = Quaternion.Euler(2.2f * Mathf.Sin(num2 * 2f), 0f, 3.2f * Mathf.Sin(num2));
				if ((Object)(object)modelAnimator != (Object)null)
				{
					modelAnimator.Animate(Mathf.Clamp01(speed / 5.6f), (Object)(object)audio != (Object)null && audio.IsSpeaking, Time.time);
				}
			}
			if (Vector3.Distance(((Component)this).transform.position, lastMovePosition) < 0.08f)
			{
				stuckTimer += dt;
			}
			else
			{
				stuckTimer = 0f;
				lastMovePosition = ((Component)this).transform.position;
			}
			if (allowRecovery && stuckTimer > 2.5f && ((Vector3)(ref val)).magnitude > 5f)
			{
				Vector3 point2 = destination - ((Vector3)(ref val)).normalized * 2f;
				if (Plugin.Ground(ref point2))
				{
					((Component)this).transform.position = point2;
					lastMovePosition = point2;
					stuckTimer = 0f;
					Plugin obj = plugin;
					Vector3 val7 = point2;
					obj.LogInfo("Ludvig movement recovery used at " + ((object)(*(Vector3*)(&val7))/*cast due to .constrained prefix*/).ToString());
				}
			}
			return false;
		}

		private void Voice(string group)
		{
			if ((Object)(object)audio != (Object)null)
			{
				audio.Play(group);
			}
			plugin.BroadcastVoice(group);
		}

		internal void PlayVoiceLocal(string group)
		{
			if ((Object)(object)audio != (Object)null)
			{
				audio.Play(group);
			}
		}

		private void SetVisible(bool visible)
		{
			if ((Object)(object)model != (Object)null)
			{
				((Component)model).gameObject.SetActive(visible);
			}
		}

		internal void PlayVoice(string group)
		{
			Voice(group);
		}

		internal void Status()
		{
			string text = ((state.job.phase != JobPhase.Idle) ? (state.job.phase.ToString() + ": " + state.job.displayName + ", " + state.job.cargo + " i sekken") : ((!state.recruited) ? "kan rekrutteres med E" : (state.waiting ? "venter ved hjemmet" : "følger deg")));
			plugin.Say(text + (state.woodPaid ? " — vedjobb pågår" : ""));
		}

		internal void UpdatePin()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if (pin == null)
			{
				return;
			}
			if (!plugin.ShowMapPin.Value)
			{
				pin.Remove();
				return;
			}
			string text = "Ludvig";
			if (state.job.phase == JobPhase.Away)
			{
				text += " (på tur)";
			}
			if (state.job.phase == JobPhase.Delivery)
			{
				text += " (klar til levering)";
			}
			pin.Update((state.job.phase == JobPhase.Away) ? state.woodTarget : ((Component)this).transform.position, text);
		}

		internal void NetworkState(bool recruited, bool waiting, JobPhase phase)
		{
			state.recruited = recruited;
			state.waiting = waiting;
			state.job.phase = phase;
			SetVisible(phase != JobPhase.Away);
		}

		internal void NetworkTick(Vector3 target, float dt)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0097: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			if (Vector3.Distance(position, target) > 20f)
			{
				((Component)this).transform.position = target;
			}
			else
			{
				((Component)this).transform.position = Vector3.Lerp(position, target, Mathf.Clamp01(dt * 12f));
			}
			Vector3 val = ((Component)this).transform.position - position;
			val.y = 0f;
			float num = ((dt > 0.0001f) ? (((Vector3)(ref val)).magnitude / dt) : 0f);
			if (((Vector3)(ref val)).sqrMagnitude > 0.0004f)
			{
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(((Vector3)(ref val)).normalized), Mathf.Clamp01(dt * 10f));
			}
			if ((Object)(object)modelAnimator != (Object)null)
			{
				modelAnimator.Animate(Mathf.Clamp01(num / 5.6f), (Object)(object)audio != (Object)null && audio.IsSpeaking, Time.time);
			}
			UpdateNightLight(dt);
		}

		internal void RemovePin()
		{
			if (pin != null)
			{
				pin.Remove();
			}
		}

		private void OnDestroy()
		{
			RemovePin();
			if ((Object)(object)model != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)model).gameObject);
			}
			if ((Object)(object)tempoCar != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)tempoCar).gameObject);
			}
		}
	}
	public enum JobPhase
	{
		Idle,
		Leaving,
		Away,
		Returning,
		Delivery
	}
	[Serializable]
	public sealed class Expedition
	{
		public JobPhase phase;

		public string ore;

		public string displayName;

		public float remaining;

		public int cargo;

		public int eventId;

		public bool eventReported;

		public bool resumeWaiting;

		public static Expedition Start(string ore, string name, float duration, int baseline, int roll, bool waiting)
		{
			if (roll < 0 || roll > 3)
			{
				throw new ArgumentOutOfRangeException("roll");
			}
			baseline = Math.Max(1, Math.Min(100, baseline));
			int[] array = new int[4] { 0, 3, -3, 1 };
			return new Expedition
			{
				phase = JobPhase.Leaving,
				ore = ore,
				displayName = name,
				remaining = Math.Max(10f, duration) + (float)((roll == 2) ? 15 : 0),
				cargo = Math.Max(1, baseline + array[roll]),
				eventId = roll,
				resumeWaiting = waiting
			};
		}

		public bool AdvanceAway(float dt)
		{
			if (phase != JobPhase.Away)
			{
				return false;
			}
			remaining = Math.Max(0f, remaining - Math.Max(0f, dt));
			if (remaining > 0f)
			{
				return false;
			}
			phase = JobPhase.Returning;
			return true;
		}

		public void AcknowledgeDelivery(int count)
		{
			if (phase != JobPhase.Delivery)
			{
				throw new InvalidOperationException("Not ready to deliver");
			}
			if (count < 0 || count > cargo)
			{
				throw new ArgumentOutOfRangeException("count");
			}
			cargo -= count;
			if (cargo == 0)
			{
				phase = JobPhase.Idle;
			}
		}
	}
	internal static class GameApi
	{
		internal static bool SpendCoins(int amount)
		{
			if (amount == 0)
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			GameObject val = (((Object)(object)ObjectDB.instance == (Object)null) ? null : ObjectDB.instance.GetItemPrefab("Coins"));
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)val == (Object)null)
			{
				return false;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			string name = component.m_itemData.m_shared.m_name;
			if (inventory.CountItems(name, -1, true) < amount)
			{
				return false;
			}
			inventory.RemoveItem(name, amount, -1, true);
			return true;
		}

		internal static int Deliver(string prefabName, int amount)
		{
			Player localPlayer = Player.m_localPlayer;
			GameObject val = (((Object)(object)ObjectDB.instance == (Object)null) ? null : ObjectDB.instance.GetItemPrefab(prefabName));
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)val == (Object)null)
			{
				return 0;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < amount; i++)
			{
				ItemData val2 = component.m_itemData.Clone();
				val2.m_dropPrefab = val;
				val2.m_stack = 1;
				if (!((Humanoid)localPlayer).GetInventory().AddItem(val2))
				{
					break;
				}
				num++;
			}
			return num;
		}

		internal static bool InputBlocked()
		{
			if (Time.timeScale == 0f)
			{
				return true;
			}
			if (!Probe("Chat", "HasFocus", isStatic: false) && !Probe("Console", "IsVisible", isStatic: true) && !Probe("InventoryGui", "IsVisible", isStatic: true) && !Probe("Menu", "IsVisible", isStatic: true) && !Probe("TextInput", "IsVisible", isStatic: true))
			{
				return Probe("StoreGui", "IsVisible", isStatic: true);
			}
			return true;
		}

		private static bool Probe(string typeName, string methodName, bool isStatic)
		{
			try
			{
				Type type = typeof(Player).Assembly.GetType(typeName);
				if (type == null)
				{
					return false;
				}
				MethodInfo method = type.GetMethod(methodName, (BindingFlags)(0x30 | (isStatic ? 8 : 4)), null, Type.EmptyTypes, null);
				if (method == null)
				{
					return true;
				}
				object obj = null;
				if (!isStatic)
				{
					obj = type.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null, null) ?? type.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
					if (obj == null)
					{
						return false;
					}
				}
				return (bool)method.Invoke(obj, null);
			}
			catch
			{
				return true;
			}
		}
	}
	internal sealed class MapPin
	{
		private readonly Plugin plugin;

		private Minimap map;

		private object pin;

		private bool failed;

		internal MapPin(Plugin plugin)
		{
			this.plugin = plugin;
		}

		internal void Update(Vector3 position, string name)
		{
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)map != (Object)(object)Minimap.instance)
			{
				Remove();
				map = Minimap.instance;
				failed = false;
			}
			if (failed)
			{
				return;
			}
			try
			{
				if (pin == null)
				{
					MethodInfo methodInfo = typeof(Minimap).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).First((MethodInfo m) => m.Name == "AddPin" && m.GetParameters().Length >= 5 && m.GetParameters()[0].ParameterType == typeof(Vector3));
					ParameterInfo[] parameters = methodInfo.GetParameters();
					object[] array = new object[parameters.Length];
					array[0] = position;
					array[1] = Enum.Parse(parameters[1].ParameterType, "Icon3");
					array[2] = name;
					array[3] = false;
					array[4] = false;
					for (int num = 5; num < array.Length; num++)
					{
						array[num] = ((parameters[num].ParameterType == typeof(string)) ? "" : (parameters[num].ParameterType.IsValueType ? Activator.CreateInstance(parameters[num].ParameterType) : null));
					}
					pin = methodInfo.Invoke(map, array);
					if (pin == null)
					{
						throw new InvalidOperationException("AddPin returned null");
					}
				}
				pin.GetType().GetField("m_pos").SetValue(pin, position);
				pin.GetType().GetField("m_name").SetValue(pin, name);
			}
			catch (Exception ex)
			{
				failed = true;
				plugin.LogWarning("Ludvig map pin unavailable in this build: " + ex);
			}
		}

		internal void Remove()
		{
			if (pin != null && (Object)(object)map != (Object)null)
			{
				try
				{
					typeof(Minimap).GetMethod("RemovePin", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { pin.GetType() }, null)?.Invoke(map, new object[1] { pin });
				}
				catch (Exception ex)
				{
					plugin.LogWarning("Ludvig map pin cleanup: " + ex.Message);
				}
			}
			pin = null;
			map = null;
		}
	}
	internal static class Geometry
	{
		private static string ReadString(BinaryReader r)
		{
			int num = r.ReadInt32();
			if (num < 0 || num > 1048576)
			{
				throw new InvalidDataException("Invalid geometry string length: " + num);
			}
			byte[] array = r.ReadBytes(num);
			if (array.Length != num)
			{
				throw new EndOfStreamException();
			}
			return Encoding.UTF8.GetString(array);
		}

		private static float[] ReadFloats(BinaryReader r)
		{
			int num = r.ReadInt32();
			if (num < 0 || num > 50000000)
			{
				throw new InvalidDataException("Invalid float array length: " + num);
			}
			float[] array = new float[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = r.ReadSingle();
			}
			return array;
		}

		private static int[] ReadInts(BinaryReader r)
		{
			int num = r.ReadInt32();
			if (num < 0 || num > 50000000)
			{
				throw new InvalidDataException("Invalid int array length: " + num);
			}
			int[] array = new int[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = r.ReadInt32();
			}
			return array;
		}

		internal static Dictionary<string, Mesh> Load(List<Mesh> owned, Plugin owner)
		{
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Expected O, but got Unknown
			using Stream stream = typeof(Geometry).Assembly.GetManifestResourceStream("LudvigValheim.mesh_shapes.bin");
			if (stream == null)
			{
				throw new InvalidDataException("Missing embedded resource: LudvigValheim.mesh_shapes.bin");
			}
			owner.LogInfo("mesh_shapes.bin bytes: " + stream.Length);
			using BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8);
			string text = Encoding.ASCII.GetString(binaryReader.ReadBytes(4));
			if (text != "LVG1")
			{
				throw new InvalidDataException("Bad geometry header: " + text);
			}
			int num = binaryReader.ReadInt32();
			if (num <= 0 || num > 1000)
			{
				throw new InvalidDataException("Invalid shape count: " + num);
			}
			Dictionary<string, Mesh> dictionary = new Dictionary<string, Mesh>();
			for (int i = 0; i < num; i++)
			{
				string text2 = ReadString(binaryReader);
				float[] array = ReadFloats(binaryReader);
				float[] array2 = ReadFloats(binaryReader);
				float[] array3 = ReadFloats(binaryReader);
				float[] array4 = ReadFloats(binaryReader);
				int[] array5 = ReadInts(binaryReader);
				if (string.IsNullOrEmpty(text2) || array.Length == 0 || array.Length % 3 != 0)
				{
					throw new InvalidDataException("Invalid geometry shape header: " + text2);
				}
				int num2 = array.Length / 3;
				if (array2.Length != num2 * 3 || array3.Length != num2 * 4 || array4.Length != num2 * 2 || array5.Length == 0 || array5.Length % 3 != 0)
				{
					throw new InvalidDataException("Invalid vertex attributes: " + text2);
				}
				Vector3[] array6 = (Vector3[])(object)new Vector3[num2];
				Vector3[] array7 = (Vector3[])(object)new Vector3[num2];
				Vector2[] array8 = (Vector2[])(object)new Vector2[num2];
				Vector4[] array9 = (Vector4[])(object)new Vector4[num2];
				for (int j = 0; j < num2; j++)
				{
					array6[j] = new Vector3(array[j * 3], array[j * 3 + 1], array[j * 3 + 2]);
					array7[j] = new Vector3(array2[j * 3], array2[j * 3 + 1], array2[j * 3 + 2]);
					array8[j] = new Vector2(array4[j * 2], array4[j * 2 + 1]);
					array9[j] = new Vector4(array3[j * 4], array3[j * 4 + 1], array3[j * 4 + 2], array3[j * 4 + 3]);
				}
				int[] array10 = array5;
				foreach (int num3 in array10)
				{
					if (num3 < 0 || num3 >= num2)
					{
						throw new InvalidDataException("Invalid triangle index: " + text2);
					}
				}
				Mesh val = new Mesh();
				owned.Add(val);
				((Object)val).name = "Ludvig geometry " + text2;
				val.indexFormat = (IndexFormat)1;
				val.vertices = array6;
				val.normals = array7;
				val.uv = array8;
				val.tangents = array9;
				val.triangles = array5;
				val.RecalculateBounds();
				dictionary.Add(text2, val);
			}
			owner.LogInfo("Ludvig binary geometry decoded: " + dictionary.Count + " shapes");
			return dictionary;
		}
	}
	internal sealed class LudvigAudio : MonoBehaviour
	{
		private Plugin plugin;

		private AudioSource source;

		private readonly Dictionary<string, List<AudioClip>> groups = new Dictionary<string, List<AudioClip>>(StringComparer.OrdinalIgnoreCase);

		private readonly List<AudioClip> owned = new List<AudioClip>();

		private float enemyCooldown;

		internal bool IsSpeaking
		{
			get
			{
				if ((Object)(object)source != (Object)null)
				{
					return source.isPlaying;
				}
				return false;
			}
		}

		internal void Init(Plugin owner)
		{
			plugin = owner;
			source = ((Component)this).gameObject.AddComponent<AudioSource>();
			source.spatialBlend = 1f;
			source.minDistance = 2f;
			source.maxDistance = 24f;
			source.rolloffMode = (AudioRolloffMode)1;
			source.playOnAwake = false;
			source.volume = 1f;
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Sounds");
			if (!Directory.Exists(text))
			{
				plugin.LogWarning("Sounds folder missing: " + text);
				return;
			}
			string[] files = Directory.GetFiles(text, "ludvig_*.wav");
			foreach (string text2 in files)
			{
				try
				{
					AudioClip item = LoadWav(text2);
					owned.Add(item);
					string text3 = Path.GetFileNameWithoutExtension(text2).ToLowerInvariant();
					int length = "ludvig_".Length;
					int num = text3.LastIndexOf('_');
					string key = ((num > length) ? text3.Substring(length, num - length) : text3.Substring(length));
					if (!groups.TryGetValue(key, out var value))
					{
						value = (groups[key] = new List<AudioClip>());
					}
					value.Add(item);
				}
				catch (Exception ex)
				{
					plugin.LogWarning("Could not load sound " + text2 + ": " + ex.Message);
				}
			}
			plugin.LogInfo("Ludvig audio loaded: " + owned.Count + " clips from " + text);
		}

		internal void Play(string group)
		{
			if (!((Object)(object)source == (Object)null) && !source.isPlaying && groups.TryGetValue(group, out var value) && value.Count != 0)
			{
				source.clip = value[Random.Range(0, value.Count)];
				source.Play();
			}
		}

		internal void TickEnemy(float dt)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			enemyCooldown -= dt;
			if (enemyCooldown > 0f || (Object)(object)source == (Object)null || source.isPlaying)
			{
				return;
			}
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 9f);
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = ((Object)((Component)val).transform.root).name.ToLowerInvariant();
				if (text.Contains("greyling") || text.Contains("greydwarf") || text.Contains("troll") || text.Contains("skeleton"))
				{
					enemyCooldown = 18f;
					if (text.Contains("greydwarf"))
					{
						Play("enemy_greydwarf");
					}
					else if (text.Contains("greyling"))
					{
						Play("enemy_greyling");
					}
					else if (text.Contains("skeleton"))
					{
						Play("enemy_skeleton");
					}
					else if (text.Contains("troll"))
					{
						Play("enemy_troll");
					}
					if (!IsSpeaking)
					{
						Play("enemy");
					}
					break;
				}
			}
		}

		private static AudioClip LoadWav(string path)
		{
			byte[] array = File.ReadAllBytes(path);
			if (array.Length < 44 || array[0] != 82 || array[1] != 73 || array[2] != 70 || array[3] != 70)
			{
				throw new InvalidDataException("Not RIFF WAV");
			}
			int num = BitConverter.ToInt16(array, 22);
			int num2 = BitConverter.ToInt32(array, 24);
			if (BitConverter.ToInt16(array, 34) != 16 || num < 1)
			{
				throw new InvalidDataException("Expected PCM16 WAV");
			}
			int i = 12;
			int num3 = -1;
			int num4 = 0;
			int num5;
			for (; i + 8 <= array.Length; i += 8 + num5 + (num5 & 1))
			{
				string text = Encoding.ASCII.GetString(array, i, 4);
				num5 = BitConverter.ToInt32(array, i + 4);
				if (text == "data")
				{
					num3 = i + 8;
					num4 = Math.Min(num5, array.Length - num3);
					break;
				}
			}
			if (num3 < 0 || num4 < 2)
			{
				throw new InvalidDataException("WAV data chunk missing");
			}
			int num6 = num4 / 2 / num;
			float[] array2 = new float[num6 * num];
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = (float)BitConverter.ToInt16(array, num3 + j * 2) / 32768f;
			}
			AudioClip obj = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num6, num, num2, false);
			obj.SetData(array2, 0);
			return obj;
		}

		private void OnDestroy()
		{
			foreach (AudioClip item in owned)
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.Destroy((Object)(object)item);
				}
			}
		}
	}
	internal sealed class Model : MonoBehaviour
	{
		private sealed class Part
		{
			public string name;

			public string shape;

			public string color;

			public Vector3 position;

			public Vector3 scale;

			public Vector3 rotation;
		}

		private string stage = "start";

		private readonly List<Material> materials = new List<Material>();

		private readonly List<Mesh> meshes = new List<Mesh>();

		internal Transform armL;

		internal Transform armR;

		internal Transform legL;

		internal Transform legR;

		internal Transform footL;

		internal Transform footR;

		internal Transform body;

		internal Transform eyes;

		internal Transform mouth;

		internal Vector3 armLBase;

		internal Vector3 armRBase;

		internal Vector3 legLBase;

		internal Vector3 legRBase;

		internal Vector3 footLBase;

		internal Vector3 footRBase;

		internal Vector3 bodyBase;

		internal Vector3 eyesBase;

		internal Vector3 mouthBase;

		private float smoothStride;

		private float gaitPhase;

		internal static Transform Build(Transform parent, Plugin owner)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("LudvigModel");
			val.transform.SetParent(parent, false);
			Model model = val.AddComponent<Model>();
			try
			{
				model.Create(owner);
				return val.transform;
			}
			catch (Exception innerException)
			{
				val.SetActive(false);
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Ludvig model stage: " + model.stage, innerException);
			}
		}

		private static string ReadString(BinaryReader r)
		{
			int num = r.ReadInt32();
			if (num < 0 || num > 1048576)
			{
				throw new InvalidDataException("Invalid string length in model data: " + num);
			}
			byte[] array = r.ReadBytes(num);
			if (array.Length != num)
			{
				throw new EndOfStreamException();
			}
			return Encoding.UTF8.GetString(array);
		}

		private static Vector3 ReadVector3(BinaryReader r)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}

		private static List<Part> LoadParts(Plugin owner)
		{
			//IL_00ea: 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_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_0102: 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)
			using Stream stream = typeof(Model).Assembly.GetManifestResourceStream("LudvigValheim.model_parts.bin");
			if (stream == null)
			{
				throw new InvalidDataException("Missing embedded resource: LudvigValheim.model_parts.bin");
			}
			owner.LogInfo("model_parts.bin bytes: " + stream.Length);
			using BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8);
			string text = Encoding.ASCII.GetString(binaryReader.ReadBytes(4));
			if (text != "LVM1")
			{
				throw new InvalidDataException("Bad model data header: " + text);
			}
			int num = binaryReader.ReadInt32();
			if (num <= 0 || num > 100000)
			{
				throw new InvalidDataException("Invalid model part count: " + num);
			}
			List<Part> list = new List<Part>(num);
			for (int i = 0; i < num; i++)
			{
				list.Add(new Part
				{
					name = ReadString(binaryReader),
					shape = ReadString(binaryReader),
					color = ReadString(binaryReader),
					position = ReadVector3(binaryReader),
					scale = ReadVector3(binaryReader),
					rotation = ReadVector3(binaryReader)
				});
			}
			owner.LogInfo("Ludvig model parts decoded: " + list.Count);
			return list;
		}

		private void Create(Plugin owner)
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Expected O, but got Unknown
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0601: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_062b: Expected O, but got Unknown
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0661: Expected O, but got Unknown
			//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_071a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0728: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d1: Unknown result type (might be due to invalid IL or missing references)
			stage = "reading binary model data";
			List<Part> list = LoadParts(owner);
			stage = "finding a loaded material";
			Material val = FindTemplate();
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("No loaded opaque character material yet; Ludvig will retry after the player model is ready.");
			}
			owner.LogInfo("Ludvig material template: " + ((Object)val).name + " / shader: " + ((Object)val.shader).name);
			stage = "loading binary baked geometry";
			Dictionary<string, Mesh> dictionary = Geometry.Load(meshes, owner);
			owner.LogInfo("Ludvig geometry loaded: " + dictionary.Count + " shapes; " + list.Count + " parts");
			Dictionary<string, List<CombineInstance>> dictionary2 = new Dictionary<string, List<CombineInstance>>();
			Dictionary<string, Vector3> dictionary3 = new Dictionary<string, Vector3>
			{
				{
					"armL",
					new Vector3(-0.3f, 1.05f, 0f)
				},
				{
					"armR",
					new Vector3(0.3f, 1.05f, 0f)
				},
				{
					"legL",
					new Vector3(-0.17f, 0.52f, 0f)
				},
				{
					"legR",
					new Vector3(0.17f, 0.52f, 0f)
				},
				{
					"footL",
					new Vector3(-0.17f, 0.12f, 0.16f)
				},
				{
					"footR",
					new Vector3(0.17f, 0.12f, 0.16f)
				},
				{
					"eyes",
					new Vector3(0f, 1.52f, 0.305f)
				},
				{
					"mouth",
					new Vector3(0f, 1.245f, 0.408f)
				},
				{
					"body",
					Vector3.zero
				}
			};
			Func<string, string> func = delegate(string n)
			{
				string text5 = n.ToLowerInvariant();
				if (text5.Contains("arm_l") || text5.Contains("arm_fur_l") || text5.Contains("hand_l") || text5.Contains("finger_l") || text5.Contains("thumb_l"))
				{
					return "armL";
				}
				if (text5.Contains("arm_r") || text5.Contains("arm_fur_r") || text5.Contains("hand_r") || text5.Contains("finger_r") || text5.Contains("thumb_r"))
				{
					return "armR";
				}
				if (text5.Contains("boot") && text5.Contains("_l"))
				{
					return "footL";
				}
				if (text5.Contains("boot") && text5.Contains("_r"))
				{
					return "footR";
				}
				if (text5.Contains("leg_l") || text5.Contains("leg_fur_l"))
				{
					return "legL";
				}
				if (text5.Contains("leg_r") || text5.Contains("leg_fur_r"))
				{
					return "legR";
				}
				if (text5.Contains("eye_") || text5.Contains("iris_") || text5.Contains("pupil_"))
				{
					return "eyes";
				}
				return text5.Contains("mouth") ? "mouth" : "body";
			};
			foreach (Part item2 in list)
			{
				if (item2 == null || string.IsNullOrEmpty(item2.name) || string.IsNullOrEmpty(item2.shape) || string.IsNullOrEmpty(item2.color))
				{
					throw new InvalidDataException("Invalid model part definition");
				}
				stage = "building part " + item2.name + " (" + item2.shape + ")";
				if (!dictionary.TryGetValue(item2.shape, out var value) || (Object)(object)value == (Object)null)
				{
					throw new InvalidDataException("No baked geometry for " + item2.shape);
				}
				string text = func(item2.name);
				string key = text + "|" + item2.color;
				if (!dictionary2.TryGetValue(key, out var value2))
				{
					value2 = new List<CombineInstance>();
					dictionary2.Add(key, value2);
				}
				Vector3 val2 = item2.position - dictionary3[text];
				List<CombineInstance> list2 = value2;
				CombineInstance item = default(CombineInstance);
				((CombineInstance)(ref item)).mesh = value;
				((CombineInstance)(ref item)).transform = Matrix4x4.TRS(val2, Quaternion.Euler(item2.rotation), item2.scale);
				list2.Add(item);
			}
			Dictionary<string, Transform> dictionary4 = new Dictionary<string, Transform>();
			foreach (KeyValuePair<string, Vector3> item3 in dictionary3)
			{
				GameObject val3 = new GameObject("Ludvig_" + item3.Key);
				val3.transform.SetParent(((Component)this).transform, false);
				val3.transform.localPosition = item3.Value;
				dictionary4[item3.Key] = val3.transform;
			}
			armL = dictionary4["armL"];
			armR = dictionary4["armR"];
			legL = dictionary4["legL"];
			legR = dictionary4["legR"];
			footL = dictionary4["footL"];
			footR = dictionary4["footR"];
			body = dictionary4["body"];
			eyes = dictionary4["eyes"];
			mouth = dictionary4["mouth"];
			armLBase = armL.localPosition;
			armRBase = armR.localPosition;
			legLBase = legL.localPosition;
			legRBase = legR.localPosition;
			footLBase = footL.localPosition;
			footRBase = footR.localPosition;
			bodyBase = body.localPosition;
			eyesBase = eyes.localPosition;
			mouthBase = mouth.localPosition;
			Color val6 = default(Color);
			foreach (KeyValuePair<string, List<CombineInstance>> item4 in dictionary2)
			{
				string[] array = item4.Key.Split('|');
				string key2 = array[0];
				string text2 = array[1];
				stage = "combining mesh for " + item4.Key;
				Mesh val4 = new Mesh();
				meshes.Add(val4);
				((Object)val4).name = "Ludvig_" + item4.Key;
				val4.indexFormat = (IndexFormat)1;
				val4.CombineMeshes(item4.Value.ToArray(), true, true);
				val4.RecalculateBounds();
				if (val4.vertexCount == 0)
				{
					throw new InvalidOperationException("Combined mesh is empty");
				}
				Color32[] array2 = (Color32[])(object)new Color32[val4.vertexCount];
				for (int num = 0; num < array2.Length; num++)
				{
					array2[num] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
				}
				val4.colors32 = array2;
				GameObject val5 = new GameObject(((Object)val4).name);
				val5.transform.SetParent(dictionary4[key2], false);
				val5.AddComponent<MeshFilter>().sharedMesh = val4;
				ColorUtility.TryParseHtmlString(text2, ref val6);
				Material val7 = new Material(val);
				materials.Add(val7);
				((Object)val7).name = "Ludvig " + text2;
				string[] array3 = new string[3] { "_Color", "_BaseColor", "_TintColor" };
				foreach (string text3 in array3)
				{
					if (val7.HasProperty(text3))
					{
						val7.SetColor(text3, val6);
					}
				}
				array3 = new string[3] { "_MainTex", "_BaseMap", "_BaseColorMap" };
				foreach (string text4 in array3)
				{
					if (val7.HasProperty(text4))
					{
						val7.SetTexture(text4, (Texture)(object)Texture2D.whiteTexture);
						val7.SetTextureScale(text4, Vector2.one);
						val7.SetTextureOffset(text4, Vector2.zero);
					}
				}
				if (val7.HasProperty("_Metallic"))
				{
					val7.SetFloat("_Metallic", 0f);
				}
				if (val7.HasProperty("_Glossiness"))
				{
					val7.SetFloat("_Glossiness", 0.12f);
				}
				if (val7.HasProperty("_Smoothness"))
				{
					val7.SetFloat("_Smoothness", 0.12f);
				}
				if (val7.HasProperty("_Cutoff"))
				{
					val7.SetFloat("_Cutoff", 0f);
				}
				if (val7.HasProperty("_EmissionColor"))
				{
					val7.SetColor("_EmissionColor", Color.black);
				}
				val7.DisableKeyword("_NORMALMAP");
				val7.DisableKeyword("_EMISSION");
				((Renderer)val5.AddComponent<MeshRenderer>()).sharedMaterial = val7;
			}
		}

		internal void Animate(float walk, bool speaking, float now, bool seated = false)
		{
			//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)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: 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_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00f4: 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_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: 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_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: 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_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			if (seated)
			{
				smoothStride = 0f;
				if ((Object)(object)armL != (Object)null)
				{
					armL.localRotation = Quaternion.Euler(-64f, -8f, 10f);
				}
				if ((Object)(object)armR != (Object)null)
				{
					armR.localRotation = Quaternion.Euler(-64f, 8f, -10f);
				}
				if ((Object)(object)legL != (Object)null)
				{
					legL.localRotation = Quaternion.Euler(-68f, 0f, -6f);
				}
				if ((Object)(object)legR != (Object)null)
				{
					legR.localRotation = Quaternion.Euler(-68f, 0f, 6f);
				}
				if ((Object)(object)footL != (Object)null)
				{
					footL.localPosition = footLBase + new Vector3(0f, 0.24f, 0.26f);
					footL.localRotation = Quaternion.Euler(-12f, 0f, 0f);
				}
				if ((Object)(object)footR != (Object)null)
				{
					footR.localPosition = footR