Decompiled source of RacesOfValheim v1.6.9

plugins/RacesOfValheim.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;
using Valheim.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RacesOfValheim")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RacesOfValheim")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace RacesOfValheim;

public static class AlfarArchon
{
	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	public static class Alfar_Archon_NoWeapons_Patch
	{
		public static bool Prefix(Humanoid __instance, ref bool __result)
		{
			if (Active && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				__result = false;
				return false;
			}
			return true;
		}
	}

	public const string ZdoKey = "Alfar_Archon";

	private static float nextPulse;

	public static bool Active { get; private set; }

	public static float Pool { get; private set; }

	public static float EndsAt { get; private set; }

	public static float StartedAt { get; private set; }

	public static bool IsLocalActive
	{
		get
		{
			if (Active)
			{
				return (Object)(object)Player.m_localPlayer != (Object)null;
			}
			return false;
		}
	}

	public static float FreePowerCooldown => AlfarPowerConfig.ArchonFreePowerCooldown.Value;

	public static bool IsArchon(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		ZNetView component = ((Component)player).GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null && component.IsValid())
		{
			return component.GetZDO().GetInt("Alfar_Archon", 0) == 1;
		}
		return false;
	}

	private static void Publish(Player player, bool on)
	{
		ZNetView component = ((Component)player).GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null && component.IsValid())
		{
			component.GetZDO().Set("Alfar_Archon", on ? 1 : 0);
		}
	}

	public static bool TryActivate(Player player)
	{
		if (Active || (Object)(object)player == (Object)null)
		{
			return false;
		}
		float maxEitr = ((Character)player).GetMaxEitr();
		float eitr = player.GetEitr();
		if (maxEitr <= 0f || eitr < maxEitr * AlfarPowerConfig.ArchonThreshold.Value)
		{
			((Character)player).Message((MessageType)2, ModText.Get("rov_msg_alfar_archon_not_charged"), 0, (Sprite)null, false);
			return false;
		}
		if (!AlfarHeimkall.IsReady(player))
		{
			((Character)player).Message((MessageType)2, ModText.Get("rov_msg_alfar_archon_not_ready"), 0, (Sprite)null, false);
			return false;
		}
		Pool = eitr * AlfarPowerConfig.ArchonPoolPerEitr.Value;
		AlfarEitr.Spend(player, eitr);
		Active = true;
		StartedAt = Time.time;
		EndsAt = Time.time + AlfarPowerConfig.ArchonSeconds.Value;
		AlfarStatusEffects.ShowTimer("archon", AlfarPowerConfig.ArchonSeconds.Value);
		nextPulse = Time.time + AlfarPowerConfig.ArchonPulseInterval.Value;
		Publish(player, on: true);
		Logger.LogInfo((object)$"[Alfar] Sameining on: pool {Pool:0} for {AlfarPowerConfig.ArchonSeconds.Value:0}s.");
		((Character)player).Message((MessageType)2, ModText.Get("rov_msg_alfar_archon_on"), 0, (Sprite)null, false);
		return true;
	}

	public static void Absorb(Player player, HitData hit)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		if (Active && hit != null)
		{
			float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
			hit.m_damage = default(DamageTypes);
			if (!(totalDamage <= 0f))
			{
				Pool -= totalDamage;
			}
		}
	}

	public static void Tick(Player player)
	{
		if (!Active)
		{
			return;
		}
		if ((Object)(object)player == (Object)null || ((Character)player).IsDead())
		{
			Active = false;
			if ((Object)(object)player != (Object)null)
			{
				Publish(player, on: false);
			}
		}
		else if (Pool <= 0f || Time.time >= EndsAt)
		{
			Exit(player, (Pool <= 0f) ? "pool gone" : "time up");
		}
		else if (Time.time >= nextPulse)
		{
			nextPulse = Time.time + AlfarPowerConfig.ArchonPulseInterval.Value;
			if (AlfarPowers.Pulse(player, AlfarPowerConfig.ArchonPulseRadius.Value, AlfarPowerConfig.ArchonPulseDamage.Value))
			{
				FormMelee.RaiseSkill((SkillType)9, 0.1f * AlfarPowerConfig.ArchonPulseInterval.Value);
			}
		}
	}

	public static void Exit(Player player, string reason)
	{
		if (Active)
		{
			Active = false;
			Pool = 0f;
			Publish(player, on: false);
			AlfarStatusEffects.ClearTimer("archon");
			AlfarEitr.Spend(player, player.GetEitr());
			AlfarHeimkall.TryTrigger(player, "Sameining " + reason, force: true);
			((Character)player).Message((MessageType)2, ModText.Get("rov_msg_alfar_archon_off"), 0, (Sprite)null, false);
			Logger.LogInfo((object)("[Alfar] Sameining off (" + reason + ")."));
		}
	}

	public static void ForceClear(Player player)
	{
		Active = false;
		Pool = 0f;
		if ((Object)(object)player != (Object)null)
		{
			Publish(player, on: false);
		}
		AlfarStatusEffects.ClearTimer("archon");
	}
}
public class AlfarChestGlow : MonoBehaviour
{
	public Renderer[] Glows;

	public ParticleSystem Embers;

	public Color GlowColor;

	public bool WoodOnly;

	private Container m_container;

	private Material m_lit;

	private Material m_cold;

	private bool? m_shown;

	private float m_nextCheck;

	private void Awake()
	{
		//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_006d: Expected O, but got Unknown
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		m_container = ((Component)this).GetComponent<Container>();
		if (Glows != null && Glows.Length != 0 && !((Object)(object)Glows[0] == (Object)null))
		{
			m_cold = Glows[0].sharedMaterial;
			m_lit = new Material(m_cold)
			{
				name = ((Object)m_cold).name + "_lit"
			};
			m_lit.color = Color.black;
			m_lit.EnableKeyword("_EMISSION");
			m_lit.SetColor("_EmissionColor", GlowColor);
		}
	}

	private void Update()
	{
		if (Time.time < m_nextCheck)
		{
			return;
		}
		m_nextCheck = Time.time + 1f;
		bool flag = HasWork();
		if (m_shown == flag)
		{
			return;
		}
		m_shown = flag;
		if ((Object)(object)m_lit != (Object)null)
		{
			Renderer[] glows = Glows;
			foreach (Renderer val in glows)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.sharedMaterial = (flag ? m_lit : m_cold);
				}
			}
		}
		if ((Object)(object)Embers != (Object)null)
		{
			if (flag)
			{
				Embers.Play(true);
			}
			else
			{
				Embers.Stop(true, (ParticleSystemStopBehavior)1);
			}
		}
	}

	private bool HasWork()
	{
		Inventory val = (((Object)(object)m_container != (Object)null) ? m_container.GetInventory() : null);
		if (val == null)
		{
			return false;
		}
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem != null && !((Object)(object)allItem.m_dropPrefab == (Object)null))
			{
				string name = ((Object)allItem.m_dropPrefab).name;
				if (WoodOnly ? AlfarDroneAI.IsWood(name) : (name != "AlfarSigil"))
				{
					return true;
				}
			}
		}
		return false;
	}

	private void OnDestroy()
	{
		if ((Object)(object)m_lit != (Object)null)
		{
			Object.Destroy((Object)(object)m_lit);
		}
	}
}
public static class AlfarSigil
{
	public const string PrefabName = "AlfarSigil";

	public const string DisplayName = "$rov_item_alfar_sigil_name";

	public static void Register()
	{
		//IL_0084: 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_009f: Expected O, but got Unknown
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Expected O, but got Unknown
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Expected O, but got Unknown
		GameObject val = PrefabManager.Instance.CreateClonedPrefab("AlfarSigil", "BronzeNails");
		if ((Object)(object)val == (Object)null)
		{
			Logger.LogWarning((object)"[Alfar] Could not clone BronzeNails: no verdigris seal.");
			return;
		}
		ItemDrop component = val.GetComponent<ItemDrop>();
		if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null)
		{
			SharedData shared = component.m_itemData.m_shared;
			shared.m_name = "$rov_item_alfar_sigil_name";
			shared.m_description = "$rov_item_alfar_sigil_desc";
			AlfarConstructs.Tint(val, new Color(0.36f, 0.68f, 0.58f, 1f));
			ItemManager.Instance.AddItem(new CustomItem(val, false));
			ItemManager instance = ItemManager.Instance;
			RecipeConfig val2 = new RecipeConfig();
			val2.Item = "AlfarSigil";
			val2.Amount = 1;
			val2.CraftingStation = CraftingStations.Forge;
			val2.MinStationLevel = 1;
			val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig("BronzeNails", 1, 0, true)
			};
			instance.AddRecipe(new CustomRecipe(val2));
		}
	}
}
public static class AlfarChests
{
	public const string EntryName = "AlfarInngangskista";

	public const string WoodName = "AlfarEldividarkista";

