Decompiled source of Norse Personality Construction System v0.1.0

Plugins/VentureValheim.NPCS.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("VentureValheim.NPCS")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VentureValheim.NPCS")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2A4C40B0-FB71-4081-853D-46B3FB39AE4C")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace VentureValheim.NPCS
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.orianaventure.mod.NorsePersonalityConstructionSystem", "NorsePersonalityConstructionSystem", "0.1.0")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class NPCSPlugin : BaseUnityPlugin
	{
		private const string ModName = "NorsePersonalityConstructionSystem";

		private const string ModVersion = "0.1.0";

		private const string Author = "com.orianaventure.mod";

		private const string ModGUID = "com.orianaventure.mod.NorsePersonalityConstructionSystem";

		private readonly Harmony HarmonyInstance = new Harmony("com.orianaventure.mod.NorsePersonalityConstructionSystem");

		public static readonly ManualLogSource NPCSLogger = Logger.CreateLogSource("NorsePersonalityConstructionSystem");

		public static GameObject Root;

		public static AssetBundle Assets;

		public const string MOD_PREFIX = "vvnpcs_";

		public void Awake()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			NPCSLogger.LogInfo((object)"You're finally awake!");
			Root = new GameObject("NPCSRoot");
			Root.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)Root);
			PrefabManager.OnPrefabsRegistered += NPCFactory.AddNPCS;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			HarmonyInstance.PatchAll(executingAssembly);
		}
	}
	public interface INPC
	{
		NPCData Data { get; }
	}
	public class NPCAI : MonsterAI
	{
		public override void Awake()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			((BaseAI)this).m_viewRange = 15f;
			((BaseAI)this).m_viewAngle = 90f;
			((BaseAI)this).m_hearRange = 15f;
			((BaseAI)this).m_mistVision = false;
			((BaseAI)this).m_pathAgentType = (AgentType)1;
			((BaseAI)this).m_moveMinAngle = 90f;
			((BaseAI)this).m_smoothMovement = true;
			((BaseAI)this).m_serpentMovement = false;
			((BaseAI)this).m_jumpInterval = 0f;
			((BaseAI)this).m_randomCircleInterval = 3f;
			((BaseAI)this).m_randomMoveInterval = 15f;
			((BaseAI)this).m_randomMoveRange = 5f;
			((BaseAI)this).m_randomFly = false;
			((BaseAI)this).m_avoidFire = false;
			((BaseAI)this).m_afraidOfFire = false;
			((BaseAI)this).m_avoidWater = true;
			((BaseAI)this).m_avoidLava = true;
			((BaseAI)this).m_skipLavaTargets = true;
			((BaseAI)this).m_avoidLavaFlee = true;
			((BaseAI)this).m_aggravatable = true;
			((BaseAI)this).m_passiveAggresive = false;
			((BaseAI)this).m_spawnMessage = "";
			((BaseAI)this).m_deathMessage = "";
			((BaseAI)this).m_alertedMessage = "";
			((BaseAI)this).m_fleeRange = 25f;
			((BaseAI)this).m_fleeAngle = 45f;
			((BaseAI)this).m_fleeInterval = 10f;
			base.m_alertRange = 15f;
			base.m_fleeIfHurtWhenTargetCantBeReached = true;
			base.m_fleeUnreachableSinceAttacking = 30f;
			base.m_fleeUnreachableSinceHurt = 20f;
			base.m_fleeIfNotAlerted = false;
			base.m_fleeIfLowHealth = 0f;
			base.m_fleeTimeSinceHurt = 10f;
			base.m_fleeInLava = true;
			base.m_circulateWhileCharging = true;
			base.m_enableHuntPlayer = false;
			base.m_attackPlayerObjects = false;
			base.m_privateAreaTriggerTreshold = 50;
			base.m_interceptTimeMax = 2f;
			base.m_interceptTimeMin = 0f;
			base.m_maxChaseDistance = 15f;
			base.m_minAttackInterval = 0f;
			base.m_circleTargetInterval = 5f;
			base.m_circleTargetDuration = 2f;
			base.m_circleTargetDistance = 2f;
			((MonsterAI)this).Awake();
		}

		public override void SetAlerted(bool alert)
		{
			((MonsterAI)this).SetAlerted(alert);
			if (!alert)
			{
				((BaseAI)this).SetAggravated(false, (AggravatedReason)0);
			}
		}

		public static void SetupExisting(ref NPCAI monsterAI)
		{
			((BaseAI)monsterAI).m_viewRange = 15f;
			((BaseAI)monsterAI).m_hearRange = 15f;
			((BaseAI)monsterAI).m_aggravatable = true;
			((MonsterAI)monsterAI).m_enableHuntPlayer = false;
			((MonsterAI)monsterAI).m_attackPlayerObjects = false;
			((MonsterAI)monsterAI).m_privateAreaTriggerTreshold = 50;
		}
	}
	public class NPCAnimalAI : AnimalAI
	{
		public override void Awake()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			((BaseAI)this).m_viewRange = 15f;
			((BaseAI)this).m_viewAngle = 90f;
			((BaseAI)this).m_hearRange = 15f;
			((BaseAI)this).m_mistVision = false;
			((BaseAI)this).m_pathAgentType = (AgentType)1;
			((BaseAI)this).m_moveMinAngle = 90f;
			((BaseAI)this).m_smoothMovement = true;
			((BaseAI)this).m_serpentMovement = false;
			((BaseAI)this).m_jumpInterval = 0f;
			((BaseAI)this).m_randomCircleInterval = 3f;
			((BaseAI)this).m_randomMoveInterval = 15f;
			((BaseAI)this).m_randomMoveRange = 5f;
			((BaseAI)this).m_randomFly = false;
			((BaseAI)this).m_avoidFire = false;
			((BaseAI)this).m_afraidOfFire = false;
			((BaseAI)this).m_avoidWater = true;
			((BaseAI)this).m_avoidLava = true;
			((BaseAI)this).m_skipLavaTargets = true;
			((BaseAI)this).m_avoidLavaFlee = true;
			((BaseAI)this).m_aggravatable = true;
			((BaseAI)this).m_passiveAggresive = false;
			((BaseAI)this).m_spawnMessage = "";
			((BaseAI)this).m_deathMessage = "";
			((BaseAI)this).m_alertedMessage = "";
			((BaseAI)this).m_fleeRange = 25f;
			((BaseAI)this).m_fleeAngle = 45f;
			((BaseAI)this).m_fleeInterval = 10f;
			((AnimalAI)this).Awake();
		}

		public override void SetAlerted(bool alert)
		{
			((AnimalAI)this).SetAlerted(alert);
			if (!alert)
			{
				((BaseAI)this).SetAggravated(false, (AggravatedReason)0);
			}
		}

		public static void SetupExisting(ref NPCAnimalAI animalAI)
		{
			((BaseAI)animalAI).m_viewRange = 15f;
			((BaseAI)animalAI).m_hearRange = 15f;
			((BaseAI)animalAI).m_aggravatable = true;
		}
	}
	public class NPCCharacter : Character, Interactable, Hoverable, INPC
	{
		[CompilerGenerated]
		private sealed class <SetUp>d__6 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public NPCCharacter <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SetUp>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				NPCCharacter nPCCharacter = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					nPCCharacter.Data.Setup();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public NPCData Data { get; protected set; }

		public override void Awake()
		{
			((Character)this).Awake();
			Data = new NPCData((Character)(object)this);
			IEnumerator enumerator = SetUp();
			((MonoBehaviour)this).StartCoroutine(enumerator);
		}

		public override void OnDestroy()
		{
			((Character)this).OnDestroy();
		}

		[IteratorStateMachine(typeof(<SetUp>d__6))]
		public IEnumerator SetUp()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetUp>d__6(0)
			{
				<>4__this = this
			};
		}

		public override void CustomFixedUpdate(float fixedDeltaTime)
		{
			if (base.m_nview.IsValid())
			{
				((Character)this).CustomFixedUpdate(fixedDeltaTime);
				if (base.m_nview.GetZDO() != null && base.m_nview.IsOwner())
				{
					Data.UpdateAttach();
				}
			}
		}

		public override void OnDeath()
		{
			NPCUtils.OnDeath((Character)(object)this);
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			return NPCUtils.TryInteract((Character)(object)this);
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return NPCUtils.TryUseItem((Character)(object)this, item);
		}

		public override string GetHoverText()
		{
			return NPCUtils.GetHoverText((Character)(object)this, base.m_baseAI);
		}

		public override string GetHoverName()
		{
			return base.m_name;
		}

		public override bool IsAttached()
		{
			if (!Data.IsAttached())
			{
				return ((Character)this).IsAttached();
			}
			return true;
		}

		public void Attach(bool attach, Chair chair = null)
		{
			Data.Attach(attach, "", chair);
		}

		public override void AttachStop()
		{
			Data.SetAttachStop();
		}
	}
	public class NPCData
	{
		public enum NPCType
		{
			None,
			Information,
			Reward,
			Sellsword,
			SlayTarget,
			Trader,
			Quest
		}

		public enum NPCKeyType
		{
			Player,
			Global
		}

		private Character _character;

		private bool _newSpawn;

		private NPCQuest[] _quests;

		private int _questIndex = -1;

		private bool _questsInitialized;

		private NPCQuest _currentQuest;

		public bool HasAttach;

		public Vector3 AttachPosition = Vector3.zero;

		public Quaternion AttachRotation = Quaternion.identity;

		public string AttachAnimation = "";

		public GameObject AttachRoot;

		public Collider[] AttachColliders;

		public const string NPCGROUP = "VV_NPC";

		public static readonly Color32 HairColorMin = new Color32(byte.MaxValue, (byte)237, (byte)180, byte.MaxValue);

		public static readonly Color32 HairColorMax = new Color32(byte.MaxValue, (byte)124, (byte)71, byte.MaxValue);

		public static readonly Color32 SkinColorMin = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);

		public static readonly Color32 SkinColorMax = new Color32((byte)76, (byte)76, (byte)76, byte.MaxValue);

		public NPCData(Character character)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			_character = character;
		}

		public void Setup()
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			ZDO zdo = _character.m_nview.GetZDO();
			NPCZDOUtils.UpgradeVersion(ref zdo);
			_character.m_name = NPCZDOUtils.GetTamedName(zdo);
			_character.m_defeatSetGlobalKey = NPCZDOUtils.GetNPCDefeatKey(zdo);
			_character.m_nview.GetZDO().Set(ZDOVars.s_tamed, false);
			_character.m_tamed = false;
			if (!UpdateTrader())
			{
				UpdateTalker();
			}
			if (_character is NPCHumanoid)
			{
				Character character = _character;
				Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
				if (!_newSpawn && (Object)(object)val.m_visEquipment != (Object)null && (Object)(object)val.m_visEquipment.m_nview != (Object)null)
				{
					SetHelmet(zdo.GetInt(ZDOVars.s_helmetItem, 0));
					SetChest(zdo.GetInt(ZDOVars.s_chestItem, 0));
					SetLegs(zdo.GetInt(ZDOVars.s_legItem, 0));
					SetShoulder(zdo.GetInt(ZDOVars.s_shoulderItem, 0), zdo.GetInt(ZDOVars.s_shoulderItemVariant, 0));
					SetUtility(zdo.GetInt(ZDOVars.s_utilityItem, 0));
					SetLeftHand(zdo.GetInt(ZDOVars.s_leftItem, 0), zdo.GetInt(ZDOVars.s_leftItemVariant, 0));
					SetRightHand(zdo.GetInt(ZDOVars.s_rightItem, 0));
				}
			}
			Quaternion rotation = NPCZDOUtils.GetRotation(zdo);
			if (rotation != Quaternion.identity)
			{
				((Component)_character).transform.rotation = rotation;
			}
			if (NPCZDOUtils.GetAttached(zdo))
			{
				string animation = NPCZDOUtils.GetAnimation(zdo);
				AttachStart(animation);
			}
		}

		protected bool UpdateTrader()
		{
			if (NPCZDOUtils.GetType(_character.m_nview.GetZDO()) == 5)
			{
				NPCTrader nPCTrader = default(NPCTrader);
				if (!((Component)_character).TryGetComponent<NPCTrader>(ref nPCTrader))
				{
					nPCTrader = ((Component)_character).gameObject.AddComponent<NPCTrader>();
				}
				nPCTrader.Setup();
				return true;
			}
			return false;
		}

		protected bool UpdateTalker()
		{
			NpcTalk component = ((Component)_character).gameObject.GetComponent<NpcTalk>();
			if ((Object)(object)component != (Object)null)
			{
				ZDO zDO = _character.m_nview.GetZDO();
				component.m_randomTalk = NPCZDOUtils.GetNPCTexts("VV_TalkTexts", zDO);
				component.m_randomGreets = NPCZDOUtils.GetNPCTexts("VV_GreetTexts", zDO);
				component.m_randomGoodbye = NPCZDOUtils.GetNPCTexts("VV_ByeTexts", zDO);
				component.m_aggravated = NPCZDOUtils.GetNPCTexts("VV_AggroTexts", zDO);
				component.m_name = _character.m_name;
				return true;
			}
			return false;
		}

		protected void RefreshQuestList(bool forceReset = false)
		{
			if (_quests == null || forceReset)
			{
				ZDO zDO = _character.m_nview.GetZDO();
				int nPCQuestCount = NPCZDOUtils.GetNPCQuestCount(zDO);
				if (nPCQuestCount > 0)
				{
					_quests = new NPCQuest[nPCQuestCount];
					for (int i = 0; i < nPCQuestCount; i++)
					{
						NPCZDOUtils.GetNPCQuest(zDO, i, out NPCQuest quest);
						_quests[i] = quest;
					}
				}
			}
			_questsInitialized = true;
			_questIndex = 0;
		}

		protected void UpdateQuest(bool forceReset = false)
		{
			if (!_questsInitialized)
			{
				RefreshQuestList();
			}
			if (forceReset || _questIndex < 0)
			{
				_questIndex = 0;
			}
			if (_quests == null)
			{
				return;
			}
			for (int i = _questIndex; i < _quests.Length; i++)
			{
				if (_quests[i] != null && _quests[i].RewardLimit.Value != 0 && NPCUtils.HasCorrectNotReqiuredKeys(_quests[i].NotRequiredKeysSet))
				{
					_questIndex = i;
					break;
				}
			}
			if (_questIndex >= 0 && _questIndex < _quests.Length)
			{
				_currentQuest = _quests[_questIndex];
			}
			else
			{
				_currentQuest = null;
			}
		}

		public NPCQuest GetCurrentQuest(bool update = true)
		{
			if (!_questsInitialized)
			{
				UpdateQuest(forceReset: true);
			}
			else if (update)
			{
				UpdateQuest();
			}
			return _currentQuest;
		}

		public void UpdateAttach()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			if (!HasAttach)
			{
				return;
			}
			((Component)_character).transform.position = AttachPosition;
			((Component)_character).transform.rotation = AttachRotation;
			Vector3 linearVelocity = Vector3.zero;
			if (Object.op_Implicit((Object)(object)AttachRoot))
			{
				Rigidbody componentInParent = AttachRoot.GetComponentInParent<Rigidbody>();
				if (Object.op_Implicit((Object)(object)componentInParent))
				{
					linearVelocity = componentInParent.GetPointVelocity(((Component)_character).transform.position);
				}
			}
			_character.m_body.linearVelocity = linearVelocity;
			_character.m_body.useGravity = false;
			_character.m_body.angularVelocity = Vector3.zero;
			_character.m_maxAirAltitude = ((Component)_character).transform.position.y;
		}

		public bool IsAttached()
		{
			return HasAttach;
		}

		public void Attach(bool attach, string animation = "", Chair chair = null)
		{
			if (attach)
			{
				AttachStop();
				SetAttachStart(animation, chair);
			}
			else
			{
				SetAttachStop(animation);
			}
		}

		public void SetAttachStart(string animation = "", Chair chair = null)
		{
			ZDO zdo = _character.m_nview.GetZDO();
			_character.m_nview.ClaimOwnership();
			NPCZDOUtils.SetAttached(ref zdo, attach: true);
			if (Object.op_Implicit((Object)(object)chair))
			{
				animation = chair.m_attachAnimation;
			}
			NPCZDOUtils.SetAnimation(ref zdo, animation);
			AttachStart(animation, chair);
		}

		protected void AttachStart(string animation = "", Chair chair = null)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			//IL_00ca: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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)
			HasAttach = true;
			if (!Object.op_Implicit((Object)(object)chair) && (animation == "attach_chair" || animation == "attach_throne"))
			{
				chair = Utility.GetClosestChair(((Component)_character).transform.position, ((Component)_character).transform.localScale / 2f);
			}
			if (!Utility.IsNullOrWhiteSpace(AttachAnimation))
			{
				_character.m_zanim.SetBool(AttachAnimation, false);
			}
			if (Object.op_Implicit((Object)(object)chair))
			{
				AttachPosition = chair.m_attachPoint.position;
				AttachRotation = chair.m_attachPoint.rotation;
				((Component)_character).transform.position = AttachPosition;
				((Component)_character).transform.rotation = AttachRotation;
				AttachAnimation = chair.m_attachAnimation;
				AttachRoot = ((Component)((Component)chair).transform.root).gameObject;
			}
			else
			{
				AttachPosition = ((Component)_character).transform.position;
				AttachRotation = ((Component)_character).transform.rotation;
				AttachAnimation = animation;
				AttachRoot = null;
			}
			if (!Utility.IsNullOrWhiteSpace(AttachAnimation))
			{
				_character.m_zanim.SetBool(AttachAnimation, true);
			}
			Vector3 linearVelocity = Vector3.zero;
			if (Object.op_Implicit((Object)(object)AttachRoot))
			{
				Rigidbody componentInParent = AttachRoot.GetComponentInParent<Rigidbody>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					linearVelocity = componentInParent.GetPointVelocity(((Component)_character).transform.position);
				}
				AttachColliders = AttachRoot.GetComponentsInChildren<Collider>();
				Collider[] attachColliders = AttachColliders;
				foreach (Collider val in attachColliders)
				{
					Physics.IgnoreCollision((Collider)(object)_character.m_collider, val, true);
				}
			}
			_character.m_body.linearVelocity = linearVelocity;
			_character.m_body.mass = 1000f;
			_character.m_body.useGravity = false;
			_character.m_body.angularVelocity = Vector3.zero;
			_character.m_maxAirAltitude = ((Component)_character).transform.position.y;
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).HideHandItems(false, true);
			}
			_character.ResetCloth();
		}

		public void SetAttachStop(string animation = "")
		{
			if (HasAttach)
			{
				_character.m_nview.ClaimOwnership();
				ZDO zdo = _character.m_nview.GetZDO();
				NPCZDOUtils.SetAnimation(ref zdo, animation);
				NPCZDOUtils.SetAttached(ref zdo, attach: false);
				AttachStop(animation);
			}
		}

		protected void AttachStop(string animation = "")
		{
			if (AttachColliders != null)
			{
				Collider[] attachColliders = AttachColliders;
				foreach (Collider val in attachColliders)
				{
					Physics.IgnoreCollision((Collider)(object)_character.m_collider, val, false);
				}
			}
			HasAttach = false;
			if (!Utility.IsNullOrWhiteSpace(AttachAnimation))
			{
				_character.m_zanim.SetBool(AttachAnimation, false);
			}
			AttachAnimation = animation;
			if (!Utility.IsNullOrWhiteSpace(AttachAnimation))
			{
				_character.m_zanim.SetBool(AttachAnimation, true);
			}
			_character.m_body.useGravity = true;
			_character.m_body.mass = _character.m_originalMass;
			AttachColliders = null;
			AttachRoot = null;
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).ShowHandItems(false, true);
			}
			_character.ResetCloth();
		}

		public void SetFromConfig(NPCConfig config, bool newSpawn)
		{
			//IL_0150: 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)
			_newSpawn = newSpawn;
			if (config == null)
			{
				return;
			}
			_character.m_nview.ClaimOwnership();
			Random.InitState((int)DateTime.Now.Ticks);
			if (config.StandStill && !HasAttach)
			{
				SetAttachStart(config.Animation);
			}
			else if (!config.StandStill && HasAttach)
			{
				SetAttachStop(config.Animation);
			}
			if (config.ModelIndex.HasValue)
			{
				SetModel(config.ModelIndex.Value);
			}
			if (_character is Humanoid && ((Humanoid)/*isinst with value type is only supported in some contexts*/).m_inventory != null)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_inventory.RemoveAll();
			}
			if (_character is Humanoid && (Object)(object)((Humanoid)/*isinst with value type is only supported in some contexts*/).m_visEquipment != (Object)null)
			{
				if (config.SkinColorR.HasValue && config.SkinColorG.HasValue && config.SkinColorB.HasValue)
				{
					SetSkinColor(config.SkinColorR.Value, config.SkinColorG.Value, config.SkinColorB.Value);
				}
				else
				{
					SetSkinColor(GetRandomSkinColor());
				}
				if (config.HairColorR.HasValue && config.HairColorG.HasValue && config.HairColorB.HasValue)
				{
					SetHairColor(config.HairColorR.Value, config.HairColorG.Value, config.HairColorB.Value);
				}
				else
				{
					SetHairColor(GetRandomHairColor());
				}
				SetNPCHair(config.Hair);
				SetNPCBeard(config.Beard);
				SetHelmet(config.Helmet);
				SetChest(config.Chest);
				SetLegs(config.Legs);
				SetUtility(config.Utility);
				SetShoulder(config.Shoulder, config.ShoulderVariant.Value);
				SetLeftHand(config.LeftHand, config.LeftHandVariant.Value);
				SetRightHand(config.RightHand);
			}
			ZDO zdo = _character.m_nview.GetZDO();
			NPCZDOUtils.SetZDOFromConfig(ref zdo, config);
			UpdateQuest(forceReset: true);
			if (!UpdateTrader())
			{
				UpdateTalker();
			}
		}

		public void SetRotation(Quaternion rotation)
		{
			//IL_001b: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			_character.m_nview.ClaimOwnership();
			((Component)_character).transform.rotation = rotation;
			if (IsAttached())
			{
				AttachRotation = rotation;
			}
			ZDO zdo = _character.m_nview.GetZDO();
			NPCZDOUtils.SetRotation(ref zdo, rotation);
		}

		public void SetName(string name)
		{
			_character.m_nview.ClaimOwnership();
			_character.m_nview.GetZDO().Set(ZDOVars.s_tamedName, name);
			_character.m_name = name;
		}

		public void SetSpawnPoint(Vector3 position)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			_character.m_nview.ClaimOwnership();
			ZDO zdo = _character.m_nview.GetZDO();
			NPCZDOUtils.SetSpawnPoint(ref zdo, position);
		}

		public void SetTrueDeath(bool death)
		{
			_character.m_nview.ClaimOwnership();
			ZDO zdo = _character.m_nview.GetZDO();
			NPCZDOUtils.SetTrueDeath(ref zdo, death);
		}

		public void SetRandom()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (_character is Humanoid)
			{
				_character.m_nview.ClaimOwnership();
				Random.InitState((int)DateTime.Now.Ticks);
				int num = Random.Range(0, 2);
				SetModel(num);
				SetSkinColor(GetRandomSkinColor());
				SetNPCHair("Hair" + Random.Range(1, 32));
				SetHairColor(GetRandomHairColor());
				switch (num)
				{
				case 0:
					SetRandomMale();
					break;
				case 1:
					SetRandomFemale();
					break;
				}
			}
		}

		protected void SetRandomMale()
		{
			int num = Random.Range(1, 30);
			if (num <= 21)
			{
				SetNPCBeard("Beard" + num);
			}
			int num2 = Random.Range(1, 25);
			if (num2 <= 10)
			{
				SetHelmet("HelmetHat" + num2);
			}
			else if (num2 < 16)
			{
				SetHelmet("HelmetLeather");
			}
			int num3 = Random.Range(1, 15);
			if (num3 > 10)
			{
				SetChest("ArmorLeatherChest");
			}
			else
			{
				SetChest("ArmorTunic" + num3);
			}
			if (Random.Range(0, 15) < 10)
			{
				SetLegs("ArmorLeatherLegs");
			}
			else
			{
				SetLegs("ArmorRagsLegs");
			}
		}

		protected void SetRandomFemale()
		{
			SetNPCBeard("");
			int num = Random.Range(1, 25);
			if (num <= 10)
			{
				SetHelmet("HelmetHat" + num);
			}
			else if (num < 17)
			{
				SetHelmet("HelmetMidsummerCrown");
			}
			int num2 = Random.Range(1, 15);
			if (num2 <= 10)
			{
				SetChest("ArmorDress" + num2);
			}
			else
			{
				SetChest("ArmorLeatherChest");
			}
			int num3 = Random.Range(0, 15);
			if (num3 < 5)
			{
				SetLegs("ArmorLeatherLegs");
			}
			else if (num3 < 8)
			{
				SetLegs("ArmorRagsLegs");
			}
		}

		protected void SetNPCHair(string name)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_hairItem = name;
				Character character2 = _character;
				((Humanoid)((character2 is Humanoid) ? character2 : null)).m_visEquipment.SetHairItem(name);
			}
		}

		protected void SetHairColor(Color color)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			SetHairColor(color.r, color.g, color.b);
		}

		protected void SetHairColor(float r, float g, float b)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (_character is Humanoid)
			{
				Vector3 hairColor = default(Vector3);
				((Vector3)(ref hairColor))..ctor(r, g, b);
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetHairColor(hairColor);
			}
		}

		protected void SetSkinColor(Color color)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			SetSkinColor(color.r, color.g, color.b);
		}

		protected void SetSkinColor(float r, float g, float b)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (_character is Humanoid)
			{
				Vector3 skinColor = default(Vector3);
				((Vector3)(ref skinColor))..ctor(r, g, b);
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetSkinColor(skinColor);
			}
		}

		protected void SetNPCBeard(string name)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_beardItem = name;
				Character character2 = _character;
				((Humanoid)((character2 is Humanoid) ? character2 : null)).m_visEquipment.SetBeardItem(name);
			}
		}

		protected void SetModel(int index)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetModel(index);
			}
		}

		private void SetItem(ref ItemData slot, int hash, int variant = -1)
		{
			if (!(_character is Humanoid))
			{
				return;
			}
			Character character = _character;
			if (((Humanoid)((character is Humanoid) ? character : null)).m_inventory == null || !Utility.GetItemPrefab(hash, out GameObject item))
			{
				slot = null;
				return;
			}
			Character character2 = _character;
			ItemData val = ((Humanoid)((character2 is Humanoid) ? character2 : null)).PickupPrefab(item, 0, false);
			if (val != null)
			{
				if (variant != -1)
				{
					val.m_variant = variant;
				}
				Character character3 = _character;
				((Humanoid)((character3 is Humanoid) ? character3 : null)).EquipItem(val, false);
			}
		}

		protected void SetHelmet(string name)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetHelmetItem(name);
				SetHelmet(StringExtensionMethods.GetStableHashCode(name));
			}
		}

		protected void SetHelmet(int hash)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				SetItem(ref ((Humanoid)((character is Humanoid) ? character : null)).m_helmetItem, hash);
			}
		}

		protected void SetChest(string name)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetChestItem(name);
				SetChest(StringExtensionMethods.GetStableHashCode(name));
			}
		}

		protected void SetChest(int hash)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				SetItem(ref ((Humanoid)((character is Humanoid) ? character : null)).m_chestItem, hash);
			}
		}

		protected void SetLegs(string name)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetLegItem(name);
				SetLegs(StringExtensionMethods.GetStableHashCode(name));
			}
		}

		protected void SetLegs(int hash)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				SetItem(ref ((Humanoid)((character is Humanoid) ? character : null)).m_legItem, hash);
			}
		}

		protected void SetShoulder(string name, int variant = 0)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetShoulderItem(name, variant);
				SetShoulder(StringExtensionMethods.GetStableHashCode(name), variant);
			}
		}

		protected void SetShoulder(int hash, int variant = 0)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				SetItem(ref ((Humanoid)((character is Humanoid) ? character : null)).m_shoulderItem, hash, variant);
			}
		}

		protected void SetUtility(string name)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetUtilityItem(name);
				SetUtility(StringExtensionMethods.GetStableHashCode(name));
			}
		}

		protected void SetUtility(int hash)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				SetItem(ref ((Humanoid)((character is Humanoid) ? character : null)).m_utilityItem, hash);
			}
		}

		protected void SetRightHand(string name)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetRightItem(name);
				SetRightHand(StringExtensionMethods.GetStableHashCode(name));
			}
		}

		protected void SetRightHand(int hash)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				SetItem(ref ((Humanoid)((character is Humanoid) ? character : null)).m_rightItem, hash);
			}
		}

		protected void SetLeftHand(string name, int variant = 0)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				((Humanoid)((character is Humanoid) ? character : null)).m_visEquipment.SetLeftItem(name, variant);
				SetLeftHand(StringExtensionMethods.GetStableHashCode(name), variant);
			}
		}

		protected void SetLeftHand(int hash, int variant = 0)
		{
			if (_character is Humanoid)
			{
				Character character = _character;
				SetItem(ref ((Humanoid)((character is Humanoid) ? character : null)).m_leftItem, hash, variant);
			}
		}

		protected Color GetRandomSkinColor()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.Range(0f, 1f);
			return Color.Lerp(Color32.op_Implicit(SkinColorMin), Color32.op_Implicit(SkinColorMax), num);
		}

		protected Color GetRandomHairColor()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.Range(0f, 1f);
			float num2 = Random.Range(0f, 1f);
			return Color.Lerp(Color32.op_Implicit(HairColorMin), Color32.op_Implicit(HairColorMax), num) * Mathf.Lerp(0.1f, 1f, num2);
		}

		public string GetSkinColor()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			Vector3 skinColor = NPCZDOUtils.GetSkinColor(_character.m_nview.GetZDO());
			return $"Skin Color RGB: {skinColor.x}, {skinColor.y}, {skinColor.z}";
		}

		public string GetHairColor()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			Vector3 hairColor = NPCZDOUtils.GetHairColor(_character.m_nview.GetZDO());
			return $"Hair Color RGB: {hairColor.x}, {hairColor.y}, {hairColor.z}";
		}
	}
	public class NPCFactory
	{
		private static List<Type> RemoveComponents = new List<Type>
		{
			typeof(PlayerController),
			typeof(Talker),
			typeof(Skills),
			typeof(CharacterDrop),
			typeof(Tameable),
			typeof(Procreation)
		};

		public static GameObject SpawnNPC(Vector3 position, Quaternion rotation, string name = "Ragnar", string model = "Player")
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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)
			string text = "vvnpcs_" + model;
			GameObject prefab = ZNetScene.instance.GetPrefab(StringExtensionMethods.GetStableHashCode(text));
			if ((Object)(object)prefab == (Object)null)
			{
				NPCSPlugin.NPCSLogger.LogError((object)"No prefab found");
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(prefab, position, rotation);
			INPC component = obj.GetComponent<INPC>();
			if (component != null)
			{
				if (model.Equals("Player"))
				{
					component.Data.SetRandom();
				}
				component.Data.SetName(name);
				component.Data.SetSpawnPoint(position);
			}
			return obj;
		}

		public static GameObject SpawnSavedNPC(Vector3 position, Quaternion rotation, string id)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			NPCConfig config = NPCConfiguration.GetConfig(id);
			if (config == null)
			{
				return null;
			}
			string text = "vvnpcs_" + config.Model;
			GameObject prefab = ZNetScene.instance.GetPrefab(StringExtensionMethods.GetStableHashCode(text));
			if ((Object)(object)prefab == (Object)null)
			{
				NPCSPlugin.NPCSLogger.LogError((object)"No prefab found");
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(prefab, position, rotation);
			INPC component = obj.GetComponent<INPC>();
			if (component != null)
			{
				component.Data.SetFromConfig(config, newSpawn: true);
				component.Data.SetSpawnPoint(position);
			}
			return obj;
		}

		public static GameObject RespawnNPC(ZPackage original)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_002a: 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_0030: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			NPCSPlugin.NPCSLogger.LogDebug((object)"Trying RespawnNPC...");
			ZDO val = new ZDO();
			original.m_stream.Position = 0L;
			val.Deserialize(original);
			Vector3 spawnPoint = NPCZDOUtils.GetSpawnPoint(val);
			if (spawnPoint == Vector3.zero)
			{
				NPCSPlugin.NPCSLogger.LogDebug((object)"No spawn point found!");
				return null;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(val.m_prefab);
			if ((Object)(object)prefab == (Object)null)
			{
				NPCSPlugin.NPCSLogger.LogDebug((object)"Issue finding prefab!");
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(prefab, spawnPoint, Quaternion.identity);
			ZNetView component = val2.GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null)
			{
				NPCSPlugin.NPCSLogger.LogDebug((object)"Issue instantiating prefab!");
				ZNetScene.instance.Destroy(val2);
				return null;
			}
			ZDO zDO = component.GetZDO();
			original.m_stream.Position = 0L;
			zDO.Deserialize(original);
			zDO.Set(ZDOVars.s_health, val2.GetComponent<Character>().GetMaxHealth());
			return val2;
		}

		public static void AddNPCS()
		{
			CreateNPC("Player");
			CreateNPC("Asksvin");
			CreateNPC("Boar");
			CreateNPC("Charred_Melee");
			CreateNPC("Deer");
			CreateNPC("Draugr");
			CreateNPC("Dverger");
			CreateNPC("Fenring");
			CreateNPC("Fenring_Cultist");
			CreateNPC("Ghost");
			CreateNPC("Goblin");
			CreateNPC("GoblinShaman");
			CreateNPC("Greydwarf");
			CreateNPC("Greyling");
			CreateNPC("Lox");
			CreateNPC("Neck");
			CreateNPC("Skeleton");
			CreateNPC("Troll");
			CreateNPC("Wolf");
		}

		public static GameObject CreateNPC(string model)
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				NPCSPlugin.NPCSLogger.LogError((object)"ZNetScene not ready");
				return null;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(StringExtensionMethods.GetStableHashCode(model));
			if ((Object)(object)prefab == (Object)null)
			{
				NPCSPlugin.NPCSLogger.LogError((object)"No prefab found");
				return null;
			}
			bool activeSelf = prefab.activeSelf;
			prefab.SetActive(false);
			GameObject val = Utility.CreateGameObject(prefab, model);
			foreach (Type removeComponent in RemoveComponents)
			{
				Component component = val.GetComponent(removeComponent);
				if ((Object)(object)component != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)component);
				}
			}
			Character component2 = prefab.GetComponent<Character>();
			Character component3 = val.GetComponent<Character>();
			Character npc = null;
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component3);
				npc = (Character)((!(component2 is Humanoid)) ? ((INPC)val.AddComponent<NPCCharacter>()) : ((INPC)val.AddComponent<NPCHumanoid>()));
			}
			SetupNPC<Character>(ref npc, component2);
			if (model.Equals("Player"))
			{
				((Humanoid)(npc as NPCHumanoid)).m_defaultItems = (GameObject[])(object)new GameObject[0];
				npc.m_walkSpeed = 2f;
				npc.m_speed = 2f;
				npc.m_runSpeed = 4f;
				npc.m_health = 200f;
				Utility.GetItemPrefab(StringExtensionMethods.GetStableHashCode("PlayerUnarmed"), out GameObject item);
				((Humanoid)(npc as NPCHumanoid)).m_unarmedWeapon = item.GetComponent<ItemDrop>();
			}
			npc.m_eye = Utils.FindChild(((Component)npc).gameObject.transform, "EyePos", (IterativeSearchType)0);
			npc.m_faction = (Faction)10;
			npc.m_tamed = false;
			npc.m_group = "VV_NPC";
			BaseAI val2 = val.GetComponent<BaseAI>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = (BaseAI)(object)val.AddComponent<NPCAI>();
			}
			else if (val2 is MonsterAI)
			{
				MonsterAI component4 = prefab.GetComponent<MonsterAI>();
				Object.DestroyImmediate((Object)(object)val2);
				NPCAI npcAI = val.AddComponent<NPCAI>();
				SetupMonsterAI(ref npcAI, component4);
			}
			else if (val2 is AnimalAI)
			{
				AnimalAI component5 = prefab.GetComponent<AnimalAI>();
				Object.DestroyImmediate((Object)(object)val2);
				NPCAnimalAI npcAI2 = val.AddComponent<NPCAnimalAI>();
				SetupAnimalAI(ref npcAI2, component5);
			}
			if (val2 is MonsterAI && (Object)(object)val.GetComponent<NpcTalk>() == (Object)null)
			{
				val.AddComponent<NpcTalk>();
			}
			ZNetView component6 = val.GetComponent<ZNetView>();
			component6.m_persistent = true;
			component6.m_type = (ObjectType)0;
			ZSyncTransform component7 = val.GetComponent<ZSyncTransform>();
			component7.m_syncPosition = true;
			component7.m_syncRotation = true;
			component7.m_syncBodyVelocity = false;
			component7.m_characterParentSync = false;
			prefab.SetActive(activeSelf);
			val.SetActive(activeSelf);
			Utility.RegisterGameObject(val);
			return val;
		}

		private static void SetupNPC<T>(ref T npc, Character original) where T : Character
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			Utility.CopyFields<Character, T>(original, ref npc);
			EffectData[] effectPrefabs = original.m_deathEffects.m_effectPrefabs;
			EffectData[] array = (EffectData[])(object)new EffectData[effectPrefabs.Length];
			for (int i = 0; i < effectPrefabs.Length; i++)
			{
				array[i] = new EffectData();
				Utility.CopyFields<EffectData, EffectData>(effectPrefabs[i], ref array[i]);
				if ((Object)(object)effectPrefabs[i].m_prefab != (Object)null && Object.op_Implicit((Object)(object)effectPrefabs[i].m_prefab.GetComponent<Ragdoll>()))
				{
					array[i].m_prefab = SetupRagdoll(effectPrefabs[i].m_prefab);
				}
			}
			((Character)npc).m_deathEffects = new EffectList();
			((Character)npc).m_deathEffects.m_effectPrefabs = array;
		}

		private static GameObject SetupRagdoll(GameObject original)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			bool activeSelf = original.activeSelf;
			original.SetActive(false);
			GameObject val = Utility.CreateGameObject(original, ((Object)original).name);
			Ragdoll component = original.GetComponent<Ragdoll>();
			Object.DestroyImmediate((Object)(object)val.GetComponent<Ragdoll>());
			NPCRagdoll clone = val.AddComponent<NPCRagdoll>();
			Utility.CopyFields<Ragdoll, NPCRagdoll>(component, ref clone);
			if (((Ragdoll)clone).m_removeEffect.m_effectPrefabs.Length == 0)
			{
				((Ragdoll)clone).m_removeEffect = new EffectList();
				GameObject prefab = ZNetScene.instance.GetPrefab(StringExtensionMethods.GetStableHashCode("vfx_corpse_destruction_small"));
				EffectData val2 = new EffectData();
				val2.m_prefab = prefab;
				((Ragdoll)clone).m_removeEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[1];
				((Ragdoll)clone).m_removeEffect.m_effectPrefabs[0] = val2;
			}
			ZNetView component2 = val.GetComponent<ZNetView>();
			component2.m_persistent = true;
			component2.m_type = (ObjectType)0;
			val.layer = 0;
			Rigidbody[] componentsInChildren = val.GetComponentsInChildren<Rigidbody>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).gameObject.layer = 0;
			}
			original.SetActive(activeSelf);
			val.SetActive(activeSelf);
			Utility.RegisterGameObject(val);
			return val;
		}

		private static void SetupMonsterAI(ref NPCAI npcAI, MonsterAI original)
		{
			Utility.CopyFields<MonsterAI, NPCAI>(original, ref npcAI);
			NPCAI.SetupExisting(ref npcAI);
		}

		private static void SetupAnimalAI(ref NPCAnimalAI npcAI, AnimalAI original)
		{
			Utility.CopyFields<AnimalAI, NPCAnimalAI>(original, ref npcAI);
			NPCAnimalAI.SetupExisting(ref npcAI);
		}
	}
	public class NPCHumanoid : Humanoid, Interactable, Hoverable, INPC
	{
		[CompilerGenerated]
		private sealed class <SetUp>d__7 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public NPCHumanoid <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SetUp>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				NPCHumanoid nPCHumanoid = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					nPCHumanoid.Data.Setup();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public NPCData Data { get; protected set; }

		public override void Awake()
		{
			((Humanoid)this).Awake();
			Data = new NPCData((Character)(object)this);
			IEnumerator enumerator = SetUp();
			((MonoBehaviour)this).StartCoroutine(enumerator);
		}

		public override void Start()
		{
			if (!NPCZDOUtils.GetInitialized(((Character)this).m_nview.GetZDO()))
			{
				((Humanoid)this).Start();
			}
		}

		public override void OnDestroy()
		{
			((Humanoid)this).OnDestroy();
		}

		[IteratorStateMachine(typeof(<SetUp>d__7))]
		public IEnumerator SetUp()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetUp>d__7(0)
			{
				<>4__this = this
			};
		}

		public override void CustomFixedUpdate(float fixedDeltaTime)
		{
			if (((Character)this).m_nview.IsValid())
			{
				((Humanoid)this).CustomFixedUpdate(fixedDeltaTime);
				if (((Character)this).m_nview.GetZDO() != null && ((Character)this).m_nview.IsOwner())
				{
					Data.UpdateAttach();
				}
			}
		}

		public override void OnDeath()
		{
			NPCUtils.OnDeath((Character)(object)this);
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			return NPCUtils.TryInteract((Character)(object)this);
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return NPCUtils.TryUseItem((Character)(object)this, item);
		}

		public override string GetHoverText()
		{
			return NPCUtils.GetHoverText((Character)(object)this, ((Character)this).m_baseAI);
		}

		public override string GetHoverName()
		{
			return ((Character)this).m_name;
		}

		public override bool IsAttached()
		{
			if (!Data.IsAttached())
			{
				return ((Humanoid)this).IsAttached();
			}
			return true;
		}

		public void Attach(bool attach, Chair chair = null)
		{
			Data.Attach(attach, "", chair);
		}

		public override void AttachStop()
		{
			Data.SetAttachStop();
		}
	}
	public class NPCRagdoll : Ragdoll, Interactable, Hoverable
	{
		[CompilerGenerated]
		private sealed class <SetUp>d__1 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public NPCRagdoll <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SetUp>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				NPCRagdoll nPCRagdoll = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (!NPCZDOUtils.GetTrueDeath(((Ragdoll)nPCRagdoll).m_nview.GetZDO()))
					{
						((MonoBehaviour)nPCRagdoll).InvokeRepeating("DestroyNow", ((Ragdoll)nPCRagdoll).m_ttl, 1f);
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public void Awake()
		{
			base.m_nview = ((Component)this).GetComponent<ZNetView>();
			base.m_bodies = ((Component)this).GetComponentsInChildren<Rigidbody>();
			((MonoBehaviour)this).Invoke("RemoveInitVel", 2f);
			if (Object.op_Implicit((Object)(object)base.m_mainModel))
			{
				float @float = base.m_nview.GetZDO().GetFloat(ZDOVars.s_hue, 0f);
				float float2 = base.m_nview.GetZDO().GetFloat(ZDOVars.s_saturation, 0f);
				float float3 = base.m_nview.GetZDO().GetFloat(ZDOVars.s_value, 0f);
				base.m_mainModel.material.SetFloat("_Hue", @float);
				base.m_mainModel.material.SetFloat("_Saturation", float2);
				base.m_mainModel.material.SetFloat("_Value", float3);
			}
			base.m_ttl = 4f;
			IEnumerator enumerator = SetUp();
			((MonoBehaviour)this).StartCoroutine(enumerator);
		}

		[IteratorStateMachine(typeof(<SetUp>d__1))]
		public IEnumerator SetUp()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetUp>d__1(0)
			{
				<>4__this = this
			};
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			((Ragdoll)this).DestroyNow();
			return false;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverText()
		{
			if ((Object)(object)base.m_nview != (Object)null && base.m_nview.GetZDO() != null && NPCZDOUtils.GetTrueDeath(base.m_nview.GetZDO()))
			{
				return Localization.instance.Localize(base.m_nview.GetZDO().GetString(ZDOVars.s_tamedName, "") + "\n[<color=yellow><b>$KEY_Use</b></color>] Bury Body\n[<color=yellow><b>F</b></color>] Pay Respects");
			}
			return "";
		}

		public string GetHoverName()
		{
			return "";
		}
	}
	public class NPCRespawner : MonoBehaviour
	{
		[HarmonyPatch(typeof(Game), "Start")]
		private static class Patch_Game_Start
		{
			private static void Postfix(Game __instance)
			{
				_instance = ((Component)__instance).gameObject.AddComponent<NPCRespawner>();
			}
		}

		[CompilerGenerated]
		private sealed class <WaitToRespawn>d__5 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public NPCRespawner <>4__this;

			public uint zdoId;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitToRespawn>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				int num = <>1__state;
				NPCRespawner nPCRespawner = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					nPCRespawner.RespawnNow(zdoId);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static readonly Dictionary<uint, ZPackage> _npcs = new Dictionary<uint, ZPackage>();

		private static NPCRespawner _instance;

		public static NPCRespawner Instance => _instance;

		public void AddZdo(string prefabName, ZDO zdo)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			IEnumerator enumerator = WaitToRespawn(((ZDOID)(ref zdo.m_uid)).ID);
			ZPackage val = new ZPackage();
			val.Clear();
			zdo.Serialize(val);
			_npcs.Add(((ZDOID)(ref zdo.m_uid)).ID, val);
			((MonoBehaviour)this).StartCoroutine(enumerator);
		}

		[IteratorStateMachine(typeof(<WaitToRespawn>d__5))]
		private IEnumerator WaitToRespawn(uint zdoId)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitToRespawn>d__5(0)
			{
				<>4__this = this,
				zdoId = zdoId
			};
		}

		public void OnDestroy()
		{
			foreach (ZPackage value in _npcs.Values)
			{
				NPCFactory.RespawnNPC(value);
			}
			_npcs.Clear();
		}

		private void RespawnNow(uint zdoId)
		{
			if (_npcs.ContainsKey(zdoId))
			{
				NPCFactory.RespawnNPC(_npcs[zdoId]);
				_npcs.Remove(zdoId);
			}
		}
	}
	public class NPCTamable : Tameable
	{
		public void Awake()
		{
			base.m_fedDuration = 60f;
			base.m_tamingTime = 10000f;
			base.m_startsTamed = false;
			base.m_commandable = false;
			((Tameable)this).Awake();
		}
	}
	public class NPCTrader : Trader
	{
		public void Setup()
		{
			ZDO zDO = ((Component)this).gameObject.GetComponent<ZNetView>().GetZDO();
			LookAt val = default(LookAt);
			if (!((Component)this).TryGetComponent<LookAt>(ref val))
			{
				((Component)this).gameObject.AddComponent<LookAt>();
			}
			base.m_items = NPCZDOUtils.GetNPCTradeItems(zDO);
			base.m_useItems = NPCZDOUtils.GetNPCTraderUseItems(zDO);
			base.m_randomTalk = NPCZDOUtils.GetNPCTexts("VV_TalkTexts", zDO, isTrader: true);
			base.m_randomGreets = NPCZDOUtils.GetNPCTexts("VV_GreetTexts", zDO, isTrader: true);
			base.m_randomGoodbye = NPCZDOUtils.GetNPCTexts("VV_ByeTexts", zDO, isTrader: true);
			base.m_randomStartTrade = NPCZDOUtils.GetNPCTexts("VV_StartTradeTexts", zDO, isTrader: true);
			base.m_randomBuy = NPCZDOUtils.GetNPCTexts("VV_BuyTexts", zDO, isTrader: true);
			base.m_randomSell = NPCZDOUtils.GetNPCTexts("VV_SellTexts", zDO, isTrader: true);
			base.m_randomGiveItemNo = NPCZDOUtils.GetNPCTexts("VV_NoCorrTexts", zDO, isTrader: true);
			base.m_randomUseItemAlreadyRecieved = NPCZDOUtils.GetNPCTexts("VV_NoAvailTexts", zDO, isTrader: true);
			base.m_dialogHeight = 2.5f;
			base.m_hideDialogDelay = 5f;
		}
	}
	public static class NPCUtils
	{
		public static string SetupText(NPCQuest quest, string text)
		{
			if (quest == null)
			{
				return text;
			}
			if (quest.GiveItem != null && text.Contains("{giveitem}"))
			{
				string text2 = quest.GiveItem.PrefabName;
				if (Utility.GetItemDrop(text2, out ItemDrop item))
				{
					text2 = item.m_itemData.m_shared.m_name;
				}
				string text3 = $"{quest.GiveItem.Amount} {text2}";
				if (quest.GiveItem.Quality > 1)
				{
					text3 += $" *{quest.GiveItem.Quality}";
				}
				text = text.Replace("{giveitem}", text3);
			}
			if (quest.RewardItems != null && text.Contains("{reward}"))
			{
				string text4 = "";
				for (int i = 0; i < quest.RewardItems.Count; i++)
				{
					NPCItem nPCItem = quest.RewardItems[i];
					string text5 = nPCItem.PrefabName;
					if (Utility.GetItemDrop(text5, out ItemDrop item2))
					{
						text5 = item2.m_itemData.m_shared.m_name;
					}
					text4 += $"{nPCItem.Amount} {text5}";
					if (nPCItem.Quality > 1)
					{
						text4 += $" *{nPCItem.Quality}";
					}
					if (i < quest.RewardItems.Count - 1)
					{
						text4 += ", ";
					}
				}
				text = text.Replace("{reward}", text4);
			}
			return Localization.instance.Localize(text);
		}

		public static void Talk(Character npc, string title, string text, NPCQuest quest)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer != (Object)null && !Utility.IsNullOrWhiteSpace(text))
			{
				Chat.instance.SetNpcText(((Component)npc).gameObject, Vector3.up * 2f, 15f, 20f, title, SetupText(quest, text), true);
			}
		}

		public static bool HasCorrectReqiuredKeys(HashSet<string> requiredKeys)
		{
			foreach (string requiredKey in requiredKeys)
			{
				if (!Utility.HasKey(requiredKey))
				{
					return false;
				}
			}
			return true;
		}

		public static bool HasCorrectNotReqiuredKeys(HashSet<string> notRequiredKeys)
		{
			foreach (string notRequiredKey in notRequiredKeys)
			{
				if (Utility.HasKey(notRequiredKey))
				{
					return false;
				}
			}
			return true;
		}

		public static bool HasCorrectKeys(HashSet<string> requiredKeys, HashSet<string> notRequiredKeys)
		{
			if (HasCorrectReqiuredKeys(requiredKeys))
			{
				return HasCorrectNotReqiuredKeys(notRequiredKeys);
			}
			return false;
		}

		public static void GiveReward(ref ZNetView nview, ref Character character, NPCQuest quest)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (quest.RewardItems != null)
			{
				foreach (NPCItem rewardItem in quest.RewardItems)
				{
					if (Utility.GetItemPrefab(StringExtensionMethods.GetStableHashCode(rewardItem.PrefabName), out GameObject item))
					{
						ItemDrop component = Object.Instantiate<GameObject>(item, ((Component)character).transform.position + new Vector3(0f, 0.75f, 0f) + ((Component)character).transform.rotation * Vector3.forward, ((Component)character).transform.rotation).GetComponent<ItemDrop>();
						component.SetStack(rewardItem.Amount.Value);
						component.SetQuality(rewardItem.Quality.Value);
						((Component)component).GetComponent<Rigidbody>().linearVelocity = (((Component)character).transform.forward + Vector3.up) * 1f;
					}
				}
				character.m_zanim.SetTrigger("interact");
			}
			if (quest.RewardLimit.Value > 0)
			{
				nview.ClaimOwnership();
				quest.RewardLimit--;
				ZDO zdo = nview.GetZDO();
				NPCZDOUtils.SetNPCQuest(ref zdo, quest.Index.Value, quest);
			}
			if (!Utility.IsNullOrWhiteSpace(quest.RewardKey))
			{
				Utility.SetKey(quest.RewardKey, quest.RewardKeyType);
			}
		}

		public static bool TryUseItem(Character npc, ItemData item)
		{
			BaseAI component = ((Component)npc).GetComponent<BaseAI>();
			if ((Object)(object)component != (Object)null && component.m_aggravated)
			{
				return false;
			}
			ZNetView nview = ((Component)npc).GetComponent<ZNetView>();
			ZDO zDO = nview.GetZDO();
			if (NPCZDOUtils.GetType(zDO) == 5)
			{
				NPCTrader component2 = ((Component)npc).GetComponent<NPCTrader>();
				if ((Object)(object)component2 == (Object)null)
				{
					return false;
				}
				((Trader)component2).UseItem((Humanoid)(object)Player.m_localPlayer, item);
				return true;
			}
			NPCQuest currentQuest = ((Component)npc).GetComponent<INPC>().Data.GetCurrentQuest();
			if (currentQuest == null)
			{
				return false;
			}
			string tamedName = NPCZDOUtils.GetTamedName(zDO);
			string text = currentQuest.Text;
			if (currentQuest.GiveItem != null && !Utility.IsNullOrWhiteSpace(currentQuest.GiveItem.PrefabName))
			{
				if (item == null || !((Object)item.m_dropPrefab).name.Equals(currentQuest.GiveItem.PrefabName) || !((Object)(object)Player.m_localPlayer != (Object)null))
				{
					Talk(npc, tamedName, "Hmmm that's not right... " + text, currentQuest);
					return false;
				}
				int value = currentQuest.GiveItem.Quality.Value;
				int value2 = currentQuest.GiveItem.Amount.Value;
				Player localPlayer = Player.m_localPlayer;
				if (((Humanoid)localPlayer).GetInventory().CountItems(item.m_shared.m_name, value, true) < value2)
				{
					Talk(npc, tamedName, "Hmmm that's not enough... " + text, currentQuest);
					return false;
				}
				if (currentQuest.GiveItem.RemoveItem.Value)
				{
					((Humanoid)localPlayer).UnequipItem(item, true);
					((Humanoid)localPlayer).GetInventory().RemoveItem(item.m_shared.m_name, value2, value, true);
					((Character)localPlayer).m_zanim.SetTrigger("interact");
				}
			}
			if (TryGiveReward(ref nview, ref npc, currentQuest) && !Utility.IsNullOrWhiteSpace(currentQuest.RewardText))
			{
				text = currentQuest.RewardText;
			}
			Talk(npc, tamedName, text, currentQuest);
			return true;
		}

		public static bool TryInteract(Character npc)
		{
			if (((Component)npc).GetComponent<BaseAI>().m_aggravated)
			{
				return false;
			}
			ZNetView nview = ((Component)npc).GetComponent<ZNetView>();
			if (NPCZDOUtils.GetType(nview.GetZDO()) == 5)
			{
				NPCTrader component = ((Component)npc).GetComponent<NPCTrader>();
				if ((Object)(object)component == (Object)null)
				{
					return false;
				}
				((Trader)component).Interact((Humanoid)null, false, false);
				return true;
			}
			NPCQuest currentQuest = ((Component)npc).GetComponent<INPC>().Data.GetCurrentQuest();
			if (currentQuest == null)
			{
				return false;
			}
			string text = currentQuest.Text;
			if ((currentQuest.GiveItem == null || Utility.IsNullOrWhiteSpace(currentQuest.GiveItem.PrefabName)) && TryGiveReward(ref nview, ref npc, currentQuest) && !Utility.IsNullOrWhiteSpace(currentQuest.RewardText))
			{
				text = currentQuest.RewardText;
			}
			if (!Utility.IsNullOrWhiteSpace(currentQuest.InteractKey))
			{
				Utility.SetKey(currentQuest.InteractKey, currentQuest.InteractKeyType);
			}
			string tamedName = NPCZDOUtils.GetTamedName(nview.GetZDO());
			Talk(npc, tamedName, text, currentQuest);
			return false;
		}

		private static bool TryGiveReward(ref ZNetView nview, ref Character character, NPCQuest quest)
		{
			if (HasCorrectReqiuredKeys(quest.RequiredKeysSet))
			{
				GiveReward(ref nview, ref character, quest);
				return true;
			}
			return false;
		}

		public static string GetHoverText(Character npc, BaseAI baseAI)
		{
			if ((Object)(object)npc == (Object)null || npc.m_nview.GetZDO() == null || ((Object)(object)baseAI != (Object)null && baseAI.m_aggravated))
			{
				return "";
			}
			int type = NPCZDOUtils.GetType(npc.m_nview.GetZDO());
			string text = "";
			if (type != 0)
			{
				NPCQuest currentQuest = ((Component)npc).GetComponent<INPC>().Data.GetCurrentQuest(update: false);
				if (type == 5 || currentQuest != null)
				{
					text = Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] $raven_interact");
					if (type == 5 || (currentQuest != null && currentQuest.GiveItem != null))
					{
						text += Localization.instance.Localize("\n[<color=yellow><b>1-8</b></color>] $npc_giveitem");
					}
				}
			}
			return text;
		}

		public static void OnDeath(Character character)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character.m_nview == (Object)null || !character.m_nview.IsOwner())
			{
				return;
			}
			ZDO zDO = character.m_nview.GetZDO();
			GameObject[] array = character.m_deathEffects.Create(((Component)character).transform.position, ((Component)character).transform.rotation, ((Component)character).transform, 1f, -1);
			for (int i = 0; i < array.Length; i++)
			{
				Ragdoll component = array[i].GetComponent<Ragdoll>();
				if ((Object)(object)component != (Object)null)
				{
					Vector3 val = character.m_body.velocity;
					if (((Vector3)(ref character.m_pushForce)).magnitude * 0.5f > ((Vector3)(ref val)).magnitude)
					{
						val = character.m_pushForce * 0.5f;
					}
					component.Setup(val, 0f, 0f, 0f, (CharacterDrop)null);
					VisEquipment copy = array[i].GetComponent<VisEquipment>();
					if ((Object)(object)copy != (Object)null)
					{
						NPCZDOUtils.CopyVisEquipment(ref copy, zDO);
					}
					ZDO zdo = component.m_nview.GetZDO();
					NPCZDOUtils.SetTamedName(ref zdo, character.m_name);
					NPCZDOUtils.SetTrueDeath(ref zdo, NPCZDOUtils.GetTrueDeath(zDO));
				}
			}
			Utility.SetKey(character.m_defeatSetGlobalKey, NPCData.NPCKeyType.Global);
			if (character.m_onDeath != null)
			{
				character.m_onDeath();
			}
			if (!NPCZDOUtils.GetTrueDeath(zDO))
			{
				NPCSPlugin.NPCSLogger.LogWarning((object)("Adding new " + ((Object)character).name + " to respawner!"));
				NPCRespawner.Instance.AddZdo(Utils.GetPrefabName(((Object)character).name), zDO);
			}
			ZNetScene.instance.Destroy(((Component)character).gameObject);
		}
	}
	public static class NPCZDOUtils
	{
		public static readonly char BackTickSeparator = '`';

		public static readonly char[] BackTickSeparatorList = new char[1] { '`' };

		public static readonly char PipeSeparator = '|';

		public static readonly char[] PipeSeparatorList = new char[1] { '|' };

		public static readonly char[] CommaSeparatorList = new char[1] { ',' };

		public static readonly int Version = 2;

		public const string ZDOVar_NPCVERSION = "VV_NPCVersion";

		public const string ZDOVar_INITIALIZED = "VV_Initialized";

		public const string ZDOVar_NPCTYPE = "VV_NPCType";

		public const string ZDOVar_ANIMATION = "VV_Animation";

		public const string ZDOVar_ATTACHED = "VV_Attached";

		public const string ZDOVar_ROTATION = "VV_Rotation";

		public const string ZDOVar_SPAWNPOINT = "VV_SpawnPoint";

		public const string ZDOVar_DEFEATKEY = "VV_DefeatKey";

		public const string ZDOVar_TRUEDEATH = "VV_TrueDeath";

		public const string ZDOVar_QUESTCOUNT = "VV_QuestCount";

		public const string ZDOVar_QUESTS = "VV_Quests";

		public const string ZDOVar_TRADEITEMS = "VV_TradeItems";

		public const string ZDOVar_TRADERUSEITEMS = "VV_TraderUseItems";

		public const string ZDOVar_AGGROTEXTS = "VV_AggroTexts";

		public const string ZDOVar_TALKTEXTS = "VV_TalkTexts";

		public const string ZDOVar_GREETTEXTS = "VV_GreetTexts";

		public const string ZDOVar_GOODBYETEXTS = "VV_ByeTexts";

		public const string ZDOVar_STARTTRADETEXTS = "VV_StartTradeTexts";

		public const string ZDOVar_BUYTEXTS = "VV_BuyTexts";

		public const string ZDOVar_SELLTEXTS = "VV_SellTexts";

		public const string ZDOVar_NOTCORRECTTEXTS = "VV_NoCorrTexts";

		public const string ZDOVar_NOTAVAILABLETEXTS = "VV_NoAvailTexts";

		public const string ZDOVar_SITTING = "VV_Sitting";

		private const string ZDOVar_DEFAULTTEXT = "VV_DefaultText";

		private const string ZDOVar_INTERACTTEXT = "VV_InteractText";

		private const string ZDOVar_GIVEITEM = "VV_GiveItem";

		private const string ZDOVar_GIVEITEMQUALITY = "VV_UseItemQuality";

		private const string ZDOVar_GIVEITEMAMOUNT = "VV_UseItemAmount";

		private const string ZDOVar_REWARDTEXT = "VV_RewardText";

		private const string ZDOVar_REWARDITEM = "VV_RewardItem";

		private const string ZDOVar_REWARDITEMQUALITY = "VV_RewardItemQualtiy";

		private const string ZDOVar_REWARDITEMAMOUNT = "VV_RewardItemAmount";

		private const string ZDOVar_REWARDLIMIT = "VV_RewardLimit";

		private const string ZDOVar_REQUIREDKEYS = "VV_RequiredKeys";

		private const string ZDOVar_NOTREQUIREDKEYS = "VV_NotRequiredKeys";

		private const string ZDOVar_INTERACTKEY = "VV_InteractKey";

		private const string ZDOVar_INTERACTKEYTYPE = "VV_InteractKeyType";

		private const string ZDOVar_REWARDKEY = "VV_RewardKey";

		private const string ZDOVar_REWARDKEYTYPE = "VV_RewardKeyType";

		public static List<int> ZdoVisEquipment = new List<int>
		{
			ZDOVars.s_beardItem,
			ZDOVars.s_hairItem,
			ZDOVars.s_helmetItem,
			ZDOVars.s_chestItem,
			ZDOVars.s_legItem,
			ZDOVars.s_shoulderItem,
			ZDOVars.s_shoulderItemVariant,
			ZDOVars.s_utilityItem,
			ZDOVars.s_rightItem,
			ZDOVars.s_leftItem,
			ZDOVars.s_leftItemVariant
		};

		public static int GetVersion(ZDO zdo)
		{
			return zdo.GetInt("VV_NPCVersion", 0);
		}

		public static void SetVersion(ref ZDO zdo)
		{
			zdo.Set("VV_NPCVersion", Version);
		}

		public static bool GetInitialized(ZDO zdo)
		{
			return zdo.GetBool("VV_Initialized", false);
		}

		public static void SetInitialized(ref ZDO zdo, bool init)
		{
			zdo.Set("VV_Initialized", init);
		}

		public static void SetMaxHealth(ref ZDO zdo, float health)
		{
			zdo.Set(ZDOVars.s_maxHealth, health);
		}

		public static string GetTamedName(ZDO zdo)
		{
			return zdo.GetString(ZDOVars.s_tamedName, "");
		}

		public static void SetTamedName(ref ZDO zdo, string name)
		{
			zdo.Set(ZDOVars.s_tamedName, name);
		}

		public static int GetType(ZDO zdo)
		{
			return zdo.GetInt("VV_NPCType", 0);
		}

		public static void SetType(ref ZDO zdo, int type)
		{
			zdo.Set("VV_NPCType", type);
		}

		public static string GetAnimation(ZDO zdo)
		{
			return zdo.GetString("VV_Animation", "");
		}

		public static void SetAnimation(ref ZDO zdo, string animation)
		{
			zdo.Set("VV_Animation", animation);
		}

		public static bool GetAttached(ZDO zdo)
		{
			return zdo.GetBool("VV_Attached", false);
		}

		public static void SetAttached(ref ZDO zdo, bool attach)
		{
			zdo.Set("VV_Attached", attach);
		}

		public static Quaternion GetRotation(ZDO zdo)
		{
			//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)
			return zdo.GetQuaternion("VV_Rotation", Quaternion.identity);
		}

		public static void SetRotation(ref ZDO zdo, Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			zdo.Set("VV_Rotation", rotation);
		}

		public static Vector3 GetSpawnPoint(ZDO zdo)
		{
			//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)
			return zdo.GetVec3("VV_SpawnPoint", Vector3.zero);
		}

		public static void SetSpawnPoint(ref ZDO zdo, Vector3 point)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			zdo.Set("VV_SpawnPoint", point);
		}

		public static string GetNPCDefeatKey(ZDO zdo)
		{
			return zdo.GetString("VV_DefeatKey", "");
		}

		public static void SetNPCDefeatKey(ref ZDO zdo, string key)
		{
			zdo.Set("VV_DefeatKey", key);
		}

		public static bool GetTrueDeath(ZDO zdo)
		{
			return zdo.GetBool("VV_TrueDeath", false);
		}

		public static void SetTrueDeath(ref ZDO zdo, bool death)
		{
			zdo.Set("VV_TrueDeath", death);
		}

		public static int GetNPCQuestCount(ZDO zdo)
		{
			return zdo.GetInt("VV_QuestCount", 0);
		}

		public static void SetNPCQuestCount(ref ZDO zdo, int count)
		{
			zdo.Set("VV_QuestCount", count);
		}

		public static bool GetNPCQuest(ZDO zdo, int index, out NPCQuest quest)
		{
			string @string = zdo.GetString(string.Format("{0}{1}", "VV_Quests", index), "");
			if (Utility.IsNullOrWhiteSpace(@string))
			{
				quest = null;
				return false;
			}
			string[] array = @string.Split(BackTickSeparatorList, int.MaxValue, StringSplitOptions.None);
			if (array.Length >= 9)
			{
				quest = new NPCQuest(array);
				string nPCQuestGive = GetNPCQuestGive(zdo, index);
				if (!Utility.IsNullOrWhiteSpace(nPCQuestGive))
				{
					string[] array2 = nPCQuestGive.Split(BackTickSeparatorList, int.MaxValue, StringSplitOptions.None);
					if (array2.Length >= 4)
					{
						quest.GiveItem = new NPCItem(array2);
					}
				}
				string nPCQuestReward = GetNPCQuestReward(zdo, index);
				if (!Utility.IsNullOrWhiteSpace(nPCQuestReward) && nPCQuestReward.Split(PipeSeparatorList, int.MaxValue, StringSplitOptions.None).Length != 0)
				{
					string[] array3 = nPCQuestReward.Split(BackTickSeparatorList, int.MaxValue, StringSplitOptions.None);
					if (array3.Length >= 4)
					{
						quest.RewardItems = new List<NPCItem>
						{
							new NPCItem(array3)
						};
					}
				}
				return true;
			}
			NPCSPlugin.NPCSLogger.LogWarning((object)"GetNPCQuest failed!! Data format incorrect.");
			quest = null;
			return false;
		}

		public static string GetNPCQuest(ZDO zdo, int index)
		{
			return zdo.GetString(string.Format("{0}{1}", "VV_Quests", index), "");
		}

		public static string GetNPCQuestGive(ZDO zdo, int index)
		{
			return zdo.GetString(string.Format("{0}{1}GIVE", "VV_Quests", index), "");
		}

		public static string GetNPCQuestReward(ZDO zdo, int index)
		{
			return zdo.GetString(string.Format("{0}{1}REWARD", "VV_Quests", index), "");
		}

		public static void SetNPCQuest(ref ZDO zdo, int index, NPCQuest quest)
		{
			SetNPCQuestString(ref zdo, index, Utility.GetString(quest));
			if (quest == null)
			{
				SetNPCQuestGive(ref zdo, index, "");
				SetNPCQuestReward(ref zdo, index, "");
			}
			else
			{
				SetNPCQuestGive(ref zdo, index, Utility.GetString(quest.GiveItem));
				SetNPCQuestReward(ref zdo, index, Utility.GetStringFromList(quest.RewardItems));
			}
		}

		public static void SetNPCQuestString(ref ZDO zdo, int index, string quest)
		{
			zdo.Set(string.Format("{0}{1}", "VV_Quests", index), quest);
		}

		public static void SetNPCQuestGive(ref ZDO zdo, int index, string give)
		{
			zdo.Set(string.Format("{0}{1}GIVE", "VV_Quests", index), give);
		}

		public static void SetNPCQuestReward(ref ZDO zdo, int index, string reward)
		{
			zdo.Set(string.Format("{0}{1}REWARD", "VV_Quests", index), reward);
		}

		public static List<TradeItem> GetNPCTradeItems(ZDO zdo)
		{
			return GetTradeItems(zdo.GetString("VV_TradeItems", ""));
		}

		public static void SetNPCTradeItems(ref ZDO zdo, List<NPCTradeItem> items)
		{
			zdo.Set("VV_TradeItems", Utility.GetStringFromList(items));
		}

		public static List<TraderUseItem> GetNPCTraderUseItems(ZDO zdo)
		{
			return GetTraderUseItems(zdo.GetString("VV_TraderUseItems", ""));
		}

		public static void SetNPCTraderUseItems(ref ZDO zdo, List<NPCTraderUseItem> items)
		{
			zdo.Set("VV_TraderUseItems", Utility.GetStringFromList(items));
		}

		private static List<TradeItem> GetTradeItems(string config)
		{
			List<TradeItem> list = new List<TradeItem>();
			string[] array = config.Split(PipeSeparatorList, int.MaxValue, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				TradeItem tradeItem = GetTradeItem(array[i]);
				if (tradeItem != null)
				{
					list.Add(tradeItem);
				}
			}
			return list;
		}

		private static TradeItem GetTradeItem(string item)
		{
			//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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			string[] array = item.Split(BackTickSeparatorList, int.MaxValue, StringSplitOptions.None);
			if (array.Length >= 5)
			{
				NPCTradeItem nPCTradeItem = new NPCTradeItem(array);
				Utility.GetItemPrefab(StringExtensionMethods.GetStableHashCode(nPCTradeItem.PrefabName), out GameObject item2);
				ItemDrop prefab = default(ItemDrop);
				if ((Object)(object)item2 == (Object)null || !item2.TryGetComponent<ItemDrop>(ref prefab))
				{
					return null;
				}
				return new TradeItem
				{
					m_prefab = prefab,
					m_stack = nPCTradeItem.Amount.Value,
					m_price = nPCTradeItem.Cost.Value,
					m_requiredGlobalKey = nPCTradeItem.RequiredKey
				};
			}
			return null;
		}

		private static List<TraderUseItem> GetTraderUseItems(string config)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			List<TraderUseItem> list = new List<TraderUseItem>();
			string[] array = config.Split(PipeSeparatorList, int.MaxValue, StringSplitOptions.RemoveEmptyEntries);
			ItemDrop prefab2 = default(ItemDrop);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(BackTickSeparatorList, int.MaxValue, StringSplitOptions.None);
				if (array2.Length < 4)
				{
					continue;
				}
				NPCTraderUseItem nPCTraderUseItem = new NPCTraderUseItem(array2);
				if (nPCTraderUseItem != null)
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(nPCTraderUseItem.PrefabName);
					if ((Object)(object)prefab == (Object)null || !prefab.TryGetComponent<ItemDrop>(ref prefab2))
					{
						return null;
					}
					TraderUseItem val = new TraderUseItem();
					val.m_prefab = prefab2;
					val.m_setsGlobalKey = nPCTraderUseItem.RewardKey;
					val.m_removesItem = nPCTraderUseItem.RemoveItem.Value;
					val.m_dialog = nPCTraderUseItem.Text;
					list.Add(val);
				}
			}
			return list;
		}

		private static string JoinStrings(List<string> strings)
		{
			string text = "";
			foreach (string @string in strings)
			{
				text += $"{@string}{BackTickSeparator}";
			}
			return text;
		}

		public static List<string> GetNPCTexts(string zdoVar, ZDO zdo, bool isTrader = false)
		{
			List<string> list = zdo.GetString(zdoVar, "").Split(BackTickSeparatorList, int.MaxValue, StringSplitOptions.RemoveEmptyEntries).ToList();
			if (list.Count == 0 && isTrader)
			{
				list.Add("...");
			}
			return list;
		}

		public static void SetNPCTexts(string zdoVar, ref ZDO zdo, List<string> texts)
		{
			zdo.Set(zdoVar, JoinStrings(texts));
		}

		public static bool GetLegacyNPCSitting(ZDO zdo)
		{
			return zdo.GetBool("VV_Sitting", false);
		}

		private static string GetLegacyNPCDefaultText(ZDO zdo)
		{
			return zdo.GetString("VV_DefaultText", "");
		}

		private static string GetLegacyNPCInteractText(ZDO zdo)
		{
			return zdo.GetString("VV_InteractText", "");
		}

		private static string GetLegacyNPCGiveItem(ZDO zdo)
		{
			return zdo.GetString("VV_GiveItem", "");
		}

		private static int GetLegacyNPCGiveItemQuality(ZDO zdo)
		{
			return zdo.GetInt("VV_UseItemQuality", 0);
		}

		private static int GetLegacyNPCGiveItemAmount(ZDO zdo)
		{
			return zdo.GetInt("VV_UseItemAmount", 0);
		}

		private static string GetLegacyNPCRewardText(ZDO zdo)
		{
			return zdo.GetString("VV_RewardText", "");
		}

		private static string GetLegacyNPCRewardItem(ZDO zdo)
		{
			return zdo.GetString("VV_RewardItem", "");
		}

		private static int GetLegacyNPCRewardItemQuality(ZDO zdo)
		{
			return zdo.GetInt("VV_RewardItemQualtiy", 0);
		}

		private static int GetLegacyNPCRewardItemAmount(ZDO zdo)
		{
			return zdo.GetInt("VV_RewardItemAmount", 0);
		}

		private static int GetLegacyNPCRewardLimit(ZDO zdo)
		{
			return zdo.GetInt("VV_RewardLimit", -1);
		}

		private static string GetLegacyNPCRequiredKeys(ZDO zdo)
		{
			return zdo.GetString("VV_RequiredKeys", "");
		}

		private static string GetLegacyNPCNotRequiredKeys(ZDO zdo)
		{
			return zdo.GetString("VV_NotRequiredKeys", "");
		}

		private static string GetLegacyNPCInteractKey(ZDO zdo)
		{
			return zdo.GetString("VV_InteractKey", "");
		}

		private static bool GetLegacyNPCInteractKeyType(ZDO zdo)
		{
			return zdo.GetBool("VV_InteractKeyType", false);
		}

		private static string GetLegacyNPCRewardKey(ZDO zdo)
		{
			return zdo.GetString("VV_RewardKey", "");
		}

		private static bool GetLegacyNPCRewardKeyType(ZDO zdo)
		{
			return zdo.GetBool("VV_RewardKeyType", false);
		}

		private static void ResetLegacyNPCData(ref ZDO zdo)
		{
			zdo.Set("VV_DefaultText", "");
			zdo.Set("VV_InteractText", "");
			zdo.Set("VV_GiveItem", "");
			zdo.RemoveInt("VV_UseItemQuality");
			zdo.RemoveInt("VV_UseItemAmount");
			zdo.Set("VV_RewardText", "");
			zdo.Set("VV_RewardItem", "");
			zdo.RemoveInt("VV_RewardItemQualtiy");
			zdo.RemoveInt("VV_RewardItemAmount");
			zdo.RemoveInt("VV_RewardLimit");
			zdo.Set("VV_RequiredKeys", "");
			zdo.Set("VV_NotRequiredKeys", "");
			zdo.Set("VV_InteractKey", "");
			zdo.RemoveInt("VV_InteractKeyType");
			zdo.Set("VV_RewardKey", "");
			zdo.RemoveInt("VV_RewardKeyType");
			zdo.RemoveInt("VV_Sitting");
		}

		public static Vector3 GetSkinColor(ZDO zdo)
		{
			//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)
			return zdo.GetVec3(ZDOVars.s_skinColor, Vector3.zero);
		}

		public static Vector3 GetHairColor(ZDO zdo)
		{
			//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)
			return zdo.GetVec3(ZDOVars.s_hairColor, Vector3.zero);
		}

		public static void CopyVisEquipment(ref VisEquipment copy, ZDO original)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			copy.SetModel(original.GetInt(ZDOVars.s_modelIndex, 0));
			copy.SetSkinColor(original.GetVec3(ZDOVars.s_skinColor, Vector3.zero));
			copy.SetHairColor(original.GetVec3(ZDOVars.s_hairColor, Vector3.zero));
			foreach (int item in ZdoVisEquipment)
			{
				copy.m_nview.GetZDO().Set(item, original.GetInt(item, 0), false);
			}
		}

		public static void SetZDOFromConfig(ref ZDO zdo, NPCConfig config)
		{
			try
			{
				SetTamedName(ref zdo, config.Name);
				SetType(ref zdo, (int)config.Type);
				SetTrueDeath(ref zdo, config.TrueDeath);
				SetNPCDefeatKey(ref zdo, config.DefeatKey);
				SetInitialized(ref zdo, !config.GiveDefaultItems.Value);
				if (config.MaxHealth > 0f)
				{
					SetMaxHealth(ref zdo, config.MaxHealth.Value);
				}
				if (config.Quests != null)
				{
					SetQuestData(ref zdo, config.Quests);
				}
				SetNPCTradeItems(ref zdo, config.TradeItems);
				SetNPCTraderUseItems(ref zdo, config.TraderUseItems);
				SetNPCTexts("VV_AggroTexts", ref zdo, config.AggravatedTexts);
				SetNPCTexts("VV_TalkTexts", ref zdo, config.TalkTexts);
				SetNPCTexts("VV_GreetTexts", ref zdo, config.GreetTexts);
				SetNPCTexts("VV_ByeTexts", ref zdo, config.GoodbyeTexts);
				SetNPCTexts("VV_StartTradeTexts", ref zdo, config.StartTradeTexts);
				SetNPCTexts("VV_BuyTexts", ref zdo, config.BuyTexts);
				SetNPCTexts("VV_SellTexts", ref zdo, config.SellTexts);
				SetNPCTexts("VV_NoAvailTexts", ref zdo, config.NotAvailableTexts);
				SetNPCTexts("VV_NoCorrTexts", ref zdo, config.NotCorrectTexts);
				SetVersion(ref zdo);
			}
			catch (Exception ex)
			{
				NPCSPlugin.NPCSLogger.LogError((object)"There was an issue spawing the npc from configurations, did you forget to reload the file?");
				NPCSPlugin.NPCSLogger.LogWarning((object)ex);
			}
		}

		private static void SetQuestData(ref ZDO zdo, List<NPCQuest> quests)
		{
			int nPCQuestCount = GetNPCQuestCount(zdo);
			if (nPCQuestCount > 0)
			{
				for (int i = 0; i < nPCQuestCount; i++)
				{
					SetNPCQuest(ref zdo, i, null);
				}
			}
			for (int j = 0; j < quests.Count; j++)
			{
				SetNPCQuest(ref zdo, j, quests[j]);
			}
			SetNPCQuestCount(ref zdo, quests.Count);
		}

		public static void UpgradeVersion(ref ZDO zdo)
		{
			if (GetVersion(zdo) >= 2)
			{
				return;
			}
			NPCSPlugin.NPCSLogger.LogWarning((object)("Upgrading npc version for " + GetTamedName(zdo) + "..."));
			NPCData.NPCType type = (NPCData.NPCType)GetType(zdo);
			if (type == NPCData.NPCType.Information || type == NPCData.NPCType.Reward)
			{
				SetType(ref zdo, 6);
				NPCQuest nPCQuest = new NPCQuest();
				NPCQuest nPCQuest2 = new NPCQuest();
				bool flag = false;
				string legacyNPCInteractText = GetLegacyNPCInteractText(zdo);
				if (!Utility.IsNullOrWhiteSpace(legacyNPCInteractText))
				{
					nPCQuest.Text = legacyNPCInteractText;
					nPCQuest2.Text = GetLegacyNPCDefaultText(zdo);
					flag = true;
				}
				else
				{
					nPCQuest.Text = GetLegacyNPCDefaultText(zdo);
				}
				nPCQuest.RewardText = GetLegacyNPCRewardText(zdo);
				nPCQuest.NotRequiredKeys = GetLegacyNPCNotRequiredKeys(zdo);
				nPCQuest.RequiredKeys = GetLegacyNPCRequiredKeys(zdo);
				nPCQuest.InteractKey = GetLegacyNPCInteractKey(zdo);
				nPCQuest.InteractKeyType = (GetLegacyNPCInteractKeyType(zdo) ? NPCData.NPCKeyType.Global : NPCData.NPCKeyType.Player);
				nPCQuest.RewardKey = GetLegacyNPCRewardKey(zdo);
				nPCQuest.RewardKeyType = (GetLegacyNPCRewardKeyType(zdo) ? NPCData.NPCKeyType.Global : NPCData.NPCKeyType.Player);
				nPCQuest.RewardLimit = GetLegacyNPCRewardLimit(zdo);
				string legacyNPCRewardItem = GetLegacyNPCRewardItem(zdo);
				if (!Utility.IsNullOrWhiteSpace(legacyNPCRewardItem))
				{
					nPCQuest.RewardItems = new List<NPCItem>();
					NPCItem nPCItem = new NPCItem();
					nPCItem.PrefabName = legacyNPCRewardItem;
					nPCItem.Amount = GetLegacyNPCRewardItemAmount(zdo);
					nPCItem.Quality = GetLegacyNPCRewardItemQuality(zdo);
					nPCItem.RemoveItem = true;
					nPCQuest.RewardItems.Add(nPCItem);
				}
				string legacyNPCGiveItem = GetLegacyNPCGiveItem(zdo);
				if (!Utility.IsNullOrWhiteSpace(legacyNPCGiveItem))
				{
					nPCQuest.GiveItem = new NPCItem();
					nPCQuest.GiveItem.PrefabName = legacyNPCGiveItem;
					nPCQuest.GiveItem.Amount = GetLegacyNPCGiveItemAmount(zdo);
					nPCQuest.GiveItem.Quality = GetLegacyNPCGiveItemQuality(zdo);
					nPCQuest.GiveItem.RemoveItem = true;
				}
				List<NPCQuest> list = new List<NPCQuest> { nPCQuest };
				if (flag)
				{
					list.Add(nPCQuest2);
				}
				SetQuestData(ref zdo, list);
				if (GetLegacyNPCSitting(zdo))
				{
					SetAttached(ref zdo, attach: true);
					SetAnimation(ref zdo, "attach_chair");
				}
				ResetLegacyNPCData(ref zdo);
			}
			SetVersion(ref zdo);
		}
	}
	public class Patches
	{
		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		private static class Patch_Terminal_InitTerminal
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__1_0;

				public static ConsoleEvent <>9__1_1;

				public static ConsoleEvent <>9__1_2;

				public static ConsoleEvent <>9__1_3;

				public static ConsoleEvent <>9__1_4;

				public static ConsoleEvent <>9__1_5;

				public static ConsoleEvent <>9__1_6;

				public static ConsoleEvent <>9__1_7;

				public static ConsoleEvent <>9__1_8;

				public static ConsoleEvent <>9__1_9;

				public static ConsoleEvent <>9__1_10;

				public static ConsoleEvent <>9__1_11;

				public static ConsoleEvent <>9__1_12;

				public static ConsoleEvent <>9__1_13;

				public static ConsoleEvent <>9__1_14;

				internal void <Postfix>b__1_0(ConsoleEventArgs args)
				{
					NPCConfiguration.ReloadFile();
				}

				internal void <Postfix>b__1_1(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0023: Unknown result type (might be due to invalid IL or missing references)
					//IL_0028: Unknown result type (might be due to invalid IL or missing references)
					//IL_0029: Unknown result type (might be due to invalid IL or missing references)
					//IL_002a: Unknown result type (might be due to invalid IL or missing references)
					//IL_002f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0034: Unknown result type (might be due to invalid IL or missing references)
					//IL_0039: 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_0044: 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_0079: Unknown result type (might be due to invalid IL or missing references)
					//IL_0063: Unknown result type (might be due to invalid IL or missing references)
					//IL_0064: Unknown result type (might be due to invalid IL or missing references)
					Vector3 position = ((Component)Player.m_localPlayer).gameObject.transform.position;
					Quaternion rotation = ((Component)Player.m_localPlayer).gameObject.transform.rotation;
					Vector3 position2 = position + rotation * Vector3.forward;
					if (args.Length > 2)
					{
						NPCFactory.SpawnNPC(position2, rotation, args[1], args[2]);
					}
					else if (args.Length > 1)
					{
						NPCFactory.SpawnNPC(position2, rotation, args[1]);
					}
					else
					{
						NPCFactory.SpawnNPC(position2, rotation);
					}
				}

				internal void <Postfix>b__1_2(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0023: Unknown result type (might be due to invalid IL or missing references)
					//IL_0028: Unknown result type (might be due to invalid IL or missing references)
					//IL_0029: Unknown result type (might be due to invalid IL or missing references)
					//IL_002a: Unknown result type (might be due to invalid IL or missing references)
					//IL_002f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0034: Unknown result type (might be due to invalid IL or missing references)
					//IL_0039: 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_0044: Unknown result type (might be due to invalid IL or missing references)
					Vector3 position = ((Component)Player.m_localPlayer).gameObject.transform.position;
					Quaternion rotation = ((Component)Player.m_localPlayer).gameObject.transform.rotation;
					Vector3 position2 = position + rotation * Vector3.forward;
					if (args.Length >= 2)
					{
						if ((Object)(object)NPCFactory.SpawnSavedNPC(position2, rotation, args[1]) == (Object)null)
						{
							args.Context.AddString("Could not spawn NPC!");
						}
					}
					else
					{
						args.Context.AddString("Wrong Syntax!");
					}
				}

				internal void <Postfix>b__1_3(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					float distance;
					INPC closestNPC = Utility.GetClosestNPC(((Component)Player.m_localPlayer).gameObject.transform.position, out distance);
					if (closestNPC == null)
					{
						args.Context.AddString("No npc found.");
					}
					else if (args.Length >= 2)
					{
						closestNPC.Data.SetFromConfig(NPCConfiguration.GetConfig(args[1]), newSpawn: false);
					}
					else
					{
						args.Context.AddString("Wrong Syntax!");
					}
				}

				internal void <Postfix>b__1_4(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					float distance;
					INPC closestNPC = Utility.GetClosestNPC(((Component)Player.m_localPlayer).gameObject.transform.position, out distance);
					if (closestNPC == null)
					{
						args.Context.AddString("No npc found.");
					}
					else if (args.Length >= 2)
					{
						closestNPC.Data.SetTrueDeath(bool.Parse(args[1]));
					}
					else
					{
						closestNPC.Data.SetTrueDeath(death: true);
					}
				}

				internal void <Postfix>b__1_5(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					float distance;
					INPC closestNPC = Utility.GetClosestNPC(((Component)Player.m_localPlayer).gameObject.transform.position, out distance);
					if (closestNPC == null)
					{
						args.Context.AddString("No npc found.");
						return;
					}
					string animation = "";
					if (args.Length >= 2)
					{
						animation = args[1];
					}
					closestNPC.Data.Attach(attach: false, animation);
				}

				internal void <Postfix>b__1_6(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					float distance;
					INPC closestNPC = Utility.GetClosestNPC(((Component)Player.m_localPlayer).gameObject.transform.position, out distance);
					if (closestNPC == null)
					{
						args.Context.AddString("No npc found.");
						return;
					}
					string animation = "";
					if (args.Length >= 2)
					{
						animation = args[1];
					}
					closestNPC.Data.Attach(attach: true, animation);
				}

				internal void <Postfix>b__1_7(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0014: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_0032: Unknown result type (might be due to invalid IL or missing references)
					//IL_0033: 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)
					Vector3 position = ((Component)Player.m_localPlayer).gameObject.transform.position;
					float distance;
					INPC closestNPC = Utility.GetClosestNPC(position, out distance);
					if (closestNPC == null)
					{
						args.Context.AddString("No npc found.");
						return;
					}
					Chair closestChair = Utility.GetClosestChair(position, Vector3.one * 2f);
					closestNPC.Data.Attach(attach: true, "", closestChair);
				}

				internal void <Postfix>b__1_8(ConsoleEventArgs args)
				{
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					Vector3 position = ((Component)Player.m_localPlayer).gameObject.transform.position;
					float range = 5f;
					if (args.Length >= 2 && float.TryParse(args[1], out var result))
					{
						range = result;
					}
					foreach (INPC allNPC in Utility.GetAllNPCS(position, range))
					{
						BaseAI val = null;
						((Character)((allNPC is Character) ? allNPC : null)).m_nview.ClaimOwnership();
						val = ((Component)((allNPC is Character) ? allNPC : null)).GetComponent<BaseAI>();
						if ((Object)(object)val != (Object)null)
						{
							val.SetAlerted(false);
							val.SetAggravated(false, (AggravatedReason)