Decompiled source of BaseAssistant v0.1.6

plugins\BaseAssistant.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("BaseAssistant")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Base Assistant Mod for Valheim")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+991da4ea4f056543d98b86a411fbed444f92aa4f")]
[assembly: AssemblyProduct("BaseAssistant")]
[assembly: AssemblyTitle("BaseAssistant")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BaseAssistant
{
	public class AssistantAI : MonoBehaviour
	{
		private ZNetView _nview;

		private Character _character;

		private MonsterAI _monsterAI;

		private Humanoid _humanoid;

		private bool _itemsHidden = false;

		private float _scanInterval = 2f;

		private float _timeSinceLastScan = 0f;

		private float _greetCooldown = 0f;

		private float _taskTimeout = 0f;

		private GameObject _targetObj;

		private string _currentTask = "Idle";

		private string _lastTaskCategory = "";

		private ItemData _heldItemData = null;

		private bool _weaponsCleared = false;

		private Dictionary<GameObject, float> _blacklistedObjects = new Dictionary<GameObject, float>();

		public static HashSet<ZDOID> ReservedItems = new HashSet<ZDOID>();

		private ZDOID _reservedZDOID = ZDOID.None;

		private Vector3 _lastPos;

		private float _stuckTimer = 0f;

		private bool _isSleeping = false;

		private bool _wasNight = false;

		private static readonly string[] _sleepPhrases = new string[8] { "Deu a minha hora, o peão tá cansado. Até amanhã!", "Chega por hoje, amanhã tem mais.", "Bati o ponto! Boa noite chefe.", "Indo deitar. Ninguém é de ferro, né?", "E chegou a hora de dormir, até amanhã!", "Acabou o expediente, patrão. Vou berçar.", "Vou capotar na cama agora. Boa noite!", "Sextou... ou não, mas eu vou dormir." };

		private static readonly string[] _wakePhrases = new string[4] { "Bom dia! Bora trabalhar que a base não se constrói sozinha.", "O sol nasceu, hora de arregaçar as mangas!", "Mais um dia de labuta. Bom dia chefe!", "Acordei! Cadê as fornalhas pra encher?" };

		private float _aliveTime = 0f;

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

		private bool _wasPaused = false;

		private GameObject _targetSmelter;

		private void Awake()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			_nview = ((Component)this).GetComponent<ZNetView>();
			_character = ((Component)this).GetComponent<Character>();
			_monsterAI = ((Component)this).GetComponent<MonsterAI>();
			_humanoid = ((Component)this).GetComponent<Humanoid>();
			if ((Object)(object)_character != (Object)null)
			{
				_character.m_faction = (Faction)0;
			}
		}

		private void Start()
		{
			if ((Object)(object)_monsterAI != (Object)null)
			{
				_monsterAI.m_alertRange = 0f;
				((BaseAI)_monsterAI).m_viewRange = 0f;
				((BaseAI)_monsterAI).m_hearRange = 0f;
				((BaseAI)_monsterAI).m_afraidOfFire = false;
				((BaseAI)_monsterAI).m_avoidFire = false;
				_monsterAI.m_fleeIfNotAlerted = false;
			}
			if ((Object)(object)_nview != (Object)null && _nview.IsOwner() && (Object)(object)_monsterAI != (Object)null)
			{
				((BaseAI)_monsterAI).SetPatrolPoint();
				((BaseAI)_monsterAI).m_randomMoveRange = Plugin.WorkRadius.Value;
				((BaseAI)_monsterAI).m_randomMoveInterval = 5f;
			}
			if ((Object)(object)_character != (Object)null)
			{
				Character character = _character;
				character.m_onDeath = (Action)Delegate.Combine(character.m_onDeath, new Action(OnNPCDied));
			}
		}

		private void OnNPCDied()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid() || !_nview.IsOwner())
			{
				return;
			}
			ZDOID zDOID = _nview.GetZDO().GetZDOID("TotemID");
			if (zDOID != ZDOID.None)
			{
				ZDO zDO = ZDOMan.instance.GetZDO(zDOID);
				if (zDO != null)
				{
					Logger.LogInfo((object)"[AssistantAI] O NPC morreu, limpando a ZDO do Totem para permitir respawn...");
					zDO.Set("NPC_ID", ZDOID.None);
				}
			}
		}

		private void Update()
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Invalid comparison between Unknown and I4
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Invalid comparison between Unknown and I4
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Invalid comparison between Unknown and I4
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview == (Object)null || !_nview.IsOwner())
			{
				return;
			}
			_aliveTime += Time.deltaTime;
			if ((Object)(object)_character != (Object)null)
			{
				_character.m_walkSpeed = Plugin.NpcWalkSpeed.Value;
				_character.m_runSpeed = Plugin.NpcRunSpeed.Value;
			}
			if (!_weaponsCleared && (Object)(object)_humanoid != (Object)null && _humanoid.GetInventory() != null)
			{
				List<ItemData> list = new List<ItemData>(_humanoid.GetInventory().GetAllItems());
				if (list.Count > 0)
				{
					foreach (ItemData item in list)
					{
						if ((int)item.m_shared.m_itemType == 4 || (int)item.m_shared.m_itemType == 3 || (int)item.m_shared.m_itemType == 14 || item.m_shared.m_name.ToLower().Contains("crossbow") || item.m_shared.m_name.ToLower().Contains("arbalest"))
						{
							_humanoid.UnequipItem(item, true);
							_humanoid.GetInventory().RemoveItem(item);
						}
					}
					_weaponsCleared = true;
				}
			}
			if (_greetCooldown > 0f)
			{
				_greetCooldown -= Time.deltaTime;
			}
			if (!_itemsHidden && (Object)(object)_humanoid != (Object)null)
			{
				_humanoid.HideHandItems(false, true);
				_itemsHidden = true;
			}
			if ((Object)(object)_character != (Object)null)
			{
				if (_heldItemData != null && _heldItemData.m_stack > 0)
				{
					string arg = Localization.instance.Localize(_heldItemData.m_shared.m_name);
					_character.m_name = $"Assistente ({_heldItemData.m_stack}x {arg})";
				}
				else
				{
					string arg2 = (((Object)(object)_nview != (Object)null && _nview.GetZDO() != null) ? _nview.GetZDO().GetString("AssistantName", "Assistente da Base") : "Assistente da Base");
					int num = (((Object)(object)_nview != (Object)null && _nview.GetZDO() != null) ? _nview.GetZDO().GetInt("AssistantProfession", 0) : 0);
					AssistantSpawner.Profession profession = (AssistantSpawner.Profession)num;
					_character.m_name = $"{arg2} [{profession}]";
				}
			}
			if (_isSleeping && (Object)(object)_targetObj != (Object)null && _currentTask == "GoToSleep")
			{
				if ((Object)(object)_monsterAI != (Object)null)
				{
					((Behaviour)_monsterAI).enabled = false;
				}
				if ((Object)(object)_character != (Object)null)
				{
					_character.SetMoveDir(Vector3.zero);
					Animator componentInChildren = ((Component)_character).GetComponentInChildren<Animator>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						((Component)componentInChildren).transform.localRotation = Quaternion.Euler(-90f, 0f, 0f);
						((Component)componentInChildren).transform.localPosition = Vector3.up * 0.5f;
					}
				}
			}
			else
			{
				if ((Object)(object)_monsterAI != (Object)null && !((Behaviour)_monsterAI).enabled)
				{
					((Behaviour)_monsterAI).enabled = true;
				}
				if ((Object)(object)_character != (Object)null)
				{
					Animator componentInChildren2 = ((Component)_character).GetComponentInChildren<Animator>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						((Component)componentInChildren2).transform.localRotation = Quaternion.identity;
						((Component)componentInChildren2).transform.localPosition = Vector3.zero;
					}
				}
			}
			_timeSinceLastScan += Time.deltaTime;
			if (_timeSinceLastScan >= _scanInterval)
			{
				_timeSinceLastScan = 0f;
				CheckForPlayerGreeting();
				ProcessAI();
			}
		}

		private void SayMessage(string msgId, string text, float cooldownMinutes = 3f, bool force = false)
		{
			//IL_0007: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			Player closestPlayer = Player.GetClosestPlayer(((Component)this).transform.position, 15f);
			if ((Object)(object)closestPlayer == (Object)null || (!force && _messageCooldowns.ContainsKey(msgId) && Time.time < _messageCooldowns[msgId]))
			{
				return;
			}
			AssistantAI[] array = Object.FindObjectsOfType<AssistantAI>();
			AssistantAI assistantAI = this;
			float num = Vector3.Distance(((Component)this).transform.position, ((Component)closestPlayer).transform.position);
			AssistantAI[] array2 = array;
			foreach (AssistantAI assistantAI2 in array2)
			{
				float num2 = Vector3.Distance(((Component)assistantAI2).transform.position, ((Component)closestPlayer).transform.position);
				if (num2 < num)
				{
					assistantAI = assistantAI2;
					num = num2;
				}
			}
			if (!((Object)(object)assistantAI != (Object)(object)this))
			{
				Chat.instance.SetNpcText(((Component)this).gameObject, Vector3.up * 1.5f, 20f, 5f, "", text, false);
				_messageCooldowns[msgId] = Time.time + cooldownMinutes * 60f;
			}
		}

		private void CheckForPlayerGreeting()
		{
			//IL_001c: 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)
			if (_greetCooldown <= 0f)
			{
				Player closestPlayer = Player.GetClosestPlayer(((Component)this).transform.position, 10f);
				if ((Object)(object)closestPlayer != (Object)null)
				{
					((Component)this).transform.LookAt(((Component)closestPlayer).transform.position);
					SayMessage("greet", "Olá " + closestPlayer.GetPlayerName() + ", trabalhando duro na base!", 5f);
					_greetCooldown = 60f;
				}
			}
		}

		private GameObject FindBed()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return null;
			}
			ZDOID zDOID = component.GetZDO().GetZDOID("AssignedBed");
			List<Piece> list = new List<Piece>();
			Piece.GetAllPiecesInRadius(GetBaseCenter(), Plugin.WorkRadius.Value, list);
			GameObject val = null;
			float num = float.MaxValue;
			if (zDOID != ZDOID.None)
			{
				foreach (Piece item in list)
				{
					if (((Object)item).name.StartsWith("BaseAssistantBed") || item.m_name.Contains("Cama do Assistente") || ((Object)item).name.ToLower().Contains("bed"))
					{
						ZNetView component2 = ((Component)item).GetComponent<ZNetView>();
						if ((Object)(object)component2 != (Object)null && component2.IsValid() && component2.GetZDO().m_uid == zDOID)
						{
							return ((Component)item).gameObject;
						}
					}
				}
				component.GetZDO().Set("AssignedBed", ZDOID.None);
				zDOID = ZDOID.None;
			}
			foreach (Piece item2 in list)
			{
				if (!((Object)item2).name.StartsWith("BaseAssistantBed") && !item2.m_name.Contains("Cama do Assistente") && !((Object)item2).name.ToLower().Contains("bed"))
				{
					continue;
				}
				ZNetView component3 = ((Component)item2).GetComponent<ZNetView>();
				if ((Object)(object)component3 == (Object)null || !component3.IsValid())
				{
					continue;
				}
				ZDOID uid = component3.GetZDO().m_uid;
				ZDOID val2 = component3.GetZDO().GetZDOID("AssignedNPC");
				if (val2 != ZDOID.None && val2 != component.GetZDO().m_uid)
				{
					ZDO zDO = ZDOMan.instance.GetZDO(val2);
					if (zDO == null)
					{
						val2 = ZDOID.None;
						component3.GetZDO().Set("AssignedNPC", ZDOID.None);
					}
				}
				if ((val2 == ZDOID.None || val2 == component.GetZDO().m_uid) && (!ReservedItems.Contains(uid) || !(_reservedZDOID != uid)))
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)item2).transform.position);
					if (num2 < num)
					{
						num = num2;
						val = ((Component)item2).gameObject;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				ZNetView component4 = val.GetComponent<ZNetView>();
				component.GetZDO().Set("AssignedBed", component4.GetZDO().m_uid);
				component4.GetZDO().Set("AssignedNPC", component.GetZDO().m_uid);
			}
			return val;
		}

		private GameObject FindTotem()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			List<Piece> list = new List<Piece>();
			Piece.GetAllPiecesInRadius(GetBaseCenter(), 5f, list);
			GameObject result = null;
			float num = float.MaxValue;
			foreach (Piece item in list)
			{
				if (((Object)item).name.StartsWith("AssistantTotem") || (Object)(object)((Component)item).GetComponent<AssistantSpawner>() != (Object)null)
				{
					float num2 = Vector3.Distance(GetBaseCenter(), ((Component)item).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = ((Component)item).gameObject;
					}
				}
			}
			return result;
		}

		private void ReleaseReservation()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			if (_reservedZDOID != ZDOID.None)
			{
				ReservedItems.Remove(_reservedZDOID);
				_reservedZDOID = ZDOID.None;
			}
		}

		private void ClearReservationWithoutRelease()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_reservedZDOID = ZDOID.None;
		}

		private void SetTask(string task, GameObject target)
		{
			if (task != _currentTask)
			{
				ReleaseReservation();
			}
			if (task != "GoToSleep")
			{
				_isSleeping = false;
			}
			_currentTask = task;
			_targetObj = target;
			_taskTimeout = 15f;
			_stuckTimer = 0f;
			if ((Object)(object)_monsterAI != (Object)null)
			{
				_monsterAI.SetFollowTarget(target);
			}
		}

		private void ProcessAI()
		{
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview != (Object)null && _nview.IsValid())
			{
				bool flag = _nview.GetZDO().GetBool("AssistantPaused", false);
				if (flag)
				{
					if (!_wasPaused)
					{
						SayMessage("vacation_start", "Férias merecidas! Vou tirar um cochilo.", 5f, force: true);
						DropHoldingItem();
						_wasPaused = true;
						GameObject val = FindBed();
						if ((Object)(object)val != (Object)null)
						{
							SetTask("GoToSleep", val);
						}
						else
						{
							GameObject target = FindTotem();
							SetTask("WaitByTotem", target);
						}
					}
					if (flag && _isSleeping)
					{
						return;
					}
				}
				else if (_wasPaused)
				{
					SayMessage("vacation_end", "Acabou a folga! Voltando ao trabalho.", 5f, force: true);
					SetTask("Idle", null);
					_isSleeping = false;
					_wasPaused = false;
				}
			}
			bool flag2 = (Object)(object)EnvMan.instance != (Object)null && EnvMan.IsNight();
			if (flag2 && !_wasNight)
			{
				string text = _sleepPhrases[Random.Range(0, _sleepPhrases.Length)];
				SayMessage("night_start", text, 10f, force: true);
				_wasNight = true;
				GameObject val2 = FindBed();
				if ((Object)(object)val2 != (Object)null)
				{
					DropHoldingItem();
					SetTask("GoToSleep", val2);
					ZNetView component = val2.GetComponent<ZNetView>();
					if ((Object)(object)component != (Object)null)
					{
						ZDOID uid = component.GetZDO().m_uid;
						ReservedItems.Add(uid);
						_reservedZDOID = uid;
					}
				}
				else
				{
					SayMessage("no_bed", "Trabalhei o dia todo e não me deram nem uma cama... Que exploração!", 10f, force: true);
					GameObject val3 = FindTotem();
					if ((Object)(object)val3 != (Object)null)
					{
						DropHoldingItem();
						SetTask("WaitByTotem", val3);
					}
				}
			}
			else if (!flag2 && _wasNight)
			{
				string text2 = _wakePhrases[Random.Range(0, _wakePhrases.Length)];
				SayMessage("morning_start", text2, 10f, force: true);
				_wasNight = false;
				_isSleeping = false;
				SetTask("Idle", null);
				GameObject val4 = FindBed();
				if ((Object)(object)val4 != (Object)null)
				{
					((Component)this).transform.position = val4.transform.position + Vector3.up * 1.5f;
				}
				else
				{
					GameObject val5 = FindTotem();
					if ((Object)(object)val5 != (Object)null)
					{
						((Component)this).transform.position = val5.transform.position + Vector3.up * 1.5f;
					}
					else
					{
						((Component)this).transform.position = GetBaseCenter() + Vector3.up * 1.5f;
					}
				}
				GameObject prefab = Cache.GetPrefab<GameObject>("vfx_sledge_hit");
				if ((Object)(object)prefab != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab, ((Component)this).transform.position, Quaternion.identity);
				}
			}
			if (_isSleeping && flag2)
			{
				return;
			}
			if (IsUnderAttack())
			{
				if (_currentTask != "Panic")
				{
					SetTask("Panic", null);
					SayMessage("panic_start", "Socorro! Monstros na base!", 5f, force: true);
				}
				GameObject val6 = FindBed();
				if ((Object)(object)val6 != (Object)null)
				{
					_monsterAI.SetFollowTarget(val6);
					return;
				}
				GameObject val7 = FindTotem();
				if ((Object)(object)val7 != (Object)null)
				{
					_monsterAI.SetFollowTarget(val7);
				}
				else
				{
					_monsterAI.SetFollowTarget((GameObject)null);
				}
				return;
			}
			if (_currentTask == "Panic")
			{
				SetTask("Idle", null);
				SayMessage("panic_end", "Ufa, parece seguro agora...", 5f, force: true);
			}
			if (_isSleeping)
			{
				return;
			}
			if ((_wasNight || _wasPaused) && _currentTask == "Idle")
			{
				GameObject val8 = FindBed();
				if ((Object)(object)val8 != (Object)null)
				{
					SetTask("GoToSleep", val8);
					return;
				}
				GameObject val9 = FindTotem();
				if ((Object)(object)val9 != (Object)null)
				{
					SetTask("WaitByTotem", val9);
				}
				return;
			}
			if (_currentTask != "Idle")
			{
				if (Vector3.Distance(((Component)this).transform.position, _lastPos) < 0.5f)
				{
					_stuckTimer += _scanInterval;
					if (_stuckTimer >= Plugin.StuckTimeout.Value && (Object)(object)_targetObj != (Object)null)
					{
						Logger.LogInfo((object)("[AssistantAI] Preso indo para " + ((Object)_targetObj).name + ". Abandonando tarefa!"));
						float num = ((_currentTask == "PickupGround") ? 5f : 15f);
						_blacklistedObjects[_targetObj] = Time.time + num;
						SetTask("Idle", null);
						return;
					}
				}
				else
				{
					_stuckTimer = 0f;
				}
				_lastPos = ((Component)this).transform.position;
				_taskTimeout -= _scanInterval;
				if ((Object)(object)_targetObj == (Object)null || _taskTimeout <= 0f)
				{
					if ((Object)(object)_targetObj == (Object)null && _currentTask == "PickupGround")
					{
						ClearReservationWithoutRelease();
					}
					Logger.LogWarning((object)("[AssistantAI] Tarefa " + _currentTask + " expirou ou alvo foi destruído. Voltando para Idle."));
					SetTask("Idle", null);
					return;
				}
			}
			string currentTask = _currentTask;
			if (_currentTask == "Idle" && !_wasNight && !_wasPaused)
			{
				FindNewTask();
			}
			else if (_currentTask == "PickupGround")
			{
				ExecutePickupGround();
			}
			else if (_currentTask == "TakeFromInbox")
			{
				ExecuteTakeFromInbox();
			}
			else if (_currentTask == "MoveToChestToStore")
			{
				ExecuteStoreToChest();
			}
			else if (_currentTask == "MoveToChestToFetch")
			{
				ExecuteFetchForSmelting();
			}
			else if (_currentTask == "MoveToChestToConsolidate")
			{
				ExecuteConsolidateFetch();
			}
			else if (_currentTask == "FeedSmelter")
			{
				ExecuteFeedSmelter();
			}
			else if (_currentTask == "RepairPiece")
			{
				ExecuteRepairPiece();
			}
			else if (_currentTask == "GoToSleep")
			{
				ExecuteGoToSleep();
			}
			else if (_currentTask == "WaitByTotem")
			{
				ExecuteWaitByTotem();
			}
			if (currentTask != _currentTask)
			{
				Logger.LogInfo((object)("[AssistantAI] Mudou de tarefa: " + currentTask + " -> " + _currentTask));
			}
		}

		private Vector3 GetBaseCenter()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview != (Object)null && _nview.GetZDO() != null)
			{
				Vector3 vec = _nview.GetZDO().GetVec3("HomeBedPos", Vector3.zero);
				if (vec != Vector3.zero)
				{
					return vec;
				}
			}
			return ((Component)this).transform.position;
		}

		private bool CheckAndSetSmeltingTask(Collider[] hits)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (Collider val in hits)
			{
				Smelter componentInParent = ((Component)val).GetComponentInParent<Smelter>();
				if (!((Object)(object)componentInParent != (Object)null) || (_blacklistedObjects.ContainsKey(((Component)componentInParent).gameObject) && Time.time < _blacklistedObjects[((Component)componentInParent).gameObject]))
				{
					continue;
				}
				ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid())
				{
					continue;
				}
				ZDOID uid = component.GetZDO().m_uid;
				if (ReservedItems.Contains(uid) && _reservedZDOID != uid)
				{
					continue;
				}
				if (componentInParent.m_maxFuel > 0 && (Object)(object)componentInParent.m_fuelItem != (Object)null)
				{
					float num = component.GetZDO().GetFloat("fuel", 0f);
					if (num < (float)componentInParent.m_maxFuel)
					{
						string name = componentInParent.m_fuelItem.m_itemData.m_shared.m_name;
						int leaveAmount = (name.ToLower().Contains("coal") ? Plugin.LeaveCoalAmount.Value : Plugin.LeaveWoodAmount.Value);
						Container val2 = FindChestForSmelterItem(hits, name, leaveAmount);
						if ((Object)(object)val2 != (Object)null)
						{
							_heldItemData = componentInParent.m_fuelItem.m_itemData.Clone();
							_heldItemData.m_dropPrefab = ((Component)componentInParent.m_fuelItem).gameObject;
							_heldItemData.m_stack = 0;
							_targetSmelter = ((Component)componentInParent).gameObject;
							SetTask("MoveToChestToFetch", ((Component)val2).gameObject);
							ReservedItems.Add(uid);
							_reservedZDOID = uid;
							return true;
						}
						string text = (name.ToLower().Contains("coal") ? "Carvão" : "Madeira para queimar");
						SayMessage("no_fuel_" + name, "Atenção chefe! Falta " + text + " nos baús!", 5f);
					}
				}
				int num2 = component.GetZDO().GetInt("queued", 0);
				if (num2 >= componentInParent.m_maxOre || componentInParent.m_conversion == null)
				{
					continue;
				}
				foreach (ItemConversion item in componentInParent.m_conversion)
				{
					if ((Object)(object)item.m_from == (Object)null || (Object)(object)item.m_to == (Object)null)
					{
						continue;
					}
					string name2 = item.m_from.m_itemData.m_shared.m_name;
					string name3 = item.m_to.m_itemData.m_shared.m_name;
					if (name3.ToLower().Contains("coal"))
					{
						string text2 = name2.ToLower();
						if (text2.Contains("finewood") || text2.Contains("roundlog") || text2.Contains("elderbark") || text2.Contains("yggdrasil"))
						{
							continue;
						}
						if (!dictionary.ContainsKey(name3))
						{
							dictionary[name3] = CountItemInBase(name3, hits);
						}
						if (dictionary[name3] >= Plugin.MaxCoalAmount.Value)
						{
							continue;
						}
					}
					int value = Plugin.LeaveOreAmount.Value;
					string text3 = name2.ToLower();
					if (text3.Contains("wood"))
					{
						value = Plugin.LeaveWoodAmount.Value;
					}
					else if (text3.Contains("copper"))
					{
						value = Plugin.LeaveCopperOre.Value;
					}
					else if (text3.Contains("tin"))
					{
						value = Plugin.LeaveTinOre.Value;
					}
					else if (text3.Contains("iron"))
					{
						value = Plugin.LeaveIronOre.Value;
					}
					else if (text3.Contains("silver"))
					{
						value = Plugin.LeaveSilverOre.Value;
					}
					else if (text3.Contains("blackmetal"))
					{
						value = Plugin.LeaveBlackMetalScrap.Value;
					}
					else if (text3.Contains("flametal"))
					{
						value = Plugin.LeaveFlametalOre.Value;
					}
					Container val3 = FindChestForSmelterItem(hits, name2, value);
					if ((Object)(object)val3 != (Object)null)
					{
						_heldItemData = item.m_from.m_itemData.Clone();
						_heldItemData.m_dropPrefab = ((Component)item.m_from).gameObject;
						_heldItemData.m_stack = 0;
						_targetSmelter = ((Component)componentInParent).gameObject;
						SetTask("MoveToChestToFetch", ((Component)val3).gameObject);
						ReservedItems.Add(uid);
						_reservedZDOID = uid;
						return true;
					}
					if (!name3.ToLower().Contains("coal"))
					{
						string text4 = Localization.instance.Localize(item.m_to.m_itemData.m_shared.m_name);
						SayMessage("no_ore_" + name2, "Chefe, a reserva de minério secou! Sem material para " + text4 + "!", 10f);
					}
				}
			}
			return false;
		}

		private Container FindChestForSmelterItem(Collider[] hits, string targetItemName, int leaveAmount)
		{
			foreach (Collider val in hits)
			{
				Container componentInParent = ((Component)val).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.GetInventory() != null && (!_blacklistedObjects.ContainsKey(((Component)componentInParent).gameObject) || !(Time.time < _blacklistedObjects[((Component)componentInParent).gameObject])))
				{
					int num = componentInParent.GetInventory().CountItems(targetItemName, -1, true);
					if (num > leaveAmount)
					{
						return componentInParent;
					}
				}
			}
			return null;
		}

		private void ExecuteWaitByTotem()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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)
			if ((Object)(object)_targetObj == (Object)null)
			{
				_currentTask = "Idle";
				return;
			}
			float num = Vector2.Distance(new Vector2(((Component)this).transform.position.x, ((Component)this).transform.position.z), new Vector2(_targetObj.transform.position.x, _targetObj.transform.position.z));
			if (num < 2.5f)
			{
				_monsterAI.SetFollowTarget((GameObject)null);
				if ((Object)(object)_character != (Object)null)
				{
					_character.SetMoveDir(Vector3.zero);
				}
				((Component)this).transform.LookAt(new Vector3(_targetObj.transform.position.x, ((Component)this).transform.position.y, _targetObj.transform.position.z));
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private void ExecuteGoToSleep()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_targetObj == (Object)null)
			{
				_currentTask = "Idle";
				return;
			}
			float num = Vector2.Distance(new Vector2(((Component)this).transform.position.x, ((Component)this).transform.position.z), new Vector2(_targetObj.transform.position.x, _targetObj.transform.position.z));
			if (num < 3.5f)
			{
				_isSleeping = true;
				((Component)this).transform.position = _targetObj.transform.position + Vector3.up * 0.8f;
				_monsterAI.SetFollowTarget((GameObject)null);
				_character.SetMoveDir(Vector3.zero);
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private void ExecuteRepairPiece()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_targetObj == (Object)null)
			{
				_currentTask = "Idle";
				return;
			}
			float value = Plugin.RepairDistance.Value;
			if (IsCloseEnough(_targetObj, value, value))
			{
				Collider[] array = Physics.OverlapSphere(_targetObj.transform.position, Plugin.AoERepairRadius.Value);
				bool flag = false;
				Collider[] array2 = array;
				foreach (Collider val in array2)
				{
					Piece componentInParent = ((Component)val).GetComponentInParent<Piece>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						WearNTear component = ((Component)componentInParent).GetComponent<WearNTear>();
						if ((Object)(object)component != (Object)null && component.GetHealthPercentage() < 1f)
						{
							component.Repair();
							componentInParent.m_placeEffect.Create(((Component)componentInParent).transform.position, ((Component)componentInParent).transform.rotation, (Transform)null, 1f, -1);
							flag = true;
						}
					}
				}
				if (flag)
				{
					((Component)this).transform.LookAt(_targetObj.transform.position);
					ZSyncAnimation component2 = ((Component)this).GetComponent<ZSyncAnimation>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.SetTrigger("interact");
					}
				}
				_currentTask = "Idle";
				_monsterAI.SetFollowTarget((GameObject)null);
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private int CountItemInBase(string prefabName, Collider[] hits)
		{
			GameObject prefab = Cache.GetPrefab<GameObject>(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				return 0;
			}
			string name = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
			int num = 0;
			foreach (Collider val in hits)
			{
				Container componentInParent = ((Component)val).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.GetInventory() != null && !((Object)componentInParent).name.Contains("personal"))
				{
					num += componentInParent.GetInventory().CountItems(name, -1, true);
					continue;
				}
				ItemDrop componentInParent2 = ((Component)val).GetComponentInParent<ItemDrop>();
				if ((Object)(object)componentInParent2 != (Object)null && componentInParent2.m_itemData != null && componentInParent2.m_itemData.m_shared.m_name == name)
				{
					num += componentInParent2.m_itemData.m_stack;
					continue;
				}
				AssistantAI componentInParent3 = ((Component)val).GetComponentInParent<AssistantAI>();
				if ((Object)(object)componentInParent3 != (Object)null && componentInParent3._heldItemData != null && componentInParent3._heldItemData.m_shared.m_name == name)
				{
					num += componentInParent3._heldItemData.m_stack;
				}
			}
			return num;
		}

		private void FindNewTask()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0669: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)(object)_nview != (Object)null && !_nview.IsOwner()) || _currentTask != "Idle")
			{
				return;
			}
			Collider[] array = Physics.OverlapSphere(GetBaseCenter(), Plugin.WorkRadius.Value);
			if (_heldItemData != null && _heldItemData.m_stack > 0)
			{
				GameObject dropPrefab = _heldItemData.m_dropPrefab;
				int num = 50;
				if ((Object)(object)dropPrefab != (Object)null)
				{
					num = dropPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize;
				}
				if (_heldItemData.m_stack < num)
				{
					Collider[] array2 = array;
					foreach (Collider val in array2)
					{
						ItemDrop componentInParent = ((Component)val).GetComponentInParent<ItemDrop>();
						if (!((Object)(object)componentInParent != (Object)null) || !((Object)(object)((Component)componentInParent).GetComponent<ZNetView>() != (Object)null) || !((Component)componentInParent).GetComponent<ZNetView>().IsValid())
						{
							continue;
						}
						ZDOID uid = ((Component)componentInParent).GetComponent<ZNetView>().GetZDO().m_uid;
						if (!ReservedItems.Contains(uid) && (!_blacklistedObjects.ContainsKey(((Component)componentInParent).gameObject) || !(Time.time < _blacklistedObjects[((Component)componentInParent).gameObject])))
						{
							string text = ((Object)((Component)componentInParent).gameObject).name.Replace("(Clone)", "").Trim();
							if ((Object)(object)dropPrefab != (Object)null && text == ((Object)dropPrefab).name)
							{
								SetTask("PickupGround", ((Component)componentInParent).gameObject);
								ReservedItems.Add(uid);
								_reservedZDOID = uid;
								return;
							}
						}
					}
				}
				Container val2 = FindChestFor(_heldItemData, array);
				if ((Object)(object)val2 != (Object)null)
				{
					SetTask("MoveToChestToStore", ((Component)val2).gameObject);
					return;
				}
				Logger.LogWarning((object)("[AssistantAI] Não achei baú com espaço para " + ((Object)_heldItemData.m_dropPrefab).name + ". Dropando no chão."));
				DropHoldingItem();
				return;
			}
			for (int j = 1; j <= 2; j++)
			{
				bool flag = j == 1 && _lastTaskCategory == "Sorting";
				bool flag2 = j == 1 && _lastTaskCategory == "Repair";
				bool flag3 = j == 1 && _lastTaskCategory == "Smelting";
				bool flag4 = j == 1 && _lastTaskCategory == "Looting";
				AssistantSpawner.Profession profession = AssistantSpawner.Profession.Geral;
				if ((Object)(object)_nview != (Object)null && _nview.IsValid())
				{
					profession = (AssistantSpawner.Profession)_nview.GetZDO().GetInt("AssistantProfession", 0);
				}
				if (!flag && Plugin.EnableSorting.Value && (profession == AssistantSpawner.Profession.Geral || profession == AssistantSpawner.Profession.Organizador))
				{
					Container val3 = FindInboxChestWithValidItems();
					if ((Object)(object)val3 != (Object)null)
					{
						_lastTaskCategory = "Sorting";
						_currentTask = "TakeFromInbox";
						_targetObj = ((Component)val3).gameObject;
						_monsterAI.SetFollowTarget(_targetObj);
						return;
					}
				}
				if (!flag2 && Plugin.EnableRepairing.Value && (profession == AssistantSpawner.Profession.Geral || profession == AssistantSpawner.Profession.Reparador))
				{
					Collider[] array3 = array;
					foreach (Collider val4 in array3)
					{
						Piece componentInParent2 = ((Component)val4).GetComponentInParent<Piece>();
						if (!((Object)(object)componentInParent2 != (Object)null) || (_blacklistedObjects.ContainsKey(((Component)componentInParent2).gameObject) && Time.time < _blacklistedObjects[((Component)componentInParent2).gameObject]))
						{
							continue;
						}
						WearNTear component = ((Component)componentInParent2).GetComponent<WearNTear>();
						if (!((Object)(object)component != (Object)null) || !(component.GetHealthPercentage() < Plugin.RepairHealthThreshold.Value))
						{
							continue;
						}
						ZNetView component2 = ((Component)componentInParent2).GetComponent<ZNetView>();
						if ((Object)(object)component2 != (Object)null && component2.IsValid())
						{
							ZDOID uid2 = component2.GetZDO().m_uid;
							if (!ReservedItems.Contains(uid2) || !(_reservedZDOID != uid2))
							{
								_lastTaskCategory = "Repair";
								SetTask("RepairPiece", ((Component)componentInParent2).gameObject);
								ReservedItems.Add(uid2);
								_reservedZDOID = uid2;
								return;
							}
						}
					}
				}
				if (!flag3 && Plugin.EnableSmelting.Value && (profession == AssistantSpawner.Profession.Geral || profession == AssistantSpawner.Profession.Ferreiro) && CheckAndSetSmeltingTask(array))
				{
					_lastTaskCategory = "Smelting";
					return;
				}
				if (!flag4 && Plugin.EnableLooting.Value && (profession == AssistantSpawner.Profession.Geral || profession == AssistantSpawner.Profession.Organizador))
				{
					Collider[] array4 = array;
					foreach (Collider val5 in array4)
					{
						ItemDrop componentInParent3 = ((Component)val5).GetComponentInParent<ItemDrop>();
						if (!((Object)(object)componentInParent3 != (Object)null) || !((Object)(object)((Component)componentInParent3).GetComponent<ZNetView>() != (Object)null) || !((Component)componentInParent3).GetComponent<ZNetView>().IsValid())
						{
							continue;
						}
						ZDOID uid3 = ((Component)componentInParent3).GetComponent<ZNetView>().GetZDO().m_uid;
						if (!ReservedItems.Contains(uid3) && (!_blacklistedObjects.ContainsKey(((Component)componentInParent3).gameObject) || !(Time.time < _blacklistedObjects[((Component)componentInParent3).gameObject])) && componentInParent3.m_itemData != null)
						{
							Container val6 = FindChestFor(componentInParent3.m_itemData, array);
							if ((Object)(object)val6 != (Object)null)
							{
								_lastTaskCategory = "Looting";
								SetTask("PickupGround", ((Component)componentInParent3).gameObject);
								ReservedItems.Add(uid3);
								_reservedZDOID = uid3;
								return;
							}
						}
					}
				}
				if (!flag && Plugin.EnableSorting.Value && CheckAndSetConsolidationTask(array))
				{
					_lastTaskCategory = "Sorting";
					return;
				}
			}
			_lastTaskCategory = "";
			SayMessage("all_done", "Base 100% limpa e organizada. Pausa para o hidromel!", 60f);
		}

		private Container FindChestFor(ItemData targetItem, Collider[] hits)
		{
			if (targetItem == null || targetItem.m_shared == null)
			{
				return null;
			}
			Container val = null;
			int num = -1;
			foreach (Collider val2 in hits)
			{
				Container componentInParent = ((Component)val2).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.GetInventory() != null && !((Object)componentInParent).name.Contains("personal") && (!_blacklistedObjects.ContainsKey(((Component)componentInParent).gameObject) || !(Time.time < _blacklistedObjects[((Component)componentInParent).gameObject])) && componentInParent.GetInventory().CanAddItem(targetItem, -1))
				{
					string customName = "";
					ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
					if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null)
					{
						customName = component.GetZDO().GetString("text", "").ToLower()
							.Trim();
					}
					int chestScore = GetChestScore(componentInParent, targetItem, customName);
					if (chestScore > num)
					{
						num = chestScore;
						val = componentInParent;
					}
				}
			}
			return (num >= 0) ? val : null;
		}

		private int GetChestScore(Container container, ItemData targetItem, string customName)
		{
			//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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Invalid comparison between Unknown and I4
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			string text = targetItem.m_shared.m_name ?? "";
			string text2 = text.ToLower();
			ItemType itemType = targetItem.m_shared.m_itemType;
			if (!string.IsNullOrEmpty(customName))
			{
				if (MatchAny(customName, Plugin.TagIgnore.Value.ToLower().Split(new char[1] { ',' })))
				{
					return -1000;
				}
				string text3 = Localization.instance.Localize(text).ToLower().Trim();
				if (customName == text3)
				{
					return 2000;
				}
				if (customName == text2.Replace("$item_", ""))
				{
					return 2000;
				}
				bool flag = false;
				if (MatchAny(customName, Plugin.TagWeapons.Value.ToLower().Split(new char[1] { ',' })) && IsWeapon(itemType))
				{
					flag = true;
				}
				if (MatchAny(customName, Plugin.TagArmor.Value.ToLower().Split(new char[1] { ',' })) && IsArmor(itemType))
				{
					flag = true;
				}
				if (MatchAny(customName, Plugin.TagFood.Value.ToLower().Split(new char[1] { ',' })) && (int)itemType == 2)
				{
					flag = true;
				}
				if (MatchAny(customName, Plugin.TagWood.Value.ToLower().Split(new char[1] { ',' })) && IsWood(text2, itemType))
				{
					flag = true;
				}
				if (MatchAny(customName, Plugin.TagMetal.Value.ToLower().Split(new char[1] { ',' })) && IsMetal(text2, itemType))
				{
					flag = true;
				}
				return flag ? 1000 : (-1000);
			}
			if (container.GetInventory().NrOfItems() == 0)
			{
				return 0;
			}
			bool flag2 = false;
			bool flag3 = false;
			foreach (ItemData allItem in container.GetInventory().GetAllItems())
			{
				if (allItem != null && allItem.m_shared != null)
				{
					string text4 = allItem.m_shared.m_name?.ToLower() ?? "";
					if (text4 == text2)
					{
						flag3 = true;
					}
					else
					{
						flag2 = true;
					}
				}
			}
			if (flag2)
			{
				return -1000;
			}
			if (flag3)
			{
				return 100;
			}
			return -1000;
		}

		private bool CheckAndSetConsolidationTask(Collider[] hits)
		{
			foreach (Collider val in hits)
			{
				Container componentInParent = ((Component)val).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent == (Object)null || componentInParent.GetInventory() == null || ((Object)componentInParent).name.Contains("personal") || (_blacklistedObjects.ContainsKey(((Component)componentInParent).gameObject) && Time.time < _blacklistedObjects[((Component)componentInParent).gameObject]))
				{
					continue;
				}
				string customName = "";
				ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null)
				{
					customName = component.GetZDO().GetString("text", "").ToLower()
						.Trim();
				}
				foreach (ItemData allItem in componentInParent.GetInventory().GetAllItems())
				{
					if (allItem == null || allItem.m_shared == null || (Object)(object)allItem.m_dropPrefab == (Object)null)
					{
						continue;
					}
					int chestScore = GetChestScore(componentInParent, allItem, customName);
					if (chestScore >= 2000)
					{
						continue;
					}
					Container val2 = FindChestFor(allItem, hits);
					if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)componentInParent)
					{
						string customName2 = "";
						ZNetView component2 = ((Component)val2).GetComponent<ZNetView>();
						if ((Object)(object)component2 != (Object)null && component2.IsValid() && component2.GetZDO() != null)
						{
							customName2 = component2.GetZDO().GetString("text", "").ToLower()
								.Trim();
						}
						int chestScore2 = GetChestScore(val2, allItem, customName2);
						if (chestScore2 >= 1000 && chestScore2 > chestScore)
						{
							_heldItemData = allItem.Clone();
							_heldItemData.m_stack = 0;
							SetTask("MoveToChestToConsolidate", ((Component)componentInParent).gameObject);
							return true;
						}
					}
				}
			}
			return false;
		}

		private bool MatchAny(string text, string[] tags)
		{
			foreach (string text2 in tags)
			{
				if (text2.Trim() != "" && text.Contains(text2.Trim()))
				{
					return true;
				}
			}
			return false;
		}

		private bool IsWeapon(ItemType t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			return (int)t == 3 || (int)t == 14 || (int)t == 4 || (int)t == 19;
		}

		private bool IsArmor(ItemType t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			return (int)t == 5 || (int)t == 6 || (int)t == 7 || (int)t == 11 || (int)t == 17;
		}

		private bool IsWood(string name, ItemType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)type != 1)
			{
				return false;
			}
			return name.Contains("wood") || name.Contains("log") || name.Contains("bark") || name.Contains("madeira") || name.Contains("lenha");
		}

		private bool IsMetal(string name, ItemType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)type != 1)
			{
				return false;
			}
			return name.Contains("ore") || name.Contains("scrap") || name.Contains("copper") || name.Contains("iron") || name.Contains("silver") || name.Contains("tin") || name.Contains("bronze") || name.Contains("metal") || name.Contains("flametal");
		}

		private Container FindChestForWood(Collider[] hits, out string foundWoodType)
		{
			foundWoodType = "Wood";
			GameObject prefab = Cache.GetPrefab<GameObject>("Wood");
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			string name = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
			foreach (Collider val in hits)
			{
				Container componentInParent = ((Component)val).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.GetInventory() != null && !((Object)componentInParent).name.Contains("personal") && (!_blacklistedObjects.ContainsKey(((Component)componentInParent).gameObject) || !(Time.time < _blacklistedObjects[((Component)componentInParent).gameObject])) && componentInParent.GetInventory().CountItems(name, -1, true) > 0)
				{
					return componentInParent;
				}
			}
			foundWoodType = "";
			return null;
		}

		private bool IsCloseEnough(GameObject target, float maxDistXZ = 1.5f, float maxDistY = 2f)
		{
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			maxDistXZ += 3.5f;
			maxDistY += 3.5f;
			Collider[] componentsInChildren = target.GetComponentsInChildren<Collider>();
			if (componentsInChildren.Length != 0)
			{
				float num = float.MaxValue;
				float num2 = float.MaxValue;
				Collider[] array = componentsInChildren;
				foreach (Collider val in array)
				{
					if (!val.isTrigger)
					{
						Bounds bounds = val.bounds;
						Vector3 val2 = ((Bounds)(ref bounds)).ClosestPoint(((Component)this).transform.position);
						float num3 = Vector2.Distance(new Vector2(((Component)this).transform.position.x, ((Component)this).transform.position.z), new Vector2(val2.x, val2.z));
						float num4 = Mathf.Abs(((Component)this).transform.position.y - val2.y);
						if (num3 < num)
						{
							num = num3;
						}
						if (num4 < num2)
						{
							num2 = num4;
						}
					}
				}
				if (num != float.MaxValue)
				{
					Logger.LogInfo((object)$"[AssistantAI] Alvo: {((Object)target).name} | Dist Atual -> XZ: {num:F2} / Y: {num2:F2} | Config -> XZ: {maxDistXZ:F2} / Y: {maxDistY:F2}");
					return num < maxDistXZ && num2 < maxDistY;
				}
			}
			float num5 = Vector2.Distance(new Vector2(((Component)this).transform.position.x, ((Component)this).transform.position.z), new Vector2(target.transform.position.x, target.transform.position.z));
			float num6 = Mathf.Abs(((Component)this).transform.position.y - target.transform.position.y);
			Logger.LogInfo((object)$"[AssistantAI] Alvo (Sem Colisão): {((Object)target).name} | Dist Atual -> XZ: {num5:F2} / Y: {num6:F2} | Config -> XZ: {maxDistXZ + 2f:F2} / Y: {maxDistY + 0.5f:F2}");
			return num5 < maxDistXZ + 2f && num6 < maxDistY + 0.5f;
		}

		private void ExecutePickupGround()
		{
			float value = Plugin.GroundItemDistance.Value;
			if (IsCloseEnough(_targetObj, value, value))
			{
				ItemDrop component = _targetObj.GetComponent<ItemDrop>();
				if (!((Object)(object)component != (Object)null) || component.m_itemData == null)
				{
					return;
				}
				if (_heldItemData == null)
				{
					_heldItemData = component.m_itemData.Clone();
				}
				else if (((Object)_heldItemData.m_dropPrefab).name == ((Object)component.m_itemData.m_dropPrefab).name)
				{
					ItemData heldItemData = _heldItemData;
					heldItemData.m_stack += component.m_itemData.m_stack;
				}
				ZSyncAnimation component2 = ((Component)this).GetComponent<ZSyncAnimation>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.SetTrigger("interact");
				}
				ZNetView component3 = ((Component)component).GetComponent<ZNetView>();
				if ((Object)(object)component3 != (Object)null)
				{
					if (!component3.IsOwner())
					{
						component3.GetZDO().SetOwner(ZDOMan.GetSessionID());
					}
					component3.Destroy();
				}
				else
				{
					Object.Destroy((Object)(object)((Component)component).gameObject);
				}
				ClearReservationWithoutRelease();
				SetTask("Idle", null);
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private void ExecuteStoreToChest()
		{
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			float value = Plugin.ChestDistance.Value;
			if (IsCloseEnough(_targetObj, value, value))
			{
				Container component = _targetObj.GetComponent<Container>();
				if ((Object)(object)component != (Object)null && component.GetInventory() != null && _heldItemData != null)
				{
					int stack = _heldItemData.m_stack;
					bool flag = component.GetInventory().NrOfItems() == 0;
					string name = _heldItemData.m_shared.m_name;
					string text = Localization.instance.Localize(name).Trim();
					if (!string.IsNullOrEmpty(text))
					{
						text = char.ToUpper(text[0]) + text.Substring(1);
					}
					((Component)component).GetComponent<ZNetView>().ClaimOwnership();
					while (_heldItemData.m_stack > 0)
					{
						ItemData val = _heldItemData.Clone();
						val.m_stack = 1;
						if (component.GetInventory().CanAddItem(val, -1))
						{
							component.GetInventory().AddItem(val);
							ItemData heldItemData = _heldItemData;
							heldItemData.m_stack--;
							continue;
						}
						break;
					}
					if (stack != _heldItemData.m_stack)
					{
						if (flag && Plugin.EnableAutoLabeling.Value)
						{
							ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
							if ((Object)(object)component2 != (Object)null && component2.IsValid())
							{
								component2.GetZDO().Set("text", text);
								Logger.LogInfo((object)("[AssistantAI] Auto-Labeling: Baú batizado como '" + text + "'"));
								string text2 = name.ToLower();
								if (IsWood(text2, _heldItemData.m_shared.m_itemType) || IsMetal(text2, _heldItemData.m_shared.m_itemType) || text2.Contains("stone") || text2.Contains("coal"))
								{
									Collider[] array = Physics.OverlapSphere(((Component)component).transform.position, 2.5f);
									Collider[] array2 = array;
									foreach (Collider val2 in array2)
									{
										Container componentInParent = ((Component)val2).GetComponentInParent<Container>();
										if (!((Object)(object)componentInParent != (Object)null) || !((Object)(object)componentInParent != (Object)(object)component) || componentInParent.GetInventory() == null)
										{
											continue;
										}
										float num = Mathf.Abs(((Component)componentInParent).transform.position.x - ((Component)component).transform.position.x);
										float num2 = Mathf.Abs(((Component)componentInParent).transform.position.z - ((Component)component).transform.position.z);
										if (!(num < 0.5f) || !(num2 < 0.5f) || componentInParent.GetInventory().NrOfItems() != 0)
										{
											continue;
										}
										ZNetView component3 = ((Component)componentInParent).GetComponent<ZNetView>();
										if ((Object)(object)component3 != (Object)null && component3.IsValid())
										{
											string value2 = component3.GetZDO().GetString("text", "");
											if (string.IsNullOrEmpty(value2))
											{
												component3.ClaimOwnership();
												component3.GetZDO().Set("text", text);
											}
										}
									}
								}
							}
						}
						ZSyncAnimation component4 = ((Component)this).GetComponent<ZSyncAnimation>();
						if ((Object)(object)component4 != (Object)null)
						{
							component4.SetTrigger("interact");
						}
						component.SetInUse(true);
						((MonoBehaviour)this).StartCoroutine(CloseChest(component));
					}
					if (_heldItemData.m_stack == 0)
					{
						_heldItemData = null;
						SetTask("Idle", null);
					}
					else
					{
						Logger.LogInfo((object)$"[AssistantAI] O baú encheu, sobrou {_heldItemData.m_stack} {((Object)_heldItemData.m_dropPrefab).name} na mão.");
						_blacklistedObjects[((Component)component).gameObject] = Time.time + 120f;
						SetTask("Idle", null);
					}
					((Component)this).transform.LookAt(((Component)component).transform.position);
				}
				else
				{
					DropHoldingItem();
				}
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private IEnumerator CloseChest(Container chest)
		{
			yield return (object)new WaitForSeconds(1.5f);
			if ((Object)(object)chest != (Object)null)
			{
				chest.SetInUse(false);
			}
		}

		private void DropHoldingItem()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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)
			if (_heldItemData != null && _heldItemData.m_stack > 0)
			{
				ItemDrop.DropItem(_heldItemData, _heldItemData.m_stack, ((Component)this).transform.position + ((Component)this).transform.forward * 1f + Vector3.up * 0.5f, Quaternion.identity);
				_heldItemData = null;
				SetTask("Idle", null);
			}
		}

		private void ExecuteConsolidateFetch()
		{
			float value = Plugin.ChestDistance.Value;
			if (IsCloseEnough(_targetObj, value, value))
			{
				Container component = _targetObj.GetComponent<Container>();
				if ((Object)(object)component != (Object)null && component.GetInventory() != null && _heldItemData != null)
				{
					string name = _heldItemData.m_shared.m_name;
					int num = component.GetInventory().CountItems(name, -1, true);
					if (num > 0)
					{
						int num2 = Mathf.Min(_heldItemData.m_shared.m_maxStackSize, num);
						((Component)component).GetComponent<ZNetView>().ClaimOwnership();
						component.GetInventory().RemoveItem(name, num2, -1, true);
						component.SetInUse(true);
						((MonoBehaviour)this).StartCoroutine(CloseChest(component));
						_heldItemData.m_stack = num2;
						Logger.LogInfo((object)$"[AssistantAI] Saquei {_heldItemData.m_stack} {((Object)_heldItemData.m_dropPrefab).name} para organizar/descontaminar.");
					}
				}
				SetTask("Idle", null);
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private void ExecuteFetchForSmelting()
		{
			float value = Plugin.ChestDistance.Value;
			if (IsCloseEnough(_targetObj, value, value))
			{
				Container component = _targetObj.GetComponent<Container>();
				if ((Object)(object)component != (Object)null && component.GetInventory() != null && _heldItemData != null)
				{
					string name = _heldItemData.m_shared.m_name;
					int num = component.GetInventory().CountItems(name, -1, true);
					int num2 = (name.ToLower().Contains("wood") ? Plugin.LeaveWoodAmount.Value : (name.ToLower().Contains("coal") ? Plugin.LeaveCoalAmount.Value : Plugin.LeaveOreAmount.Value));
					if (num > num2)
					{
						int num3 = Mathf.Min(_heldItemData.m_shared.m_maxStackSize, num - num2);
						((Component)component).GetComponent<ZNetView>().ClaimOwnership();
						component.GetInventory().RemoveItem(name, num3, -1, true);
						component.SetInUse(true);
						((MonoBehaviour)this).StartCoroutine(CloseChest(component));
						ZSyncAnimation component2 = ((Component)this).GetComponent<ZSyncAnimation>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.SetTrigger("interact");
						}
						_heldItemData.m_stack = num3;
						if ((Object)(object)_targetSmelter != (Object)null)
						{
							SetTask("FeedSmelter", _targetSmelter);
							return;
						}
					}
				}
				SetTask("Idle", null);
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private void ExecuteFeedSmelter()
		{
			float value = Plugin.KilnDistance.Value;
			if (IsCloseEnough(_targetObj, value, value))
			{
				Smelter component = _targetObj.GetComponent<Smelter>();
				if (!((Object)(object)component != (Object)null) || _heldItemData == null)
				{
					return;
				}
				ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
				bool flag = (Object)(object)component.m_fuelItem != (Object)null && component.m_fuelItem.m_itemData.m_shared.m_name == _heldItemData.m_shared.m_name;
				string text = (((Object)(object)_heldItemData.m_dropPrefab != (Object)null) ? ((Object)_heldItemData.m_dropPrefab).name : _heldItemData.m_shared.m_name);
				Logger.LogWarning((object)$"[AssistantAI] ExecuteFeedSmelter. isFuel={flag}, prefabName={text}, IsOwner={component2.IsOwner()}");
				if (flag)
				{
					float num = component2.GetZDO().GetFloat("fuel", 0f);
					int num2 = Mathf.FloorToInt((float)component.m_maxFuel - num);
					int num3 = Mathf.Min(num2, _heldItemData.m_stack);
					Logger.LogWarning((object)$"[AssistantAI] Feed FUEL: current={num}, space={num2}, amountToFeed={num3}");
					if (num3 > 0)
					{
						for (int i = 0; i < num3; i++)
						{
							component2.InvokeRPC("AddFuel", Array.Empty<object>());
						}
						ZSyncAnimation component3 = ((Component)this).GetComponent<ZSyncAnimation>();
						if ((Object)(object)component3 != (Object)null)
						{
							component3.SetTrigger("interact");
						}
						ItemData heldItemData = _heldItemData;
						heldItemData.m_stack -= num3;
						if (_heldItemData.m_stack <= 0)
						{
							_heldItemData = null;
							SetTask("Idle", null);
						}
						else
						{
							TryFeedNextSmelterOrDrop();
						}
						return;
					}
				}
				else
				{
					int num4 = component2.GetZDO().GetInt("queued", 0);
					int num5 = component.m_maxOre - num4;
					int num6 = Mathf.Min(num5, _heldItemData.m_stack);
					bool flag2 = false;
					if (component.m_conversion != null)
					{
						foreach (ItemConversion item in component.m_conversion)
						{
							if ((Object)(object)item.m_from != (Object)null && ((Object)((Component)item.m_from).gameObject).name == text)
							{
								flag2 = true;
								break;
							}
						}
					}
					Logger.LogWarning((object)$"[AssistantAI] Feed ORE: queued={num4}, space={num5}, amountToFeed={num6}, isAllowed={flag2}");
					if (num6 > 0)
					{
						if (!flag2)
						{
							Logger.LogWarning((object)("[AssistantAI] ERROR: Smelter " + ((Object)component).name + " DOES NOT ALLOW item " + text + "!"));
							DropHoldingItem();
							SetTask("Idle", null);
							return;
						}
						for (int j = 0; j < num6; j++)
						{
							component2.InvokeRPC("AddOre", new object[1] { text });
						}
						ZSyncAnimation component4 = ((Component)this).GetComponent<ZSyncAnimation>();
						if ((Object)(object)component4 != (Object)null)
						{
							component4.SetTrigger("interact");
						}
						int num7 = component2.GetZDO().GetInt("queued", 0);
						Logger.LogWarning((object)$"[AssistantAI] Queued BEFORE: {num4}, AFTER ZDO: {num7}");
						ItemData heldItemData2 = _heldItemData;
						heldItemData2.m_stack -= num6;
						if (_heldItemData.m_stack <= 0)
						{
							_heldItemData = null;
							SetTask("Idle", null);
						}
						else
						{
							TryFeedNextSmelterOrDrop();
						}
						return;
					}
				}
				if ((Object)(object)_targetObj != (Object)null)
				{
					_blacklistedObjects[_targetObj] = Time.time + 60f;
				}
				TryFeedNextSmelterOrDrop();
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}

		private void TryFeedNextSmelterOrDrop()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (_heldItemData == null || _heldItemData.m_stack <= 0)
			{
				SetTask("Idle", null);
				return;
			}
			GameObject val = FindNextSmelterForHeldItem();
			if ((Object)(object)val != (Object)null)
			{
				if (_reservedZDOID != ZDOID.None)
				{
					ReservedItems.Remove(_reservedZDOID);
				}
				_targetSmelter = val;
				_reservedZDOID = val.GetComponent<ZNetView>().GetZDO().m_uid;
				ReservedItems.Add(_reservedZDOID);
				SetTask("FeedSmelter", val);
			}
			else
			{
				DropHoldingItem();
			}
		}

		private GameObject FindNextSmelterForHeldItem()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			if (_heldItemData == null)
			{
				return null;
			}
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, Plugin.WorkRadius.Value, LayerMask.GetMask(new string[1] { "piece" }));
			GameObject result = null;
			float num = float.MaxValue;
			string text = (((Object)(object)_heldItemData.m_dropPrefab != (Object)null) ? ((Object)_heldItemData.m_dropPrefab).name : _heldItemData.m_shared.m_name);
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				Smelter componentInParent = ((Component)val).GetComponentInParent<Smelter>();
				if (!((Object)(object)componentInParent != (Object)null))
				{
					continue;
				}
				ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid())
				{
					continue;
				}
				ZDOID uid = component.GetZDO().m_uid;
				if ((ReservedItems.Contains(uid) && _reservedZDOID != uid) || (_blacklistedObjects.ContainsKey(((Component)componentInParent).gameObject) && Time.time < _blacklistedObjects[((Component)componentInParent).gameObject]))
				{
					continue;
				}
				bool flag = (Object)(object)componentInParent.m_fuelItem != (Object)null && componentInParent.m_fuelItem.m_itemData.m_shared.m_name == _heldItemData.m_shared.m_name;
				bool flag2 = false;
				if (!flag && componentInParent.m_conversion != null)
				{
					foreach (ItemConversion item in componentInParent.m_conversion)
					{
						if ((Object)(object)item.m_from != (Object)null && ((Object)((Component)item.m_from).gameObject).name == text)
						{
							flag2 = true;
							break;
						}
					}
				}
				if (flag)
				{
					float num2 = component.GetZDO().GetFloat("fuel", 0f);
					if (num2 < (float)componentInParent.m_maxFuel)
					{
						float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)componentInParent).transform.position);
						if (num3 < num)
						{
							num = num3;
							result = ((Component)componentInParent).gameObject;
						}
					}
				}
				else
				{
					if (!flag2)
					{
						continue;
					}
					int num4 = component.GetZDO().GetInt("queued", 0);
					if (num4 < componentInParent.m_maxOre)
					{
						float num5 = Vector3.Distance(((Component)this).transform.position, ((Component)componentInParent).transform.position);
						if (num5 < num)
						{
							num = num5;
							result = ((Component)componentInParent).gameObject;
						}
					}
				}
			}
			return result;
		}

		private bool IsUnderAttack()
		{
			//IL_006e: 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 ((Object)(object)_monsterAI != (Object)null && ((Object)(object)((BaseAI)_monsterAI).GetTargetCreature() != (Object)null || ((BaseAI)_monsterAI).IsAlerted()))
			{
				return true;
			}
			if ((Object)(object)RandEventSystem.instance != (Object)null && RandEventSystem.instance.GetCurrentRandomEvent() != null)
			{
				RandomEvent currentRandomEvent = RandEventSystem.instance.GetCurrentRandomEvent();
				if (Vector3.Distance(((Component)this).transform.position, currentRandomEvent.m_pos) <= 100f)
				{
					return true;
				}
			}
			return false;
		}

		private Container FindInboxChestWithValidItems()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			List<Piece> list = new List<Piece>();
			Piece.GetAllPiecesInRadius(((Component)this).transform.position, Plugin.WorkRadius.Value, list);
			foreach (Piece item in list)
			{
				if (!((Object)item).name.StartsWith("AssistantInboxChest") && !item.m_name.Contains("Caixa de Entrada"))
				{
					continue;
				}
				Container component = ((Component)item).GetComponent<Container>();
				if (!((Object)(object)component != (Object)null) || component.GetInventory().GetAllItems().Count <= 0)
				{
					continue;
				}
				foreach (ItemData allItem in component.GetInventory().GetAllItems())
				{
					if (allItem.m_shared.m_maxStackSize > 1 && HasDestinationChestForItem(allItem.m_shared.m_name))
					{
						return component;
					}
				}
			}
			return null;
		}

		private bool HasDestinationChestForItem(string localizedName)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(localizedName))
			{
				return false;
			}
			List<Piece> list = new List<Piece>();
			Piece.GetAllPiecesInRadius(((Component)this).transform.position, Plugin.WorkRadius.Value, list);
			foreach (Piece item in list)
			{
				if (((Object)item).name.StartsWith("AssistantInboxChest") || item.m_name.Contains("Caixa de Entrada") || ((Object)item).name.Contains("personal"))
				{
					continue;
				}
				Container component = ((Component)item).GetComponent<Container>();
				if (!((Object)(object)component != (Object)null) || component.GetInventory() == null)
				{
					continue;
				}
				Inventory inventory = component.GetInventory();
				if (!inventory.HaveItem(localizedName, true))
				{
					continue;
				}
				bool flag = false;
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (allItem.m_shared.m_name == localizedName && allItem.m_stack < allItem.m_shared.m_maxStackSize)
					{
						flag = true;
						break;
					}
				}
				if (!flag && inventory.GetEmptySlots() > 0)
				{
					flag = true;
				}
				if (!flag)
				{
					continue;
				}
				return true;
			}
			return false;
		}

		private void ExecuteTakeFromInbox()
		{
			float value = Plugin.ChestDistance.Value;
			if (IsCloseEnough(_targetObj, value, value))
			{
				Container component = _targetObj.GetComponent<Container>();
				if ((Object)(object)component != (Object)null && component.GetInventory() != null)
				{
					foreach (ItemData allItem in component.GetInventory().GetAllItems())
					{
						if (allItem.m_shared.m_maxStackSize <= 1 || !HasDestinationChestForItem(allItem.m_shared.m_name))
						{
							continue;
						}
						int num = Mathf.Min(allItem.m_stack, allItem.m_shared.m_maxStackSize);
						if ((Object)(object)allItem.m_dropPrefab == (Object)null)
						{
							continue;
						}
						_heldItemData = allItem.Clone();
						_heldItemData.m_stack = num;
						((Component)component).GetComponent<ZNetView>().ClaimOwnership();
						component.GetInventory().RemoveItem(allItem, num);
						ZSyncAnimation component2 = ((Component)this).GetComponent<ZSyncAnimation>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.SetTrigger("interact");
						}
						component.SetInUse(true);
						((MonoBehaviour)this).StartCoroutine(CloseChest(component));
						ZSFX componentInChildren = _targetObj.GetComponentInChildren<ZSFX>();
						if ((Object)(object)componentInChildren != (Object)null)
						{
							componentInChildren.Play();
						}
						break;
					}
				}
				SetTask("Idle", null);
				FindNewTask();
			}
			else
			{
				_monsterAI.SetFollowTarget(_targetObj);
			}
		}
	}
	public class AssistantBedMarker : MonoBehaviour
	{
		private GameObject _marker;

		private ZNetView _nview;

		private void Start()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			_nview = ((Component)this).GetComponent<ZNetView>();
			GameObject prefab = Cache.GetPrefab<GameObject>("piece_workbench");
			if (!((Object)(object)prefab != (Object)null))
			{
				return;
			}
			CraftingStation component = prefab.GetComponent<CraftingStation>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_areaMarker != (Object)null)
			{
				_marker = Object.Instantiate<GameObject>(component.m_areaMarker, ((Component)this).transform.position, Quaternion.identity, ((Component)this).transform);
				_marker.SetActive(false);
				float value = Plugin.WorkRadius.Value;
				CircleProjector componentInChildren = _marker.GetComponentInChildren<CircleProjector>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.m_radius = value;
					componentInChildren.m_nrOfSegments = Mathf.Max(32, (int)(value * 4f));
				}
			}
		}

		private void Update()
		{
			if ((Object)(object)_marker != (Object)null && (Object)(object)_nview != (Object)null && _nview.IsValid())
			{
				bool flag = _nview.GetZDO().GetBool("AssistantShowRadius", false);
				if (_marker.activeSelf != flag)
				{
					_marker.SetActive(flag);
				}
			}
		}
	}
	public class AssistantSpawner : MonoBehaviour, Hoverable, Interactable
	{
		public enum Profession
		{
			Geral,
			Organizador,
			Ferreiro,
			Reparador
		}

		private ZNetView _nview;

		private GameObject _spawnedNPC;

		private const string ZDO_NPC_ID = "AssistantNPC_ID";

		private ZDOID _cachedNpcId = ZDOID.None;

		private void Awake()
		{
			_nview = ((Component)this).GetComponent<ZNetView>();
			((MonoBehaviour)this).Invoke("TrySpawnNPC", 1f);
		}

		private void TrySpawnNPC()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview == (Object)null || !_nview.IsOwner())
			{
				return;
			}
			ZDOID val = (_cachedNpcId = _nview.GetZDO().GetZDOID("AssistantNPC_ID"));
			if (val == ZDOID.None)
			{
				GameObject prefab = Cache.GetPrefab<GameObject>("BaseAssistantNPC");
				if ((Object)(object)prefab != (Object)null)
				{
					Vector3 val2 = ((Component)this).transform.position + ((Component)this).transform.forward * 1.5f + Vector3.up * 1f;
					_spawnedNPC = Object.Instantiate<GameObject>(prefab, val2, ((Component)this).transform.rotation);
					ZNetView component = _spawnedNPC.GetComponent<ZNetView>();
					if ((Object)(object)component != (Object)null)
					{
						_cachedNpcId = component.GetZDO().m_uid;
						_nview.GetZDO().Set("AssistantNPC_ID", _cachedNpcId);
						component.GetZDO().Set("HomeBedPos", ((Component)this).transform.position);
					}
				}
			}
			else
			{
				ZDO zDO = ZDOMan.instance.GetZDO(val);
				if (zDO != null)
				{
					zDO.Set("HomeBedPos", ((Component)this).transform.position);
				}
			}
			((MonoBehaviour)this).Invoke("UpdateNPCIdentity", 0.5f);
		}

		public string GetAssistantName()
		{
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return "Assistente";
			}
			return _nview.GetZDO().GetString("AssistantName", "Assistente da Base");
		}

		public Profession GetProfession()
		{
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return Profession.Geral;
			}
			return (Profession)_nview.GetZDO().GetInt("AssistantProfession", 0);
		}

		public void CallNPC()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0088: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return;
			}
			ZDOID val = _nview.GetZDO().GetZDOID("AssistantNPC_ID");
			if (val == ZDOID.None)
			{
				val = _cachedNpcId;
			}
			if (!(val != ZDOID.None))
			{
				return;
			}
			Vector3 position = ((Component)this).transform.position + ((Component)this).transform.forward * 3f + Vector3.up * 1f;
			GameObject val2 = ZNetScene.instance.FindInstance(val);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.transform.position = position;
			}
			else
			{
				ZDO zDO = ZDOMan.instance.GetZDO(val);
				if (zDO != null)
				{
					zDO.SetPosition(position);
					ZDOMan.instance.ForceSendZDO(val);
				}
			}
			MessageHud.instance.ShowMessage((MessageType)2, "Assistente Desatolado!", 0, (Sprite)null, false);
		}

		public void ApplyConfigurations()
		{
			if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && _nview.IsOwner())
			{
				UpdateNPCIdentity();
			}
		}

		private void UpdateNPCIdentity()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			ZDOID val = _nview.GetZDO().GetZDOID("AssistantNPC_ID");
			if (val == ZDOID.None)
			{
				val = _cachedNpcId;
			}
			if (!(val != ZDOID.None))
			{
				return;
			}
			GameObject val2 = ZNetScene.instance.FindInstance(val);
			if ((Object)(object)val2 != (Object)null)
			{
				ZNetView component = val2.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.ClaimOwnership();
				}
			}
			ZDO zDO = ZDOMan.instance.GetZDO(val);
			if (zDO != null)
			{
				if (!zDO.IsOwner())
				{
					zDO.SetOwner(ZDOMan.GetSessionID());
				}
				zDO.Set("AssistantName", GetAssistantName());
				zDO.Set("AssistantProfession", (int)GetProfession());
				zDO.Set("AssistantPaused", _nview.GetZDO().GetBool("AssistantPaused", false));
				zDO.Set("TotemID", _nview.GetZDO().m_uid);
			}
		}

		public string GetHoverText()
		{
			string assistantName = GetAssistantName();
			string text = GetProfession().ToString();
			return "Totem do Assistente: <color=yellow>" + assistantName + "</color>\nProfissão: <color=orange>" + text + "</color>\n[<color=yellow><b>E</b></color>] Configurar Totem";
		}

		public string GetHoverName()
		{
			return "Totem do Assistente";
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (hold)
			{
				return false;
			}
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return false;
			}
			long num = _nview.GetZDO().GetLong("creator", 0L);
			long playerID = Player.m_localPlayer.GetPlayerID();
			if (num != 0L && playerID != num && !SynchronizationManager.Instance.PlayerIsAdmin)
			{
				((Character)user).Message((MessageType)2, "<color=red>Acesso Negado:</color> Somente o criador original ou um Administrador podem gerenciar este Assistente.", 0, (Sprite)null);
				return true;
			}
			if ((Object)(object)AssistantUI.instance != (Object)null && !AssistantUI.instance.IsVisible())
			{
				_nview.ClaimOwnership();
				AssistantUI.instance.OpenUI(this);
			}
			return true;
		}

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

		public void OnTotemDestroyed()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return;
			}
			ZDOID val = _nview.GetZDO().GetZDOID("AssistantNPC_ID");
			if (val == ZDOID.None)
			{
				val = _cachedNpcId;
			}
			if (!(val != ZDOID.None))
			{
				return;
			}
			GameObject val2 = ZNetScene.instance.FindInstance(val);
			if ((Object)(object)val2 != (Object)null)
			{
				ZNetView component = val2.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.ClaimOwnership();
					GameObject prefab = Cache.GetPrefab<GameObject>("vfx_corpse_destruction");
					if ((Object)(object)prefab != (Object)null)
					{
						Object.Instantiate<GameObject>(prefab, val2.transform.position, Quaternion.identity);
					}
					component.Destroy();
				}
			}
			else
			{
				ZDO zDO = ZDOMan.instance.GetZDO(val);
				if (zDO != null)
				{
					ZDOMan.instance.DestroyZDO(zDO);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "PlacePiece")]
	public static class Player_PlacePiece_Patch
	{
		public static bool Prefix(Player __instance, Piece piece)
		{
			//IL_006f: 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)
			if ((Object)(object)piece != (Object)null && ((Object)((Component)piece).gameObject).name.Contains("AssistantTotem"))
			{
				int num = 0;
				AssistantSpawner[] array = Object.FindObjectsOfType<AssistantSpawner>();
				AssistantSpawner[] array2 = array;
				foreach (AssistantSpawner assistantSpawner in array2)
				{
					ZNetView component = ((Component)assistantSpawner).GetComponent<ZNetView>();
					if (!((Object)(object)component == (Object)null) && component.GetZDO() != null && Vector3.Distance(((Component)__instance).transform.position, ((Component)assistantSpawner).transform.position) < Plugin.WorkRadius.Value)
					{
						num++;
					}
				}
				if (num >= 3)
				{
					((Character)__instance).Message((MessageType)2, "Limite de 3 Assistentes por base atingido!", 0, (Sprite)null);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(WearNTear), "Destroy")]
	public static class WearNTear_Destroy_Patch
	{
		public static void Prefix(WearNTear __instance)
		{
			AssistantSpawner component = ((Component)__instance).GetComponent<AssistantSpawner>();
			if ((Object)(object)component != (Object)null)
			{
				component.OnTotemDestroyed();
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "Remove")]
	public static class WearNTear_Remove_Patch
	{
		public static void Prefix(WearNTear __instance)
		{
			AssistantSpawner component = ((Component)__instance).GetComponent<AssistantSpawner>();
			if ((Object)(object)component != (Object)null)
			{
				component.OnTotemDestroyed();
			}
		}
	}
	public class AssistantUI : MonoBehaviour
	{
		public static AssistantUI instance;

		private GameObject _uiRoot;

		private InputField _nameInput;

		private int _currentProfIndex = 0;

		private string[] _profNames = new string[4] { "0 - Faz-Tudo (Geral)", "1 - Organizador", "2 - Ferreiro", "3 - Reparador" };

		private Text _profBtnText;

		private Toggle _showRadiusToggle;

		private Toggle _pauseToggle;

		private AssistantSpawner _currentSpawner;

		private void Awake()
		{
			instance = this;
		}

		private void CreateUI()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_007e: 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_00a0: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unk