	public static void Register()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		RegisterOne("AlfarInngangskista", "$rov_piece_alfar_inngangskista_name", "$rov_piece_alfar_inngangskista_desc", "$rov_hover_alfar_inngangskista", new Color(0.62f, 0.8f, 1f, 1f), AlfarInputChest.Build, "AlfarInputChest_icon.png");
		RegisterOne("AlfarEldividarkista", "$rov_piece_alfar_eldividarkista_name", "$rov_piece_alfar_eldividarkista_desc", "$rov_hover_alfar_eldividarkista", new Color(0.85f, 0.62f, 0.36f, 1f), AlfarFireChest.Build, "AlfarFireChest_icon.png");
	}

	private static void RegisterOne(string pieceName, string display, string description, string hoverName, Color tint, Func<GameObject, bool> build, string iconResource)
	{
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Expected O, but got Unknown
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Expected O, but got Unknown
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Expected O, but got Unknown
		GameObject prefab = Cache.GetPrefab<GameObject>("piece_chest_wood");
		if ((Object)(object)prefab == (Object)null)
		{
			Logger.LogWarning((object)("[Alfar] No 'piece_chest_wood': the chest " + pieceName + " is not registered."));
			return;
		}
		GameObject val = PrefabManager.Instance.CreateClonedPrefab(pieceName, prefab);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		List<RequirementConfig> list = new List<RequirementConfig>();
		Piece component = prefab.GetComponent<Piece>();
		if ((Object)(object)component != (Object)null && component.m_resources != null)
		{
			Requirement[] resources = component.m_resources;
			foreach (Requirement val2 in resources)
			{
				if (!((Object)(object)val2.m_resItem == (Object)null))
				{
					list.Add(new RequirementConfig(((Object)((Component)val2.m_resItem).gameObject).name, val2.m_amount, 0, true));
				}
			}
		}
		list.Add(new RequirementConfig("GreydwarfEye", AlfarNexusConfig.ChestEyes.Value, 0, true));
		Container component2 = val.GetComponent<Container>();
		if ((Object)(object)component2 != (Object)null)
		{
			component2.m_name = hoverName;
		}
		Piece component3 = val.GetComponent<Piece>();
		if ((Object)(object)component3 == (Object)null)
		{
			Logger.LogWarning((object)("[Alfar] The chest has no Piece: " + pieceName));
			return;
		}
		component3.m_name = display;
		component3.m_description = description;
		Sprite val3 = component3.m_icon;
		if (!build(val))
		{
			AlfarConstructs.Tint(val, tint);
		}
		else
		{
			val3 = IconFrom(iconResource) ?? val3;
		}
		PieceManager.Instance.AddPiece(new CustomPiece(val, false, new PieceConfig
		{
			Name = display,
			Description = description,
			PieceTable = PieceTables.Hammer,
			Category = PieceCategories.Crafting,
			Icon = val3,
			Requirements = list.ToArray()
		}));
		PieceDensityLimit.Register(pieceName, AlfarNexusConfig.NexusRadius.Value, 1, "rov_msg_build_limit_alfar_chest");
		PieceDensityLimit.RegisterGate(pieceName, delegate(Player player, Vector3 position)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (!AlfarRace.IsLocalAlfar())
			{
				if ((Object)(object)player != (Object)null)
				{
					((Character)player).Message((MessageType)2, ModText.Get("rov_msg_alfar_only_alfar"), 0, (Sprite)null, false);
				}
				return false;
			}
			if ((Object)(object)AlfarNexusBehaviour.Covering(position) == (Object)null)
			{
				if ((Object)(object)player != (Object)null)
				{
					((Character)player).Message((MessageType)2, ModText.Get("rov_msg_alfar_chest_needs_nexus"), 0, (Sprite)null, false);
				}
				return false;
			}
			return true;
		});
		AlfarPieces.Extra.Add(pieceName);
	}

	internal static Sprite IconFrom(string resource)
	{
		//IL_002c: 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)
		Texture2D val = PieceLook.LoadTexture(resource);
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
	}
}
public class AlfarStatusCommand : ConsoleCommand
{
	public override string Name => "alfarstatus";

	public override string Help => "[DEBUG] Prints the Alfar's eitr, health, Heimkall timer and passive.";

	public override void Run(string[] args)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			Console.instance.Print("No local player.");
			return;
		}
		string playerRace = AlfarVisuals.GetPlayerRace(localPlayer);
		Print($"race={playerRace}  progression state={BossProgressionManager.GetCurrentProgressionState()}");
		Print($"health={((Character)localPlayer).GetHealth():0}/{((Character)localPlayer).GetMaxHealth():0}  eitr={localPlayer.GetEitr():0.0}/{((Character)localPlayer).GetMaxEitr():0}");
		float num = AlfarHeimkall.Remaining(localPlayer);
		Print("Heimkall: " + ((num <= 0f) ? "READY" : ((num / 60f).ToString("0.0") + " min left")) + "  " + $"(cooldown now {AlfarHeimkall.CooldownSeconds() / 60f:0} min)");
		bool flag = ((Character)localPlayer).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_AlfarStats"));
		Print("passive status effect: " + (flag ? "on" : "OFF"));
	}

	private static void Print(string text)
	{
		Console.instance.Print("[Alfar] " + text);
		Logger.LogInfo((object)("[Alfar] " + text));
	}
}
public class AlfarResetCommand : ConsoleCommand
{
	public override string Name => "alfarreset";

	public override string Help => "[DEBUG] Clears the Alfar's Heimkall timer and every power cooldown.";

	public override void Run(string[] args)
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			AlfarHeimkall.ResetTimer(localPlayer);
			AlfarHeimkall.InvulnerableUntil = 0f;
			AlfarPowers.ResetCooldowns(localPlayer);
			Console.instance.Print("[Alfar] Heimkall timer and power cooldowns cleared.");
		}
	}
}
public class AlfarEitrCommand : ConsoleCommand
{
	public override string Name => "alfareitr";

	public override string Help => "[DEBUG] alfareitr <number|full|0> - sets the Alfr's current eitr.";

	public override void Run(string[] args)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || args.Length == 0)
		{
			Console.instance.Print("alfareitr <number|full|0>");
			return;
		}
		float result;
		if (args[0].ToLower() == "full")
		{
			result = ((Character)localPlayer).GetMaxEitr();
		}
		else if (!float.TryParse(args[0], NumberStyles.Float, CultureInfo.InvariantCulture, out result))
		{
			Console.instance.Print("alfareitr <number|full|0>");
			return;
		}
		result = Mathf.Clamp(result, 0f, ((Character)localPlayer).GetMaxEitr());
		float num = result - localPlayer.GetEitr();
		if (num > 0f)
		{
			((Character)localPlayer).AddEitr(num);
		}
		else if (num < 0f)
		{
			AlfarEitr.Spend(localPlayer, 0f - num);
		}
		Console.instance.Print($"[Alfar] eitr = {localPlayer.GetEitr():0.0}/{((Character)localPlayer).GetMaxEitr():0}");
	}
}
public class AlfarHpCommand : ConsoleCommand
{
	public override string Name => "alfarhp";

	public override string Help => "[DEBUG] alfarhp <number> - sets the current health, to test the lethal-blow case.";

	public override void Run(string[] args)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || args.Length == 0)
		{
			Console.instance.Print("alfarhp <number>");
			return;
		}
		if (!float.TryParse(args[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
		{
			Console.instance.Print("alfarhp <number>");
			return;
		}
		((Character)localPlayer).SetHealth(Mathf.Clamp(result, 1f, ((Character)localPlayer).GetMaxHealth()));
		Console.instance.Print($"[Alfar] health = {((Character)localPlayer).GetHealth():0}/{((Character)localPlayer).GetMaxHealth():0}");
	}
}
public static class AlfarConfig
{
	public const string RaceId = "Alfar";

	public static ConfigEntry<Color> SkinColor;

	public static ConfigEntry<float> HeightScale;

	public static ConfigEntry<float> WidthScale;

	public static ConfigEntry<float> EyeSizeMultiplier;

	public const float EyeSeparation = 0.037f;

	public const float EyeForward = 0.09f;

	public const float EyeHeight = 0.183f;

	public static readonly Vector3 EyeExtent = new Vector3(0.0625f, 0.035f, 0.0225f);

	public const float EyeSlant = 22f;

	public const float EyeWrap = 20f;

	public static ConfigEntry<float> DietMultiplier;

	public static ConfigEntry<float> ShieldRate;

	public static ConfigEntry<float> ConductiveMultiplier;

	public static ConfigEntry<bool> SoftFall;

	public static ConfigEntry<float> FeatherFallSpeed;

	public static ConfigEntry<float> HeimkallMinutes;

	public static ConfigEntry<float> HeimkallMinutesAfterYagluth;

	public static ConfigEntry<float> HeimkallMinutesAfterFader;

	public static ConfigEntry<float> HeimkallInvulnerableSeconds;

	public static void Bind(ConfigFile config)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Expected O, but got Unknown
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Expected O, but got Unknown
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Expected O, but got Unknown
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Expected O, but got Unknown
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Expected O, but got Unknown
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Expected O, but got Unknown
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Expected O, but got Unknown
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Expected O, but got Unknown
		HeimkallMinutes = config.Bind<float>("Alfar - Heimkall", "Cooldown Minutes", 20f, new ConfigDescription("Minutes between two Heimkalls (the lethal-blow teleport to the bed). Inside this wait, a lethal blow kills normally.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
		HeimkallMinutesAfterYagluth = config.Bind<float>("Alfar - Heimkall", "Cooldown Minutes After Yagluth", 15f, new ConfigDescription("The cooldown once Yagluth is defeated.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
		HeimkallMinutesAfterFader = config.Bind<float>("Alfar - Heimkall", "Cooldown Minutes After Fader", 10f, new ConfigDescription("The cooldown once Fader is defeated.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
		HeimkallInvulnerableSeconds = config.Bind<float>("Alfar - Heimkall", "Invulnerable Seconds", 5f, new ConfigDescription("Seconds nothing can hurt the Alfr after arriving.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
		DietMultiplier = config.Bind<float>("Alfar - Eitr", "Diet Multiplier", 1f, new ConfigDescription("Each food adds its native eitr plus min(hp, stamina) times this to the maximum eitr.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()));
		ShieldRate = config.Bind<float>("Alfar - Eitr", "Shield Rate", 1f, new ConfigDescription("Eitr spent per point of damage absorbed (1 = 1:1).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
		ConductiveMultiplier = config.Bind<float>("Alfar - Eitr", "Lightning And Spirit Multiplier", 2f, new ConfigDescription("Lightning and spirit damage cost this many times the shield rate.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
		SoftFall = config.Bind<bool>("Alfar - Eitr", "Soft Fall", true, new ConfigDescription("Falling does no damage, and is slowed, while the Alfr has any eitr.", (AcceptableValueBase)null, Array.Empty<object>()));
		FeatherFallSpeed = config.Bind<float>("Alfar - Eitr", "Feather Fall Speed", 4f, new ConfigDescription("Maximum falling speed (m/s) while the Alfr has eitr. Lower floats more.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
		SkinColor = config.Bind<Color>("Alfar - Look", "Skin Color", new Color(0.86f, 0.88f, 0.88f, 1f), new ConfigDescription("How light the ash-grey skin is. The skin texture itself is made grey; this only sets its brightness.", (AcceptableValueBase)null, Array.Empty<object>()));
		HeightScale = config.Bind<float>("Alfar - Look", "Height Scale", 1.05f, new ConfigDescription("Body height against a normal Viking (1.05 = +5%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.8f, 1.3f), Array.Empty<object>()));
		WidthScale = config.Bind<float>("Alfar - Look", "Width Scale", 0.92f, new ConfigDescription("Body width and depth against a normal Viking (0.92 = 8% thinner).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.7f, 1.2f), Array.Empty<object>()));
		EyeSizeMultiplier = config.Bind<float>("Alfar - Look", "Eye Size Multiplier", 0.8f, new ConfigDescription("Scales the black almond eyes. 0.8 is the default look; raise it for bigger eyes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
	}
}
public static class AlfarConstructs
{
	public class Kind
	{
		public string PrefabName;

		public string Display;

		public string Source;

		public float Health;

		public float HealthFactor;

		public float Scale;
	}

	public class AlfarRefund : MonoBehaviour
	{
		public string Item = "";

		public int Amount;
	}

	[HarmonyPatch(typeof(Character), "OnDeath")]
	public static class Alfar_Refund_Patch
	{
		public static void Postfix(Character __instance)
		{
			//IL_008e: 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_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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			AlfarRefund alfarRefund = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<AlfarRefund>() : null);
			if ((Object)(object)alfarRefund == (Object)null || alfarRefund.Amount <= 0 || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(alfarRefund.Item);
			ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val == (Object)null) && val.m_itemData != null)
			{
				int num = alfarRefund.Amount;
				int num2 = Mathf.Max(1, val.m_itemData.m_shared.m_maxStackSize);
				Vector3 val2 = ((Component)__instance).transform.position + Vector3.up * 0.5f;
				while (num > 0)
				{
					int num3 = Mathf.Min(num, num2);
					ItemData obj = val.m_itemData.Clone();
					obj.m_dropPrefab = itemPrefab;
					ItemDrop.DropItem(obj, num3, val2 + Random.insideUnitSphere * 0.3f, Quaternion.identity);
					num -= num3;
				}
				alfarRefund.Amount = 0;
			}
		}
	}

	public const string Neistvordr = "AlfarNeistvordr";

	public const string Steinvordr = "AlfarSteinvordr";

	public const string Eldingvordr = "AlfarEldingvordr";

	public const string SphereProjectile = "AlfarLightningSphere";

	public const string SphereWeapon = "AlfarSphereAttack";

	public static readonly Kind[] Roster = new Kind[3]
	{
		new Kind
		{
			PrefabName = "AlfarNeistvordr",
			Display = "$rov_creature_alfar_neistvordr_name",
			Source = "Surtling",
			Health = 60f,
			Scale = 1f
		},
		new Kind
		{
			PrefabName = "AlfarSteinvordr",
			Display = "$rov_creature_alfar_steinvordr_name",
			Source = "StoneGolem",
			Health = 0f,
			HealthFactor = 1f,
			Scale = 0.6f
		},
		new Kind
		{
			PrefabName = "AlfarEldingvordr",
			Display = "$rov_creature_alfar_eldingvordr_name",
			Source = "Abomination",
			Health = 0f,
			HealthFactor = 0.5f,
			Scale = 0.4f
		}
	};

	public static Kind Find(string prefabName)
	{
		Kind[] roster = Roster;
		foreach (Kind kind in roster)
		{
			if (kind.PrefabName == prefabName)
			{
				return kind;
			}
		}
		return null;
	}

	public static void Register()
	{
		bool flag = RegisterSphere();
		Kind[] roster = Roster;
		foreach (Kind obj in roster)
		{
			if (obj.PrefabName == "AlfarEldingvordr" && !flag)
			{
				Logger.LogWarning((object)"[Alfar] No lightning sphere: the Eldingvordr keeps the Abomination's melee.");
			}
			RegisterOne(obj, flag);
		}
	}

	private static void RegisterOne(Kind kind, bool sphere)
	{
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		GameObject prefab = Cache.GetPrefab<GameObject>(kind.Source);
		if ((Object)(object)prefab == (Object)null)
		{
			Logger.LogWarning((object)("[Alfar] No '" + kind.Source + "' to build " + kind.Display + " from."));
			return;
		}
		GameObject val = PrefabManager.Instance.CreateClonedPrefab(kind.PrefabName, prefab);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Character component = val.GetComponent<Character>();
		if ((Object)(object)component != (Object)null)
		{
			component.m_name = kind.Display;
			component.m_faction = (Faction)0;
			if (kind.Health > 0f)
			{
				component.m_health = kind.Health;
			}
			else
			{
				component.m_health *= kind.HealthFactor;
			}
			component.m_regenAllHPTime = 0f;
		}
		if (!Mathf.Approximately(kind.Scale, 1f))
		{
			val.transform.localScale = Vector3.one * kind.Scale;
			ZNetView component2 = val.GetComponent<ZNetView>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.m_syncInitialScale = true;
			}
		}
		BaseAI component3 = val.GetComponent<BaseAI>();
		if ((Object)(object)component3 != (Object)null)
		{
			component3.m_randomMoveRange = AlfarNexusConfig.ConstructLeash.Value;
		}
		MonsterAI component4 = val.GetComponent<MonsterAI>();
		if ((Object)(object)component4 != (Object)null)
		{
			component4.m_attackPlayerObjects = false;
			component4.m_alertRange = AlfarNexusConfig.ConstructAlertRange.Value;
			component4.m_maxChaseDistance = AlfarNexusConfig.ConstructAlertRange.Value;
		}
		CharacterDrop[] componentsInChildren = val.GetComponentsInChildren<CharacterDrop>(true);
		foreach (CharacterDrop val2 in componentsInChildren)
		{
			if ((Object)(object)val2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
		}
		if (kind.PrefabName == "AlfarEldingvordr" && sphere)
		{
			GiveSphereWeapon(val);
		}
		if (kind.PrefabName == "AlfarNeistvordr")
		{
			BlueFlames(val);
		}
		else
		{
			Tint(val, new Color(0.85f, 0.52f, 0.2f, 1f));
		}
		val.AddComponent<AlfarMark>().Role = "construct";
		AlfarRefund alfarRefund = val.AddComponent<AlfarRefund>();
		alfarRefund.Item = ((kind.PrefabName == "AlfarNeistvordr") ? "Bronze" : ((kind.PrefabName == "AlfarEldingvordr") ? "Iron" : "BlackMetal"));
		alfarRefund.Amount = ((kind.PrefabName == "AlfarNeistvordr") ? AlfarNexusConfig.NeistMetal.Value : ((kind.PrefabName == "AlfarEldingvordr") ? AlfarNexusConfig.EldingMetal.Value : AlfarNexusConfig.SteinMetal.Value));
		AlfarCreatureShield alfarCreatureShield = val.AddComponent<AlfarCreatureShield>();
		alfarCreatureShield.MaxShield = (((Object)(object)component != (Object)null) ? component.m_health : 0f);
		alfarCreatureShield.Shield = alfarCreatureShield.MaxShield;
		RaisedThrall raisedThrall = val.AddComponent<RaisedThrall>();
		raisedThrall.m_kind = kind.PrefabName;
		raisedThrall.m_commandingRace = "Alfar";
		raisedThrall.m_maxFollowers = -1;
		raisedThrall.m_witherSeconds = AlfarNexusConfig.WitherSeconds.Value;
		raisedThrall.m_homeCheckRange = AlfarNexusConfig.NexusRadius.Value;
		raisedThrall.m_refusalMessage = "$rov_msg_thrall_refusal_alfar";
		PrefabManager.Instance.AddPrefab(val);
		Logger.LogInfo((object)("[Alfar] Registered '" + kind.PrefabName + "' from '" + kind.Source + "'."));
	}

	private static bool RegisterSphere()
	{
		//IL_00ab: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Expected O, but got Unknown
		GameObject prefab = Cache.GetPrefab<GameObject>("DvergerStaffIce_projectile");
		if ((Object)(object)prefab == (Object)null)
		{
			Logger.LogWarning((object)"[Alfar] DvergerStaffIce_projectile not found: no lightning sphere.");
			return false;
		}
		GameObject val = PrefabManager.Instance.CreateClonedPrefab("AlfarLightningSphere", prefab);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		Projectile component = val.GetComponent<Projectile>();
		if ((Object)(object)component == (Object)null)
		{
			return false;
		}
		component.m_gravity = 0f;
		component.m_ttl = 4f;
		component.m_aoe = 3f;
		component.m_aoeSkipWearNTear = true;
		component.m_hitFriendly = false;
		component.m_noDamageFriendly = true;
		component.m_hitOwner = false;
		component.m_statusEffect = "";
		Tint(val, new Color(0.55f, 0.85f, 1f, 1f));
		PrefabManager.Instance.AddPrefab(val);
		GameObject prefab2 = Cache.GetPrefab<GameObject>("Surtling");
		Humanoid val2 = (((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<Humanoid>() : null);
		GameObject val3 = (((Object)(object)val2 != (Object)null && val2.m_defaultItems != null && val2.m_defaultItems.Length != 0) ? val2.m_defaultItems[0] : null);
		if ((Object)(object)val3 == (Object)null)
		{
			Logger.LogWarning((object)"[Alfar] The Surtling's fireball weapon was not found: no sphere weapon.");
			return false;
		}
		GameObject val4 = PrefabManager.Instance.CreateClonedPrefab("AlfarSphereAttack", val3);
		if ((Object)(object)val4 == (Object)null)
		{
			return false;
		}
		ItemDrop component2 = val4.GetComponent<ItemDrop>();
		if ((Object)(object)component2 == (Object)null || component2.m_itemData == null || component2.m_itemData.m_shared == null)
		{
			return false;
		}
		SharedData shared = component2.m_itemData.m_shared;
		shared.m_name = "$rov_item_alfar_sphere_name";
		shared.m_aiAttackInterval = AlfarNexusConfig.SphereIntervalSeconds.Value;
		shared.m_aiAttackRange = AlfarNexusConfig.SphereRange.Value;
		shared.m_aiAttackRangeMin = 4f;
		shared.m_damages = new DamageTypes
		{
			m_lightning = AlfarNexusConfig.SphereDamage.Value
		};
		if (shared.m_attack != null)
		{
			shared.m_attack.m_attackProjectile = val;
			shared.m_attack.m_attackOriginJoint = "r.hand";
		}
		ItemManager.Instance.AddItem(new CustomItem(val4, false));
		return true;
	}

	private static void GiveSphereWeapon(GameObject prefab)
	{
		Humanoid component = prefab.GetComponent<Humanoid>();
		GameObject prefab2 = PrefabManager.Instance.GetPrefab("AlfarSphereAttack");
		if (!((Object)(object)component == (Object)null) && !((Object)(object)prefab2 == (Object)null))
		{
			component.m_defaultItems = (GameObject[])(object)new GameObject[1] { prefab2 };
			component.m_randomWeapon = (GameObject[])(object)new GameObject[0];
			component.m_randomArmor = (GameObject[])(object)new GameObject[0];
			component.m_randomShield = (GameObject[])(object)new GameObject[0];
			component.m_randomSets = (ItemSet[])(object)new ItemSet[0];
		}
	}

	public static void Tint(GameObject prefab, Color color)
	{
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if (val is ParticleSystemRenderer || val is TrailRenderer || val is LineRenderer)
			{
				continue;
			}
			Material[] materials = val.materials;
			Material[] array = materials;
			foreach (Material val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					if (val2.HasProperty("_Color"))
					{
						val2.color = color;
					}
					if (val2.HasProperty("_EmissionColor"))
					{
						val2.SetColor("_EmissionColor", color * 0.08f);
						val2.EnableKeyword("_EMISSION");
					}
				}
			}
			val.materials = materials;
		}
		Light[] componentsInChildren2 = prefab.GetComponentsInChildren<Light>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			componentsInChildren2[i].color = color;
		}
	}

	private static void BlueFlames(GameObject prefab)
	{
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name == "flames_world_BLUE")
			{
				((Component)val).gameObject.SetActive(true);
			}
			else if (((Object)val).name == "flames" || ((Object)val).name == "flames_world" || ((Object)val).name == "flames_world_Purple")
			{
				((Component)val).gameObject.SetActive(false);
			}
		}
		Color color = default(Color);
		((Color)(ref color))..ctor(0.25f, 0.55f, 1f, 1f);
		Light[] componentsInChildren2 = prefab.GetComponentsInChildren<Light>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			componentsInChildren2[i].color = color;
		}
		SkinnedMeshRenderer[] componentsInChildren3 = prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		for (int i = 0; i < componentsInChildren3.Length; i++)
		{
			Renderer val2 = (Renderer)(object)componentsInChildren3[i];
			Material[] materials = val2.materials;
			Material[] array = materials;
			foreach (Material val3 in array)
			{
				if ((Object)(object)val3 != (Object)null && val3.HasProperty("_EmissionColor"))
				{
					val3.SetColor("_EmissionColor", new Color(0.25f, 0.55f, 1f, 1f) * 30f);
				}
			}
			val2.materials = materials;
		}
	}

	public static int CountAlive(Vector3 anchor, string prefabName)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		foreach (RaisedThrall item in RaisedThrall.BoundTo(anchor))
		{
			if ((Object)(object)item != (Object)null && item.Kind == prefabName)
			{
				num++;
			}
		}
		return num;
	}

	public static bool Spawn(Vector3 anchor, string prefabName)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: 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_005b: 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)
		GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefabName) : null);
		if ((Object)(object)val == (Object)null)
		{
			Logger.LogWarning((object)("[Alfar] No '" + prefabName + "' in ZNetScene: it cannot be built."));
			return false;
		}
		Vector3 val2 = SpawnSpot(anchor);
		GameObject val3 = Object.Instantiate<GameObject>(val, val2, Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f));
		RaisedThrall raisedThrall = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<RaisedThrall>() : null);
		if ((Object)(object)raisedThrall != (Object)null)
		{
			raisedThrall.Bind(anchor);
		}
		return (Object)(object)val3 != (Object)null;
	}

	public static Vector3 SpawnSpot(Vector3 centre)
	{
		//IL_005d: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: 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_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		int mask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "vehicle" });
		float num = Random.Range(0f, 360f);
		for (int i = 0; i < 12; i++)
		{
			float num2 = (num + (float)i * 30f) * ((float)Math.PI / 180f);
			Vector3 val = centre + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * 3.5f;
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				val.y = ZoneSystem.instance.GetGroundHeight(val);
			}
			if (!Physics.CheckSphere(val + Vector3.up * 1.5f, 1f, mask))
			{
				return val + Vector3.up * 0.3f;
			}
		}
		Vector3 val2 = centre + new Vector3(0f, 0f, -3.5f);
		if ((Object)(object)ZoneSystem.instance != (Object)null)
		{
			val2.y = ZoneSystem.instance.GetGroundHeight(val2);
		}
		return val2 + Vector3.up * 0.3f;
	}
}
public class AlfarDroneAI : MonoBehaviour
{
	private class Load
	{
		public string Name;

		public int Count;
	}

	private class Job
	{
		public string Kind;

		public ZDOID Target;

		public Vector3 Point;

		public bool Hurry;

		public string Label;

		public ZDOID Claim;
	}

	private class PlantInfo
	{
		public GameObject Sapling;

		public string Item;
	}

	public const string KeyAnchor = "RoV_alfarAnchor";

	public const string KeyOrphanAt = "RoV_alfarOrphanAt";

	public const string KeyLoad = "RoV_alfarLoad";

	public const string KeySource = "RoV_alfarSource";

	public const string KeyTarget = "RoV_alfarTarget";

	public const string KeyStatus = "RoV_alfarStatus";

	public const string KeyDest = "RoV_alfarDest";

	public const string KeySaySeq = "RoV_alfarSaySeq";

	public const string KeySayKey = "RoV_alfarSayKey";

	public const string KeySayItem = "RoV_alfarSayItem";

	public const string KeySayStation = "RoV_alfarSayStation";

	public static readonly List<AlfarDroneAI> All = new List<AlfarDroneAI>();

	public const string KeyFedBy = "RoV_alfarFedBy";

	private const float PlanInterval = 1.5f;

	private const float ArriveDistance = 2.5f;

	private const float CollectRadius = 3.5f;

	private const float JobTimeout = 25f;

	private const float PenaltySeconds = 180f;

	private const float ShortPenaltySeconds = 20f;

	private const float FleeSeconds = 6f;

	private const float WitherSeconds = 30f;

	private const float HomeCheckRange = 25f;

	private const float SpoilPanicSeconds = 12f;

	private const float WaitToMetres = 0.25f;

	private const int PayloadCap = 120;

	private static readonly MethodInfo MoveToMethod = AccessTools.Method(typeof(BaseAI), "MoveTo", new Type[4]
	{
		typeof(float),
		typeof(Vector3),
		typeof(float),
		typeof(bool)
	}, (Type[])null);

	private static readonly FieldInfo AllPiecesField = AccessTools.Field(typeof(Piece), "s_allPieces");

	private static readonly MethodInfo ContainerSaveMethod = AccessTools.Method(typeof(Container), "Save", (Type[])null, (Type[])null);

	private static int s_itemMask = -1;

	public ButlerFamily m_family;

	public bool m_fightsBack;

	public float m_homeDistance = 2.5f;

	public float m_radiusBonus;

	private const float FightRange = 12f;

	private const float FightScanInterval = 1f;

	private const float FightLinger = 5f;

	private float m_nextFightScan;

	private float m_fightUntil;

	private bool m_fighting;

	private ZNetView m_nview;

	private Character m_character;

	private MonsterAI m_ai;

	private readonly object[] m_moveArgs = new object[4];

	private readonly List<Load> m_payload = new List<Load>();

	private readonly Dictionary<ZDOID, float> m_penalties = new Dictionary<ZDOID, float>();

	private readonly Dictionary<ZDOID, float> m_idleSince = new Dictionary<ZDOID, float>();

	private readonly List<ButlerStation> m_stations = new List<ButlerStation>();

	private readonly List<Container> m_chests = new List<Container>();

	private Container m_entry;

	private Container m_wood;

	private readonly List<WearNTear> m_damaged = new List<WearNTear>();

	private Vector3? m_farmSpot;

	private Quaternion m_farmRot;

	private PlantInfo m_farmInfo;

	private float m_farmReadyAt;

	private string m_sortItem;

	private ZDOID m_sortDest;

	private float m_scannedAt = -99f;

	private int m_heardSeq;

	private float m_nextListen;

	private float m_nextKilnCheck;

	private Job m_job;

	private float m_nextPlan;

	private float m_jobDeadline;

	private float m_fleeUntil;

	private string m_status = "";

	private static string s_sigilShared;

	private static string s_sigilFor;

	private static readonly Dictionary<ZDOID, KeyValuePair<AlfarDroneAI, float>> s_claims = new Dictionary<ZDOID, KeyValuePair<AlfarDroneAI, float>>();

	private const float ClaimSeconds = 30f;

	private static readonly Dictionary<string, PlantInfo> s_plants = new Dictionary<string, PlantInfo>();

	private static bool s_plantsBuilt;

	private static float s_pickScanAt = -99f;

	private static readonly List<Pickable> s_pickables = new List<Pickable>();

	private static readonly FieldInfo PickedField = AccessTools.Field(typeof(Pickable), "m_picked");

	private static string[] s_wild;

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

	private const float NowhereRepeatSeconds = 300f;

	private const float KeepRepeatSeconds = 1800f;

	private const float SpeechRange = 40f;

	private static readonly HashSet<string> s_woodFamily = new HashSet<string> { "Wood", "FineWood", "RoundLog", "ElderBark", "YggdrasilWood", "Blackwood" };

	public Vector3? Anchor
	{
		get
		{
			//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_004d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return null;
			}
			Vector3 vec = m_nview.GetZDO().GetVec3("RoV_alfarAnchor", Vector3.zero);
			if (!(vec == Vector3.zero))
			{
				return vec;
			}
			return null;
		}
	}

	public string Status
	{
		get
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return m_status;
			}
			return m_nview.GetZDO().GetString("RoV_alfarStatus", m_status);
		}
	}

	private void Awake()
	{
		m_nview = ((Component)this).GetComponent<ZNetView>();
		m_character = ((Component)this).GetComponent<Character>();
		m_ai = ((Component)this).GetComponent<MonsterAI>();
		All.Add(this);
		ReadPayload();
		if ((Object)(object)m_nview != (Object)null && m_nview.IsValid())
		{
			m_heardSeq = m_nview.GetZDO().GetInt("RoV_alfarSaySeq", 0);
		}
	}

	private void Update()
	{
		if (!(Time.time < m_nextListen))
		{
			m_nextListen = Time.time + 0.5f;
			Listen();
		}
	}

	private void OnDestroy()
	{
		All.Remove(this);
		if ((Object)(object)m_character != (Object)null && m_character.IsDead())
		{
			DropPayload();
		}
	}

	public void Bind(Vector3 anchor)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
		{
			m_nview.GetZDO().Set("RoV_alfarAnchor", anchor);
			if ((Object)(object)m_ai != (Object)null)
			{
				m_ai.MakeTame();
			}
			if ((Object)(object)m_character != (Object)null)
			{
				m_character.SetTamed(true);
			}
		}
	}

	public bool IsBoundTo(Vector3 anchor)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		Vector3? anchor2 = Anchor;
		if (anchor2.HasValue)
		{
			return Vector3.SqrMagnitude(anchor2.Value - anchor) < 0.25f;
		}
		return false;
	}

	private void SetStatus(string text)
	{
		if (!(text == m_status))
		{
			m_status = text;
			if ((Object)(object)m_nview != (Object)null && m_nview.IsValid() && m_nview.IsOwner())
			{
				m_nview.GetZDO().Set("RoV_alfarStatus", text);
			}
		}
	}

	public void NoteDamage()
	{
		if (!m_fightsBack)
		{
			m_fleeUntil = Time.time + 6f;
			m_job = null;
		}
	}

	public bool HandsToVanilla()
	{
		//IL_00de: 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_0108: Unknown result type (might be due to invalid IL or missing references)
		if (!m_fightsBack || (Object)(object)m_ai == (Object)null || (Object)(object)m_character == (Object)null || m_character.IsDead())
		{
			return false;
		}
		if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || !m_nview.IsOwner())
		{
			return false;
		}
		Character val = ((BaseAI)m_ai).GetTargetCreature();
		if ((Object)(object)val != (Object)null && !val.IsDead() && !InFightReach(val))
		{
			m_ai.MakeTame();
			val = null;
		}
		if ((Object)(object)val != (Object)null && !val.IsDead())
		{
			m_fightUntil = Time.time + 5f;
		}
		else if (Time.time >= m_nextFightScan)
		{
			m_nextFightScan = Time.time + 1f;
			Character val2 = BaseAI.FindClosestEnemy(m_character, ((Component)this).transform.position, 12f);
			if ((Object)(object)val2 != (Object)null && Vector3.Distance(((Component)val2).transform.position, ((Component)this).transform.position) <= 12f)
			{
				m_fightUntil = Time.time + 5f;
			}
		}
		if (Time.time >= m_fightUntil)
		{
			if (m_fighting)
			{
				m_fighting = false;
				m_ai.MakeTame();
			}
			return false;
		}
		m_fighting = true;
		m_job = null;
		m_nextPlan = 0f;
		SetStatus("Fighting.");
		return true;
	}

	private bool InFightReach(Character enemy)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		Vector3 position = ((Component)enemy).transform.position;
		if (Vector3.Distance(position, ((Component)this).transform.position) > 24f)
		{
			return false;
		}
		Vector3? anchor = Anchor;
		float num = AlfarNexusConfig.NexusRadius.Value + m_radiusBonus + 12f;
		if (anchor.HasValue)
		{
			return Vector3.Distance(position, anchor.Value) <= num;
		}
		return true;
	}

	public bool Tick(float dt)
	{
		if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || !m_nview.IsOwner())
		{
			return false;
		}
		if ((Object)(object)m_character == (Object)null || m_character.IsDead())
		{
			return false;
		}
		if (TickWither())
		{
			return true;
		}
		if (Time.time < m_fleeUntil)
		{
			SetStatus("Driven off.");
			GoHome(dt);
			return true;
		}
		if (Time.time >= m_nextPlan)
		{
			m_nextPlan = Time.time + 1.5f;
			Plan();
		}
		Execute(dt);
		return true;
	}

	private bool TickWither()
	{
		//IL_009a: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: 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_00f0: Expected O, but got Unknown
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		Vector3? anchor = Anchor;
		if (!anchor.HasValue || (Object)(object)ZNet.instance == (Object)null)
		{
			return false;
		}
		long num = m_nview.GetZDO().GetLong("RoV_alfarOrphanAt", 0L);
		if (num == 0L)
		{
			if (Vector3.SqrMagnitude(((Component)this).transform.position - anchor.Value) > 625f)
			{
				return false;
			}
			if (RaisedThrall.StationStandsAt(anchor.Value))
			{
				return false;
			}
			m_nview.GetZDO().Set("RoV_alfarOrphanAt", ZNet.instance.GetTime().Ticks);
			return false;
		}
		if (RaisedThrall.StationStandsAt(anchor.Value))
		{
			m_nview.GetZDO().Set("RoV_alfarOrphanAt", 0L);
			return false;
		}
		if ((ZNet.instance.GetTime() - new DateTime(num)).TotalSeconds < 30.0)
		{
			return false;
		}
		HitData val = new HitData();
		val.m_damage.m_damage = 1E+10f;
		val.m_hitType = (HitType)0;
		m_character.ApplyDamage(val, true, false, (DamageModifier)0);
		return true;
	}

	private void Plan()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: 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_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_0062: 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_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: 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_0103: Unknown result type (might be due to invalid IL or missing references)
		Vector3? anchor = Anchor;
		if (!anchor.HasValue)
		{
			m_job = null;
			return;
		}
		Scan(anchor.Value);
		ExpirePenalties();
		CheckIdleKiln();
		Job job = (m_farmSpot.HasValue ? ((Time.time < m_farmReadyAt) ? new Job
		{
			Kind = "wait",
			Point = ((Component)this).transform.position,
			Label = "Waiting"
		} : new Job
		{
			Kind = "farm_finish",
			Point = m_farmSpot.Value,
			Label = "Gathering"
		}) : ((m_payload.Count <= 0) ? PlanWork(anchor.Value) : PlanDelivery(anchor.Value)));
		if (job != null && (m_job == null || m_job.Kind != job.Kind || m_job.Target != job.Target))
		{
			m_jobDeadline = Time.time + 25f;
		}
		if (m_job != null && m_job != job)
		{
			Release(m_job.Claim);
		}
		if (job != null)
		{
			Claim(job.Claim);
		}
		m_job = job;
	}

	private Job PlanWork(Vector3 anchor)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		object obj = PlanRescue() ?? PlanCollect() ?? PlanFuel() ?? PlanLoad();
		if (obj == null)
		{
			obj = PlanRepair(anchor) ?? PlanFarm(anchor) ?? PlanSort();
		}
		return (Job)obj;
	}

	private void Scan(Vector3 anchor)
	{
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time - m_scannedAt < 0.75f)
		{
			return;
		}
		m_scannedAt = Time.time;
		m_stations.Clear();
		m_chests.Clear();
		m_damaged.Clear();
		m_entry = null;
		m_wood = null;
		List<Piece> list = ((AllPiecesField != null) ? (AllPiecesField.GetValue(null) as List<Piece>) : null);
		if (list == null)
		{
			return;
		}
		float num = AlfarNexusConfig.NexusRadius.Value + m_radiusBonus;
		float num2 = num * num;
		for (int i = 0; i < list.Count; i++)
		{
			Piece val = list[i];
			if ((Object)(object)val == (Object)null || Vector3.SqrMagnitude(((Component)val).transform.position - anchor) > num2)
			{
				continue;
			}
			ButlerStation butlerStation = ButlerStation.From(((Component)val).gameObject);
			if (butlerStation != null)
			{
				m_stations.Add(butlerStation);
				continue;
			}
			Container component = ((Component)val).GetComponent<Container>();
			if ((Object)(object)component != (Object)null && !IsMarkedOff(component))
			{
				string prefabName = Utils.GetPrefabName(((Component)val).gameObject);
				if (prefabName == "AlfarInngangskista")
				{
					m_entry = component;
				}
				else if (prefabName == "AlfarEldividarkista")
				{
					m_wood = component;
				}
				else
				{
					m_chests.Add(component);
				}
			}
			WearNTear component2 = ((Component)val).GetComponent<WearNTear>();
			if ((Object)(object)component2 != (Object)null && component2.GetHealthPercentage() < 0.999f)
			{
				m_damaged.Add(component2);
			}
		}
	}

	private static bool IsMarkedOff(Container container)
	{
		if ((Object)(object)container == (Object)null || container.IsInUse())
		{
			return true;
		}
		Inventory inventory = container.GetInventory();
		if (inventory == null)
		{
			return true;
		}
		string text = SigilSharedName();
		if (!string.IsNullOrEmpty(text))
		{
			return inventory.CountItems(text, -1, true) > 0;
		}
		return false;
	}

	private static string SigilSharedName()
	{
		string text = "AlfarSigil";
		if (s_sigilFor == text)
		{
			return s_sigilShared;
		}
		s_sigilFor = text;
		s_sigilShared = null;
		GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(text) : null);
		ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
		if ((Object)(object)val2 != (Object)null && val2.m_itemData != null && val2.m_itemData.m_shared != null)
		{
			s_sigilShared = val2.m_itemData.m_shared.m_name;
		}
		else
		{
			Logger.LogWarning((object)("[AlfarDrone] No item '" + text + "' to use as the sigil; no chest can be marked until that name is right."));
		}
		return s_sigilShared;
	}

	private Job PlanRescue()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		ButlerStation butlerStation = null;
		float num = 12f;
		foreach (ButlerStation station in m_stations)
		{
			if (station.Alive && !IsPenalised(station.Id) && !ClaimedByOther(station.Id) && station.HasOutput)
			{
				float secondsToSpoil = station.SecondsToSpoil;
				if (!(secondsToSpoil >= num))
				{
					num = secondsToSpoil;
					butlerStation = station;
				}
			}
		}
		if (butlerStation == null)
		{
			return null;
		}
		return new Job
		{
			Kind = "collect",
			Target = butlerStation.Id,
			Claim = butlerStation.Id,
			Point = ApproachPoint(butlerStation),
			Hurry = true,
			Label = "Saving the food"
		};
	}

	private Job PlanCollect()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		ButlerStation butlerStation = null;
		float num = float.MaxValue;
		foreach (ButlerStation station in m_stations)
		{
			if (station.Alive && !IsPenalised(station.Id) && !ClaimedByOther(station.Id) && (station.HasOutput || HasDropsNear(station.Position)))
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, station.Position);
				if (!(num2 >= num))
				{
					num = num2;
					butlerStation = station;
				}
			}
		}
		if (butlerStation == null)
		{
			return null;
		}
		return new Job
		{
			Kind = "collect",
			Target = butlerStation.Id,
			Claim = butlerStation.Id,
			Point = ApproachPoint(butlerStation),
			Label = "Collecting"
		};
	}

	private Job PlanLoad()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: 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_0139: 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_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		ButlerStation butlerStation = null;
		string text = null;
		Container val = null;
		float num = float.MaxValue;
		foreach (ButlerStation station in m_stations)
		{
			if (!station.Alive || IsPenalised(station.Id) || ClaimedByOther(station.Id) || !station.Operable || station.FreeSlots <= 0)
			{
				continue;
			}
			Container chest;
			string text2 = FindMaterialFor(station, out chest);
			if (text2 == null)
			{
				m_idleSince.Remove(station.Id);
				continue;
			}
			float num2 = NoteIdle(station.Id);
			float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)chest).transform.position) + Vector3.Distance(((Component)chest).transform.position, station.Position) - num2 * 0.25f;
			if (!(num3 >= num))
			{
				num = num3;
				butlerStation = station;
				text = text2;
				val = chest;
			}
		}
		if (butlerStation == null)
		{
			return null;
		}
		return new Job
		{
			Kind = "load",
			Target = ZdoOf((Component)(object)val),
			Claim = butlerStation.Id,
			Point = ((Component)val).transform.position,
			Label = "Fetching " + text
		};
	}

	private Job PlanFuel()
	{
		//IL_0033: 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_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		Container val = null;
		string text = null;
		float num = float.MaxValue;
		foreach (ButlerStation station in m_stations)
		{
			if (!station.Alive || IsPenalised(station.Id) || ClaimedByOther(station.Id) || !station.Operable || station.FuelWanted <= 0)
			{
				continue;
			}
			string fuelPrefab = station.FuelPrefab;
			if (string.IsNullOrEmpty(fuelPrefab))
			{
				continue;
			}
			Container val2 = FindChestWith(fuelPrefab);
			if (!((Object)(object)val2 == (Object)null))
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position) + Vector3.Distance(((Component)val2).transform.position, station.Position);
				if (!(num2 >= num))
				{
					num = num2;
					val = val2;
					text = fuelPrefab;
				}
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		return new Job
		{
			Kind = "fuel",
			Target = ZdoOf((Component)(object)val),
			Point = ((Component)val).transform.position,
			Label = "Fetching " + text
		};
	}

	private Job PlanDelivery(Vector3 anchor)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: 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_00d6: 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)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: 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_0043: 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_02ab: 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_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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_0074: 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_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: 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_01db: Unknown result type (might be due to invalid IL or missing references)
		ZDOID zDOID = m_nview.GetZDO().GetZDOID("RoV_alfarDest");
		if (zDOID != ZDOID.None)
		{
			Container val = ContainerById(zDOID);
			if ((Object)(object)val != (Object)null && !IsMarkedOff(val) && !IsPenalised(zDOID) && HasRoomFor(val))
			{
				return new Job
				{
					Kind = "deposit",
					Target = zDOID,
					Point = ((Component)val).transform.position,
					Label = "Sorting " + Describe()
				};
			}
			m_nview.GetZDO().Set("RoV_alfarDest", ZDOID.None);
		}
		ZDOID zDOID2 = m_nview.GetZDO().GetZDOID("RoV_alfarTarget");
		if (zDOID2 != ZDOID.None)
		{
			bool flag = IsPenalised(zDOID2);
			ButlerStation butlerStation = StationById(zDOID2);
			if (butlerStation != null && butlerStation.Alive && butlerStation.Operable && AcceptsAnything(butlerStation) && !flag)
			{
				return new Job
				{
					Kind = "deposit_station",
					Target = zDOID2,
					Point = ApproachPoint(butlerStation),
					Label = "Loading " + Describe()
				};
			}
			m_nview.GetZDO().Set("RoV_alfarTarget", ZDOID.None);
			Container val2 = (flag ? ContainerById(m_nview.GetZDO().GetZDOID("RoV_alfarSource")) : null);
			if ((Object)(object)val2 != (Object)null && !IsMarkedOff(val2) && !IsPenalised(ZdoOf((Component)(object)val2)) && HasRoomFor(val2))
			{
				return new Job
				{
					Kind = "deposit",
					Target = ZdoOf((Component)(object)val2),
					Point = ((Component)val2).transform.position,
					Label = "Storing " + Describe()
				};
			}
		}
		Container val3 = ChestForProduct();
		if ((Object)(object)val3 != (Object)null)
		{
			return new Job
			{
				Kind = "deposit",
				Target = ZdoOf((Component)(object)val3),
				Point = ((Component)val3).transform.position,
				Label = "Storing " + Describe()
			};
		}
		ButlerStation butlerStation2 = StationWanting();
		if (butlerStation2 != null)
		{
			return new Job
			{
				Kind = "deposit_station",
				Target = butlerStation2.Id,
				Point = ApproachPoint(butlerStation2),
				Label = "Loading " + Describe()
			};
		}
		return new Job
		{
			Kind = "drop",
			Target = ZDOID.None,
			Point = anchor,
			Label = "Nowhere to put " + Describe()
		};
	}

	private ButlerStation StationWanting()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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)
		ButlerStation result = null;
		float num = float.MaxValue;
		foreach (ButlerStation station in m_stations)
		{
			if (station.Alive && !IsPenalised(station.Id) && !ClaimedByOther(station.Id) && station.Operable && AcceptsAnything(station))
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, station.Position);
				if (!(num2 >= num))
				{
					num = num2;
					result = station;
				}
			}
		}
		return result;
	}

	private void Execute(float dt)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		if (m_job == null)
		{
			SetStatus((m_stations.Count == 0) ? "Nothing to serve." : "Nothing to do.");
			GoHome(dt);
			return;
		}
		SetStatus(m_job.Label);
		if (!MoveToPoint(dt, m_job.Point, 2.5f, m_job.Hurry))
		{
			if (Time.time > m_jobDeadline)
			{
				Penalise(m_job.Target);
				Logger.LogInfo((object)("[AlfarDrone] Could not reach " + m_job.Kind + " target; setting it aside for a few minutes."));
				m_job = null;
				m_nextPlan = 0f;
			}
			return;
		}
		bool flag;
		switch (m_job.Kind)
		{
		case "load":
			flag = DoLoad();
			break;
		case "fuel":
			flag = DoFuel();
			break;
		case "collect":
			flag = DoCollect();
			break;
		case "deposit_station":
			flag = DoDepositStation();
			break;
		case "deposit":
			flag = DoDeposit();
			break;
		case "drop":
			DropPayload();
			flag = true;
			break;
		case "wait":
			flag = true;
			break;
		case "repair":
			flag = DoRepair();
			break;
		case "farm":
			flag = DoFarm();
			break;
		case "farm_finish":
			flag = DoFarmFinish();
			break;
		case "sortfetch":
			flag = DoSortFetch();
			break;
		default:
			flag = true;
			break;
		}
		if (!flag)
		{
			PenaliseShort(m_job.Target);
		}
		m_job = null;
		m_nextPlan = 0f;
	}

	private bool DoLoad()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: 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)
		Container val = ContainerById(m_job.Target);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		ButlerStation butlerStation = null;
		string text = null;
		foreach (ButlerStation station in m_stations)
		{
			if (station.Alive && station.Operable && station.FreeSlots > 0 && !IsPenalised(station.Id))
			{
				string text2 = FirstAccepted(station, val);
				if (text2 != null)
				{
					butlerStation = station;
					text = text2;
					break;
				}
			}
		}
		if (butlerStation == null || text == null)
		{
			return false;
		}
		int num = TakeFrom(val, text, butlerStation.FreeSlots);
		if (num <= 0)
		{
			return false;
		}
		AddToPayload(text, num);
		m_nview.GetZDO().Set("RoV_alfarSource", ZdoOf((Component)(object)val));
		m_nview.GetZDO().Set("RoV_alfarTarget", butlerStation.Id);
		WritePayload();
		return true;
	}

	private bool DoFuel()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		Container val = ContainerById(m_job.Target);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		foreach (ButlerStation station in m_stations)
		{
			if (!station.Alive || !station.Operable || IsPenalised(station.Id))
			{
				continue;
			}
			int fuelWanted = station.FuelWanted;
			string fuelPrefab = station.FuelPrefab;
			if (fuelWanted > 0 && !string.IsNullOrEmpty(fuelPrefab))
			{
				int num = TakeFrom(val, fuelPrefab, fuelWanted);
				if (num > 0)
				{
					AddToPayload(fuelPrefab, num);
					m_nview.GetZDO().Set("RoV_alfarSource", ZdoOf((Component)(object)val));
					m_nview.GetZDO().Set("RoV_alfarTarget", station.Id);
					WritePayload();
					return true;
				}
			}
		}
		return false;
	}

	private bool DoCollect()
	{
		//IL_0007: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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)
		ButlerStation butlerStation = StationById(m_job.Target);
		if (butlerStation == null || !butlerStation.Alive)
		{
			return false;
		}
		bool flag = false;
		for (int i = 0; i < butlerStation.OutputPulls; i++)
		{
			if (!butlerStation.HasOutput)
			{
				break;
			}
			butlerStation.PullOutput(((Component)this).transform.position);
			flag = true;
		}
		int num = PayloadCount();
		SweepDrops(butlerStation.Position);
		bool num2 = PayloadCount() > num;
		if (num2)
		{
			ZDOID zDOID = butlerStation.Nview.GetZDO().GetZDOID("RoV_alfarFedBy");
			m_nview.GetZDO().Set("RoV_alfarSource", zDOID);
			m_nview.GetZDO().Set("RoV_alfarTarget", ZDOID.None);
			WritePayload();
		}
		return num2 || flag;
	}

	private bool DoDepositStation()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		ButlerStation butlerStation = StationById(m_job.Target);
		if (butlerStation == null || !butlerStation.Alive || !butlerStation.Operable)
		{
			return false;
		}
		bool flag = false;
		for (int num = m_payload.Count - 1; num >= 0; num--)
		{
			Load load = m_payload[num];
			while (load.Count > 0 && butlerStation.FreeSlots > 0 && butlerStation.Accepts(load.Name))
			{
				butlerStation.Add(load.Name);
				load.Count--;
				flag = true;
			}
			if (load.Count > 0 && load.Name == butlerStation.FuelPrefab)
			{
				int num2 = butlerStation.FuelWanted;
				while (load.Count > 0 && num2 > 0)
				{
					butlerStation.AddFuel();
					load.Count--;
					num2--;
					flag = true;
				}
			}
			if (load.Count <= 0)
			{
				m_payload.RemoveAt(num);
			}
		}
		if (flag)
		{
			ZDOID zDOID = m_nview.GetZDO().GetZDOID("RoV_alfarSource");
			if (zDOID != ZDOID.None && butlerStation.Nview.IsValid())
			{
				if (!butlerStation.Nview.IsOwner())
				{
					butlerStation.Nview.ClaimOwnership();
				}
				butlerStation.Nview.GetZDO().Set("RoV_alfarFedBy", zDOID);
			}
		}
		if (m_payload.Count == 0)
		{
			m_nview.GetZDO().Set("RoV_alfarTarget", ZDOID.None);
		}
		WritePayload();
		return flag;
	}

	private bool DoDeposit()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		Container val = ContainerById(m_job.Target);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		ZNetView component = ((Component)val).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			return false;
		}
		if (!component.IsOwner())
		{
			component.ClaimOwnership();
		}
		Inventory inventory = val.GetInventory();
		if (inventory == null)
		{
			return false;
		}
		bool flag = false;
		for (int num = m_payload.Count - 1; num >= 0; num--)
		{
			Load load = m_payload[num];
			GameObject val2 = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(load.Name) : null);
			if (!((Object)(object)val2 == (Object)null))
			{
				while (load.Count > 0 && inventory.CanAddItem(val2, 1) && inventory.AddItem(val2, 1))
				{
					load.Count--;
					flag = true;
				}
				if (load.Count <= 0)
				{
					m_payload.RemoveAt(num);
				}
			}
		}
		if (flag && ContainerSaveMethod != null)
		{
			ContainerSaveMethod.Invoke(val, null);
		}
		WritePayload();
		if (m_payload.Count > 0)
		{
			Penalise(m_job.Target);
		}
		else
		{
			m_nview.GetZDO().Set("RoV_alfarDest", ZDOID.None);
		}
		return flag;
	}

	private bool ClaimedByOther(ZDOID id)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (id == ZDOID.None)
		{
			return false;
		}
		if (!s_claims.TryGetValue(id, out var value))
		{
			return false;
		}
		if ((Object)(object)value.Key == (Object)null || Time.time >= value.Value)
		{
			s_claims.Remove(id);
			return false;
		}
		return (Object)(object)value.Key != (Object)(object)this;
	}

	private void Claim(ZDOID id)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		if (id != ZDOID.None)
		{
			s_claims[id] = new KeyValuePair<AlfarDroneAI, float>(this, Time.time + 30f);
		}
	}

	private void Release(ZDOID id)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		if (id != ZDOID.None && s_claims.TryGetValue(id, out var value) && (Object)(object)value.Key == (Object)(object)this)
		{
			s_claims.Remove(id);
		}
	}

	private Job PlanRepair(Vector3 anchor)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_004e: 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_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: 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_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: 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_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		WearNTear val = null;
		AlfarDroneAI alfarDroneAI = null;
		float num = float.MaxValue;
		foreach (WearNTear item in m_damaged)
		{
			if ((Object)(object)item == (Object)null)
			{
				continue;
			}
			ZDOID id = ZdoOf((Component)(object)item);
			if (!IsPenalised(id) && !ClaimedByOther(id))
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)item).transform.position);
				if (!(num2 >= num))
				{
					num = num2;
					val = item;
				}
			}
		}
		foreach (AlfarDroneAI item2 in All)
		{
			if ((Object)(object)item2 == (Object)null || (Object)(object)item2 == (Object)(object)this || (Object)(object)item2.m_character == (Object)null || item2.m_character.IsDead() || item2.m_character.GetHealth() >= item2.m_character.GetMaxHealth() - 0.5f || Vector3.Distance(((Component)item2).transform.position, anchor) > AlfarNexusConfig.NexusRadius.Value)
			{
				continue;
			}
			ZDOID id2 = ZdoOf((Component)(object)item2);
			if (!IsPenalised(id2) && !ClaimedByOther(id2))
			{
				float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)item2).transform.position);
				if (!(num3 >= num))
				{
					num = num3;
					alfarDroneAI = item2;
					val = null;
				}
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			ZDOID val2 = ZdoOf((Component)(object)val);
			return new Job
			{
				Kind = "repair",
				Target = val2,
				Claim = val2,
				Point = ((Component)val).transform.position,
				Label = "Repairing"
			};
		}
		if ((Object)(object)alfarDroneAI != (Object)null)
		{
			ZDOID val3 = ZdoOf((Component)(object)alfarDroneAI);
			return new Job
			{
				Kind = "repair",
				Target = val3,
				Claim = val3,
				Point = ((Component)alfarDroneAI).transform.position,
				Label = "Mending a drone"
			};
		}
		return null;
	}

	private bool DoRepair()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNetScene.instance == (Object)null)
		{
			return false;
		}
		GameObject val = ZNetScene.instance.FindInstance(m_job.Target);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		WearNTear component = val.GetComponent<WearNTear>();
		if ((Object)(object)component != (Object)null)
		{
			return component.Repair();
		}
		Character component2 = val.GetComponent<Character>();
		if ((Object)(object)component2 != (Object)null && !component2.IsDead() && (Object)(object)val.GetComponent<AlfarDroneAI>() != (Object)null)
		{
			component2.Heal(component2.GetMaxHealth(), true);
			return true;
		}
		return false;
	}

	private static void BuildPlants()
	{
		if (s_plantsBuilt || (Object)(object)ZNetScene.instance == (Object)null)
		{
			return;
		}
		s_plantsBuilt = true;
		foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				continue;
			}
			Plant component = prefab.GetComponent<Plant>();
			Piece component2 = prefab.GetComponent<Piece>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || component.m_grownPrefabs == null || component2.m_resources == null || component2.m_resources.Length == 0 || (Object)(object)component2.m_resources[0].m_resItem == (Object)null)
			{
				continue;
			}
			string name = ((Object)((Component)component2.m_resources[0].m_resItem).gameObject).name;
			GameObject[] grownPrefabs = component.m_grownPrefabs;
			foreach (GameObject val in grownPrefabs)
			{
				if ((Object)(object)val != (Object)null && !s_plants.ContainsKey(((Object)val).name))
				{
					s_plants[((Object)val).name] = new PlantInfo
					{
						Sapling = prefab,
						Item = name
					};
				}
			}
		}
		Logger.LogInfo((object)$"[AlfarDrone] {s_plants.Count} replantable crops known.");
	}

	private static void RefreshPickables()
	{
		if (!(Time.time - s_pickScanAt < 4f))
		{
			s_pickScanAt = Time.time;
			s_pickables.Clear();
			s_pickables.AddRange(Object.FindObjectsByType<Pickable>((FindObjectsSortMode)0));
		}
	}

	private static bool IsPicked(Pickable pickable)
	{
		if (PickedField != null)
		{
			return (bool)PickedField.GetValue(pickable);
		}
		return false;
	}

	private static bool Yields(Pickable pickable, string item)
	{
		//IL_004d: 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_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)pickable.m_itemPrefab != (Object)null && ((Object)pickable.m_itemPrefab).name == item)
		{
			return true;
		}
		if (pickable.m_extraDrops != null && pickable.m_extraDrops.m_drops != null)
		{
			foreach (DropData drop in pickable.m_extraDrops.m_drops)
			{
				if ((Object)(object)drop.m_item != (Object)null && ((Object)drop.m_item).name == item)
				{
					return true;
				}
			}
		}
		return false;
	}

	private static bool IsWildTarget(string prefabName)
	{
		if (s_wild == null)
		{
			s_wild = AlfarNexusConfig.WildPickables.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
		}
		string[] array = s_wild;
		foreach (string text in array)
		{
			if (prefabName.IndexOf(text.Trim(), StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
		}
		return false;
	}

	private Job PlanFarm(Vector3 anchor)
	{
		//IL_005e: 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_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: 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_0096: 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_00fc: 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)
		BuildPlants();
		RefreshPickables();
		float value = AlfarNexusConfig.NexusRadius.Value;
		Pickable val = null;
		PlantInfo farmInfo = null;
		float num = float.MaxValue;
		foreach (Pickable s_pickable in s_pickables)
		{
			if ((Object)(object)s_pickable == (Object)null || !((Component)s_pickable).gameObject.activeInHierarchy || Vector3.Distance(((Component)s_pickable).transform.position, anchor) > value || IsPicked(s_pickable))
			{
				continue;
			}
			ZDOID val2 = ZdoOf((Component)(object)s_pickable);
			if (val2 == ZDOID.None || IsPenalised(val2) || ClaimedByOther(val2))
			{
				continue;
			}
			string prefabName = Utils.GetPrefabName(((Component)s_pickable).gameObject);
			PlantInfo value2 = null;
			if (s_pickable.m_respawnTimeMinutes > 0f)
			{
				if (!IsWildTarget(prefabName))
				{
					continue;
				}
			}
			else if (!s_plants.TryGetValue(prefabName, out value2) || !Yields(s_pickable, value2.Item))
			{
				continue;
			}
			float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)s_pickable).transform.position);
			if (!(num2 >= num))
			{
				num = num2;
				val = s_pickable;
				farmInfo = value2;
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		m_farmInfo = farmInfo;
		ZDOID val3 = ZdoOf((Component)(object)val);
		return new Job
		{
			Kind = "farm",
			Target = val3,
			Claim = val3,
			Point = ((Component)val).transform.position,
			Label = "Harvesting"
		};
	}

	private bool DoFarm()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_0089: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNetScene.instance == (Object)null)
		{
			return false;
		}
		GameObject val = ZNetScene.instance.FindInstance(m_job.Target);
		Pickable val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Pickable>() : null);
		if ((Object)(object)val2 == (Object)null || IsPicked(val2))
		{
			return false;
		}
		Character character = m_character;
		Humanoid val3 = (Humanoid)(object)((character is Humanoid) ? character : null);
		if ((Object)(object)val3 == (Object)null)
		{
			return false;
		}
		Vector3 position = ((Component)val2).transform.position;
		Quaternion rotation = ((Component)val2).transform.rotation;
		if (!val2.Interact(val3, false, false))
		{
			return false;
		}
		m_farmSpot = position;
		m_farmRot = rotation;
		m_farmReadyAt = Time.time + 0.8f;
		return true;
	}

	private bool DoFarmFinish()
	{
		//IL_002f: 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_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		Vector3? farmSpot = m_farmSpot;
		PlantInfo farmInfo = m_farmInfo;
		m_farmSpot = null;
		m_farmInfo = null;
		if (!farmSpot.HasValue)
		{
			return false;
		}
		SweepDrops(farmSpot.Value);
		if (farmInfo != null)
		{
			bool flag = false;
			foreach (Load item in m_payload)
			{
				if (item.Name == farmInfo.Item && item.Count > 0)
				{
					item.Count--;
					flag = true;
					break;
				}
			}
			m_payload.RemoveAll((Load l) => l.Count <= 0);
			WritePayload();
			if (flag && (Object)(object)farmInfo.Sapling != (Object)null)
			{
				Object.Instantiate<GameObject>(farmInfo.Sapling, farmSpot.Value, m_farmRot);
			}
			else
			{
				Logger.LogWarning((object)("[AlfarDrone] Harvested a crop but found no '" + farmInfo.Item + "' to put back."));
			}
		}
		m_nview.GetZDO().Set("RoV_alfarSource", ZDOID.None);
		m_nview.GetZDO().Set("RoV_alfarTarget", ZDOID.None);
		return true;
	}

	private bool AnyStationAccepts(string prefabName)
	{
		foreach (ButlerStation station in m_stations)
		{
			if (station.Alive && station.Operable && (station.Accepts(prefabName) || prefabName == station.FuelPrefab))
			{
				return true;
			}
		}
		return false;
	}

	private Container DestinationFor(string prefabName)
	{
		//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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefabName) : null);
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		Container val2 = null;
		foreach (Container chest in m_chests)
		{
			if ((Object)(object)chest == (Object)null || chest.IsInUse())
			{
				continue;
			}
			ZDOID id = ZdoOf((Component)(object)chest);
			if (IsPenalised(id) || ClaimedByOther(id))
			{
				continue;
			}
			Inventory inventory = chest.GetInventory();
			if (inventory == null || !inventory.CanAddItem(val, 1))
			{
				continue;
			}
			if (inventory.GetAllItems().Count == 0)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = chest;
				}
				continue;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem != null && (Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == prefabName)
				{
					return chest;
				}
			}
		}
		return val2;
	}

	private Job PlanSort()
	{
		//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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: 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_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_entry == (Object)null || m_entry.IsInUse())
		{
			return null;
		}
		ZDOID val = ZdoOf((Component)(object)m_entry);
		if (IsPenalised(val))
		{
			return null;
		}
		Inventory inventory = m_entry.GetInventory();
		if (inventory == null)
		{
			return null;
		}
		string text = "AlfarSigil";
		bool flag = false;
		foreach (ItemData allItem in inventory.GetAllItems())
		{
			if (allItem == null || (Object)(object)allItem.m_dropPrefab == (Object)null)
			{
				continue;
			}
			string name = ((Object)allItem.m_dropPrefab).name;
			if (name == text)
			{
				continue;
			}
			if (!IsWood(name) && AnyStationAccepts(name))
			{
				if (!flag)
				{
					flag = Say("rov_msg_alfar_drone_sort_keep", name, 1800f);
				}
				continue;
			}
			Container val2 = DestinationFor(name);
			if ((Object)(object)val2 == (Object)null)
			{
				if (!flag)
				{
					flag = Say("rov_msg_alfar_drone_sort_nowhere", name, 300f);
				}
				continue;
			}
			m_sortItem = name;
			m_sortDest = ZdoOf((Component)(object)val2);
			return new Job
			{
				Kind = "sortfetch",
				Target = val,
				Claim = m_sortDest,
				Point = ((Component)m_entry).transform.position,
				Label = "Sorting " + name
			};
		}
		return null;
	}

	private bool Say(string key, string item, float repeatSeconds, string station = "")
	{
		string key2 = key + "|" + item;
		if (s_nextMention.TryGetValue(key2, out var value) && Time.time < value)
		{
			return false;
		}
		s_nextMention[key2] = Time.time + repeatSeconds;
		ZDO zDO = m_nview.GetZDO();
		zDO.Set("RoV_alfarSayKey", key);
		zDO.Set("RoV_alfarSayItem", item);
		zDO.Set("RoV_alfarS