Decompiled source of HazelStakes v0.1.0

BepInEx/plugins/HazelStakes/HazelStakes.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.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HazelStakes;

public class HazelStake : MonoBehaviour, Hoverable, Interactable
{
	internal const string ProtectionName = "PlayerBase";

	internal const string MarkerName = "AreaMarker";

	internal static readonly HashSet<HazelStake> Placed = new HashSet<HazelStake>();

	private ZNetView _nview;

	private Piece _piece;

	private GameObject _protection;

	private GameObject _marker;

	private CircleProjector _projector;

	private bool _placed;

	internal bool IsPlaced => _placed;

	internal CircleProjector Projector => _projector;

	private void Awake()
	{
		_nview = ((Component)this).GetComponent<ZNetView>();
		_piece = ((Component)this).GetComponent<Piece>();
		Transform obj = ((Component)this).transform.Find("PlayerBase");
		_protection = ((obj != null) ? ((Component)obj).gameObject : null);
		Transform obj2 = ((Component)this).transform.Find("AreaMarker");
		_marker = ((obj2 != null) ? ((Component)obj2).gameObject : null);
		_projector = (Object.op_Implicit((Object)(object)_marker) ? _marker.GetComponent<CircleProjector>() : null);
		ApplyRadius(HazelStakesPlugin.Radius.Value);
	}

	private void Start()
	{
		_placed = Object.op_Implicit((Object)(object)_nview) && _nview.IsValid() && Object.op_Implicit((Object)(object)_piece) && _piece.IsPlacedByPlayer();
		if (_placed)
		{
			if (Object.op_Implicit((Object)(object)_protection))
			{
				_protection.SetActive(true);
			}
			Placed.Add(this);
		}
	}

	private void OnEnable()
	{
		if (_placed)
		{
			Placed.Add(this);
		}
	}

	private void OnDisable()
	{
		if (_placed)
		{
			Placed.Remove(this);
			TerritoryOverlay.Forget(this);
			SetMarker(visible: false);
		}
	}

	private void OnDestroy()
	{
		Placed.Remove(this);
		TerritoryOverlay.Forget(this);
	}

	internal void SetMarker(bool visible)
	{
		if (Object.op_Implicit((Object)(object)_marker) && _marker.activeSelf != visible)
		{
			_marker.SetActive(visible);
		}
	}

	internal void ApplyRadius(float radius)
	{
		ApplyRadius(((Component)this).gameObject, radius);
	}

	internal static void ApplyRadius(GameObject stake, float radius)
	{
		Transform val = stake.transform.Find("PlayerBase");
		SphereCollider val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<SphereCollider>() : null);
		if (Object.op_Implicit((Object)(object)val2))
		{
			val2.radius = radius;
		}
		Transform val3 = stake.transform.Find("AreaMarker");
		CircleProjector val4 = (Object.op_Implicit((Object)(object)val3) ? ((Component)val3).GetComponent<CircleProjector>() : null);
		if (Object.op_Implicit((Object)(object)val4))
		{
			val4.m_radius = radius;
			val4.m_nrOfSegments = HazelStakesPlugin.SegmentsFor(radius);
		}
	}

	public string GetHoverText()
	{
		if (!_placed)
		{
			return "";
		}
		TerritoryOverlay.NoteHover(this);
		string text = (TerritoryOverlay.IsPinned ? "$hazelstake_unpin" : "$hazelstake_pin");
		return Localization.instance.Localize(_piece.m_name + "\n[<color=yellow><b>$KEY_Use</b></color>] " + text);
	}

	public string GetHoverName()
	{
		if (!Object.op_Implicit((Object)(object)_piece))
		{
			return "";
		}
		return _piece.m_name;
	}

	public float GetHoverOffset()
	{
		return 0f;
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		if (hold || !_placed || (Object)(object)user != (Object)(object)Player.m_localPlayer)
		{
			return false;
		}
		TerritoryOverlay.TogglePin(this);
		return false;
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		return false;
	}
}
[HarmonyPatch]
internal static class PlacementPatches
{
	[HarmonyPrefix]
	[HarmonyPatch(typeof(Player), "UpdatePlacement")]
	private static void BeforePlacement(Player __instance, ItemData ___m_rightItem)
	{
		RefreshHeldStack(__instance, ___m_rightItem);
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(Player), "UpdatePlacement")]
	private static void AfterPlacement(Player __instance, ItemData ___m_rightItem)
	{
		RefreshHeldStack(__instance, ___m_rightItem);
	}

	private static void RefreshHeldStack(Player player, ItemData held)
	{
		if ((Object)(object)player != (Object)(object)Player.m_localPlayer || !IsStakeItem(held))
		{
			return;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (held.m_stack > 0 && inventory.ContainsItem(held))
		{
			return;
		}
		((Humanoid)player).UnequipItem(held, false);
		foreach (ItemData allItem in inventory.GetAllItems())
		{
			if (IsStakeItem(allItem) && allItem.m_stack > 0)
			{
				((Humanoid)player).EquipItem(allItem, false);
				break;
			}
		}
	}

	private static bool IsStakeItem(ItemData item)
	{
		if (Object.op_Implicit((Object)(object)item?.m_dropPrefab))
		{
			return ((Object)item.m_dropPrefab).name == "HazelStakeItem";
		}
		return false;
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
	private static void SetupPlacementGhostPostfix(Player __instance, GameObject ___m_placementGhost)
	{
		if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			TerritoryOverlay.SetGhost(Object.op_Implicit((Object)(object)___m_placementGhost) ? ___m_placementGhost.GetComponent<HazelStake>() : null);
		}
	}
}
[BepInPlugin("com.valheim.hazelstakes", "HazelStakes", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class HazelStakesPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.valheim.hazelstakes";

	public const string PluginName = "HazelStakes";

	public const string PluginVersion = "0.1.0";

	internal const string PrefabName = "HazelStake";

	internal const string ItemPrefabName = "HazelStakeItem";

	private const string StakePieceTable = "HazelStakePieces";

	private const string StandInPrefab = "wood_pole2";

	private const string CampfirePrefab = "fire_pit";

	private const string WorkbenchPrefab = "piece_workbench";

	private const string DefaultRecipe = "Wood:2,Feathers:1,LeatherScraps:1,GreydwarfEye:1";

	internal static ManualLogSource Log;

	internal static ConfigEntry<float> Radius;

	internal static ConfigEntry<string> Recipe;

	internal static ConfigEntry<float> OverlayRange;

	internal static ConfigEntry<Color> RingColour;

	internal static ConfigEntry<float> HoverLinger;

	private static GameObject _prefab;

	private static Recipe _itemRecipe;

	private static GameObject _templateRoot;

	private static GameObject _segmentTemplate;

	private static CircleProjector _benchProjector;

	private static readonly List<Material> OwnedMaterials = new List<Material>();

	private static float _segmentsPerMetre = 4f;

	private static bool _tintReported;

	private Harmony _harmony;

	private StakeArtwork _artwork;

	private static readonly string[] ColourProperties = new string[3] { "_Color", "_TintColor", "_BaseColor" };

	private void Awake()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Expected O, but got Unknown
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Expected O, but got Unknown
		//IL_00f4: 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_0140: Expected O, but got Unknown
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "Radius", 25f, new ConfigDescription("Metres around a stake in which natural spawns are blocked. Also the radius of its ring. 25 matches the campfire.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), new object[1] { val }));
		Recipe = ((BaseUnityPlugin)this).Config.Bind<string>("Server", "Recipe", "Wood:2,Feathers:1,LeatherScraps:1,GreydwarfEye:1", new ConfigDescription("Workbench ingredients for one stake: comma-separated 'Item:amount' pairs using vanilla item prefab names. Keep it at least as costly as a campfire (5 stone, 2 wood). An invalid entry leaves the previous recipe in place.", (AcceptableValueBase)null, new object[1] { val }));
		OverlayRange = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "OverlayRange", 64f, new ConfigDescription("Metres from a hovered, pinned, or held stake within which other stakes show their rings. Pinning also ends beyond this distance from the pinned stake.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 256f), new object[1] { val }));
		RingColour = ((BaseUnityPlugin)this).Config.Bind<Color>("Client", "RingColour", new Color(1f, 0.62f, 0.18f, 1f), "Tint of stake rings, so they cannot be confused with the white workbench ring.");
		HoverLinger = ((BaseUnityPlugin)this).Config.Bind<float>("Client", "HoverLinger", 0.5f, new ConfigDescription("Seconds the rings stay on after the crosshair leaves a stake.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
		Radius.SettingChanged += delegate
		{
			ApplyRadius();
		};
		Recipe.SettingChanged += delegate
		{
			ApplyRecipe();
		};
		RingColour.SettingChanged += delegate
		{
			TintOwnedMaterials();
		};
		SynchronizationManager.OnConfigurationSynchronized += delegate
		{
			ApplyRadius();
			ApplyRecipe();
		};
		AddLocalization();
		PrefabManager.OnVanillaPrefabsAvailable += RegisterStake;
		PieceManager.OnPiecesRegistered += ApplyRecipe;
		ItemManager.OnItemsRegistered += ApplyRecipe;
		_harmony = new Harmony("com.valheim.hazelstakes");
		_harmony.PatchAll(typeof(PlacementPatches));
		Log.LogInfo((object)"[HazelStakes] HazelStakes 0.1.0 loaded (Jotunn 2.30.1)");
	}

	private void LateUpdate()
	{
		TerritoryOverlay.Tick();
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= RegisterStake;
		PieceManager.OnPiecesRegistered -= ApplyRecipe;
		ItemManager.OnItemsRegistered -= ApplyRecipe;
		TerritoryOverlay.Reset();
		foreach (Material ownedMaterial in OwnedMaterials)
		{
			if (Object.op_Implicit((Object)(object)ownedMaterial))
			{
				Object.Destroy((Object)(object)ownedMaterial);
			}
		}
		OwnedMaterials.Clear();
		if (Object.op_Implicit((Object)(object)_templateRoot))
		{
			Object.Destroy((Object)(object)_templateRoot);
		}
		_artwork?.Dispose();
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}

	private static void AddLocalization()
	{
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		string text = "English";
		localization.AddTranslation(ref text, new Dictionary<string, string>
		{
			{ "piece_hazelstake", "Hazel stake" },
			{ "piece_hazelstake_description", "A marked hazel pole. No monster rises from the ground within twenty-five paces of it." },
			{ "item_hazelstake", "Hazel stake" },
			{ "item_hazelstake_description", "A marked hazel pole. Equip to plant it and mark your territory." },
			{ "hazelstake_pin", "Pin territory" },
			{ "hazelstake_unpin", "Unpin territory" }
		});
	}

	private void RegisterStake()
	{
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Expected O, but got Unknown
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Expected O, but got Unknown
		//IL_016e: 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_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: Expected O, but got Unknown
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Expected O, but got Unknown
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Expected O, but got Unknown
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Expected O, but got Unknown
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Expected O, but got Unknown
		try
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("fire_pit");
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_workbench");
			GameObject prefab3 = PrefabManager.Instance.GetPrefab("wood_pole2");
			if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)prefab2) || !Object.op_Implicit((Object)(object)prefab3))
			{
				Log.LogError((object)(string.Format("[HazelStakes] vanilla prefab missing ({0}: {1}, ", "fire_pit", Object.op_Implicit((Object)(object)prefab)) + string.Format("{0}: {1}, {2}: {3}); ", "piece_workbench", Object.op_Implicit((Object)(object)prefab2), "wood_pole2", Object.op_Implicit((Object)(object)prefab3)) + "the stake is not registered."));
				return;
			}
			_artwork = StakeArtwork.Load(prefab3);
			if (!TryParseRecipe(Recipe.Value, out var recipe, out var error))
			{
				Log.LogWarning((object)("[HazelStakes] Recipe '" + Recipe.Value + "' is invalid (" + error + "); using 'Wood:2,Feathers:1,LeatherScraps:1,GreydwarfEye:1'."));
				TryParseRecipe("Wood:2,Feathers:1,LeatherScraps:1,GreydwarfEye:1", out recipe, out var _);
			}
			CustomPieceTable val = new CustomPieceTable("HazelStakePieces", new PieceTableConfig
			{
				CanRemovePieces = false
			});
			val.PieceTable.m_hideAdvancedMenu = true;
			if (!PieceManager.Instance.AddPieceTable(val))
			{
				throw new InvalidOperationException("Jotunn rejected the stake piece table");
			}
			CustomItem val2 = new CustomItem("HazelStakeItem", "Hammer", new ItemConfig
			{
				Name = "$item_hazelstake",
				Description = "$item_hazelstake_description",
				CraftingStation = "piece_workbench",
				MinStationLevel = 1,
				Amount = 1,
				StackSize = 50,
				Weight = 1f,
				Requirements = ((IEnumerable<KeyValuePair<string, int>>)recipe).Select((Func<KeyValuePair<string, int>, RequirementConfig>)((KeyValuePair<string, int> r) => new RequirementConfig(r.Key, r.Value, 0, true))).ToArray()
			});
			SharedData shared = val2.ItemDrop.m_itemData.m_shared;
			shared.m_buildPieces = val.PieceTable;
			shared.m_useDurability = false;
			shared.m_maxQuality = 1;
			shared.m_canBeReparied = false;
			_artwork.ApplyItem(val2.ItemPrefab);
			if (!ItemManager.Instance.AddItem(val2))
			{
				throw new InvalidOperationException("Jotunn rejected 'HazelStakeItem'");
			}
			_itemRecipe = val2.Recipe.Recipe;
			PieceConfig val3 = new PieceConfig();
			val3.Name = "$piece_hazelstake";
			val3.Description = "$piece_hazelstake_description";
			val3.PieceTable = "HazelStakePieces";
			val3.Category = PieceCategories.All;
			val3.Usage = new string[1] { PieceUsages.Misc };
			val3.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig("HazelStakeItem", 1, 0, true)
			};
			PieceConfig val4 = val3;
			CustomPiece val5 = new CustomPiece("HazelStake", "wood_pole2", val4);
			if (!Object.op_Implicit((Object)(object)val5.PiecePrefab))
			{
				Log.LogError((object)"[HazelStakes] could not clone 'wood_pole2'; the stake is not registered.");
				return;
			}
			_prefab = val5.PiecePrefab;
			_artwork.Apply(_prefab);
			BuildRingTemplate(prefab2);
			ConfigurePiece(_prefab, prefab);
			AddProtection(_prefab);
			AddMarker(_prefab);
			_prefab.AddComponent<HazelStake>();
			if (!PieceManager.Instance.AddPiece(val5))
			{
				throw new InvalidOperationException("Jotunn rejected 'HazelStake'");
			}
			ReportCampfire(prefab);
			Log.LogInfo((object)("[HazelStakes] registered 'HazelStake' with Hedgerow Stake artwork, " + $"radius {Radius.Value:0.#} m, recipe {FormatRecipe(recipe)}"));
		}
		catch (Exception arg)
		{
			Log.LogError((object)$"[HazelStakes] failed to register the stake: {arg}");
		}
		finally
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterStake;
		}
	}

	private static void ConfigurePiece(GameObject prefab, GameObject campfire)
	{
		//IL_00e6: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		Piece component = prefab.GetComponent<Piece>();
		Piece component2 = campfire.GetComponent<Piece>();
		component.m_craftingStation = null;
		component.m_groundPiece = component2.m_groundPiece;
		component.m_groundOnly = component2.m_groundOnly;
		component.m_cultivatedGroundOnly = component2.m_cultivatedGroundOnly;
		component.m_waterPiece = component2.m_waterPiece;
		component.m_noInWater = component2.m_noInWater;
		component.m_notOnWood = component2.m_notOnWood;
		component.m_notOnTiltingSurface = component2.m_notOnTiltingSurface;
		component.m_inCeilingOnly = component2.m_inCeilingOnly;
		component.m_notOnFloor = component2.m_notOnFloor;
		component.m_onlyInTeleportArea = component2.m_onlyInTeleportArea;
		component.m_allowedInDungeons = component2.m_allowedInDungeons;
		component.m_vegetationGroundOnly = component2.m_vegetationGroundOnly;
		component.m_comfort = 0;
		((StaticTarget)component).m_primaryTarget = false;
		((StaticTarget)component).m_randomTarget = false;
		WearNTear component3 = prefab.GetComponent<WearNTear>();
		WearNTear component4 = campfire.GetComponent<WearNTear>();
		if (Object.op_Implicit((Object)(object)component3) && Object.op_Implicit((Object)(object)component4))
		{
			component3.m_health = component4.m_health;
			component3.m_materialType = component4.m_materialType;
			component3.m_damages = component4.m_damages;
			component3.m_minToolTier = component4.m_minToolTier;
			component3.m_burnable = component4.m_burnable;
			component3.m_ashDamageImmune = component4.m_ashDamageImmune;
			component3.m_ashDamageResist = component4.m_ashDamageResist;
			component3.m_supports = component4.m_supports;
		}
		else
		{
			Log.LogError((object)($"[HazelStakes] WearNTear missing (stake: {Object.op_Implicit((Object)(object)component3)}, campfire: {Object.op_Implicit((Object)(object)component4)}); " + "durability is not at campfire parity."));
		}
		if (Object.op_Implicit((Object)(object)component3))
		{
			component3.m_noRoofWear = false;
		}
		Aoe[] componentsInChildren = prefab.GetComponentsInChildren<Aoe>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
		}
		Log.LogInfo((object)($"[HazelStakes] campfire parity: health {component3?.m_health}, material {component3?.m_materialType}, " + $"groundOnly {component.m_groundOnly}, noInWater {component.m_noInWater}, notOnWood {component.m_notOnWood}, " + $"allowedInDungeons {component.m_allowedInDungeons}, rain wear off, static target off"));
	}

	private static void AddProtection(GameObject prefab)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("PlayerBase");
		val.SetActive(false);
		val.transform.SetParent(prefab.transform, false);
		val.layer = LayerMask.NameToLayer("character_trigger");
		SphereCollider obj = val.AddComponent<SphereCollider>();
		((Collider)obj).isTrigger = true;
		obj.radius = Radius.Value;
		val.AddComponent<EffectArea>().m_type = (Type)4;
	}

	private static void AddMarker(GameObject prefab)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("AreaMarker");
		val.SetActive(false);
		val.transform.SetParent(prefab.transform, false);
		CircleProjector val2 = val.AddComponent<CircleProjector>();
		val2.m_prefab = _segmentTemplate;
		val2.m_radius = Radius.Value;
		val2.m_nrOfSegments = SegmentsFor(Radius.Value);
		val2.m_turns = 1f;
		val2.m_sliceLines = false;
		val2.m_speed = 0f;
		if (Object.op_Implicit((Object)(object)_benchProjector))
		{
			val2.m_mask = _benchProjector.m_mask;
		}
	}

	private static void BuildRingTemplate(GameObject workbench)
	{
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Expected O, but got Unknown
		CraftingStation component = workbench.GetComponent<CraftingStation>();
		_benchProjector = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_areaMarker)) ? component.m_areaMarker.GetComponent<CircleProjector>() : workbench.GetComponentInChildren<CircleProjector>(true));
		if (!Object.op_Implicit((Object)(object)_benchProjector) || !Object.op_Implicit((Object)(object)_benchProjector.m_prefab))
		{
			throw new InvalidOperationException("piece_workbench has no CircleProjector segment to clone");
		}
		float num = ((Object.op_Implicit((Object)(object)component) && component.m_rangeBuild > 0f) ? component.m_rangeBuild : _benchProjector.m_radius);
		if (num > 0f && _benchProjector.m_nrOfSegments > 0)
		{
			_segmentsPerMetre = (float)_benchProjector.m_nrOfSegments / num;
		}
		_templateRoot = new GameObject("HazelStakes_Templates");
		_templateRoot.SetActive(false);
		Object.DontDestroyOnLoad((Object)(object)_templateRoot);
		_segmentTemplate = Object.Instantiate<GameObject>(_benchProjector.m_prefab, _templateRoot.transform);
		((Object)_segmentTemplate).name = "HazelStake_ring_segment";
		Collider[] componentsInChildren = _segmentTemplate.GetComponentsInChildren<Collider>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
		}
		Renderer[] componentsInChildren2 = _segmentTemplate.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer obj in componentsInChildren2)
		{
			Material[] array = ((IEnumerable<Material>)obj.sharedMaterials).Select((Func<Material, Material>)((Material m) => Object.op_Implicit((Object)(object)m) ? new Material(m)
			{
				name = ((Object)m).name + " (HazelStake)"
			} : ((Material)null))).ToArray();
			OwnedMaterials.AddRange(array.Where((Material m) => Object.op_Implicit((Object)(object)m)));
			obj.sharedMaterials = array;
		}
		TintOwnedMaterials();
		Log.LogInfo((object)("[HazelStakes] ring cloned from piece_workbench segment '" + ((Object)_benchProjector.m_prefab).name + "': " + $"{_benchProjector.m_nrOfSegments} segments at {num:0.#} m, " + $"{OwnedMaterials.Count} material(s) copied"));
	}

	private static void TintOwnedMaterials()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		Color value = RingColour.Value;
		foreach (Material ownedMaterial in OwnedMaterials)
		{
			if (!Object.op_Implicit((Object)(object)ownedMaterial))
			{
				continue;
			}
			List<string> list = new List<string>();
			string[] colourProperties = ColourProperties;
			foreach (string text in colourProperties)
			{
				if (ownedMaterial.HasProperty(text))
				{
					float a = ownedMaterial.GetColor(text).a;
					ownedMaterial.SetColor(text, new Color(value.r, value.g, value.b, a * value.a));
					list.Add(text);
				}
			}
			if (ownedMaterial.HasProperty("_EmissionColor"))
			{
				Color color = ownedMaterial.GetColor("_EmissionColor");
				float num = Mathf.Max(color.r, Mathf.Max(color.g, color.b));
				if (num > 0f)
				{
					ownedMaterial.SetColor("_EmissionColor", new Color(value.r, value.g, value.b) * num);
					list.Add("_EmissionColor");
				}
			}
			if (!_tintReported)
			{
				ManualLogSource log = Log;
				string[] obj = new string[6]
				{
					"[HazelStakes] ring material '",
					((Object)ownedMaterial).name,
					"' shader '",
					null,
					null,
					null
				};
				Shader shader = ownedMaterial.shader;
				obj[3] = ((shader != null) ? ((Object)shader).name : null);
				obj[4] = "': ";
				obj[5] = ((list.Count > 0) ? ("tinted " + string.Join(", ", list)) : "no colour property found");
				log.LogInfo((object)string.Concat(obj));
			}
		}
		_tintReported = true;
	}

	private static void ReportCampfire(GameObject campfire)
	{
		//IL_007b: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		Fireplace component = campfire.GetComponent<Fireplace>();
		GameObject[] source = (GameObject[])(object)((!Object.op_Implicit((Object)(object)component)) ? new GameObject[0] : new GameObject[6] { component.m_enabledObject, component.m_enabledObjectLow, component.m_enabledObjectHigh, component.m_fullObject, component.m_halfObject, component.m_emptyObject });
		EffectArea[] componentsInChildren = campfire.GetComponentsInChildren<EffectArea>(true);
		foreach (EffectArea area in componentsInChildren)
		{
			if ((area.m_type & 4) == 0)
			{
				continue;
			}
			Collider component2 = ((Component)area).GetComponent<Collider>();
			SphereCollider val = (SphereCollider)(object)((component2 is SphereCollider) ? component2 : null);
			float num;
			if (val == null)
			{
				if (!Object.op_Implicit((Object)(object)component2))
				{
					num = 0f;
				}
				else
				{
					Bounds bounds = component2.bounds;
					Vector3 extents = ((Bounds)(ref bounds)).extents;
					num = ((Vector3)(ref extents)).magnitude;
				}
			}
			else
			{
				num = val.radius * ((Component)area).transform.lossyScale.x;
			}
			float num2 = num;
			bool flag = Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_playerBaseObject) && ((Component)area).transform.IsChildOf(component.m_playerBaseObject.transform);
			bool flag2 = source.Any((GameObject o) => Object.op_Implicit((Object)(object)o) && ((Component)area).transform.IsChildOf(o.transform));
			Log.LogInfo((object)("[HazelStakes] fire_pit player-base area at '" + PathOf(((Component)area).transform, campfire.transform) + "': " + $"type {area.m_type}, radius {num2:0.##} m, layer {LayerMask.LayerToName(((Component)area).gameObject.layer)}, " + $"under m_playerBaseObject {flag}, under a burning-state object {flag2}"));
		}
	}

	private static string PathOf(Transform t, Transform root)
	{
		List<string> list = new List<string>();
		while (Object.op_Implicit((Object)(object)t) && (Object)(object)t != (Object)(object)root)
		{
			list.Add(((Object)t).name);
			t = t.parent;
		}
		list.Add(((Object)root).name);
		list.Reverse();
		return string.Join("/", list);
	}

	internal static int SegmentsFor(float radius)
	{
		return Mathf.Clamp(Mathf.RoundToInt(radius * _segmentsPerMetre), 8, 400);
	}

	private static void ApplyRadius()
	{
		float value = Radius.Value;
		if (Object.op_Implicit((Object)(object)_prefab))
		{
			HazelStake.ApplyRadius(_prefab, value);
		}
		foreach (HazelStake item in HazelStake.Placed)
		{
			item.ApplyRadius(value);
		}
		if (Object.op_Implicit((Object)(object)TerritoryOverlay.Ghost))
		{
			TerritoryOverlay.Ghost.ApplyRadius(value);
		}
	}

	private static void ApplyRecipe()
	{
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: 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_0113: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)_itemRecipe) || !Object.op_Implicit((Object)(object)ObjectDB.instance) || ObjectDB.instance.m_items.Count == 0)
		{
			return;
		}
		if (!TryParseRecipe(Recipe.Value, out var recipe, out var error))
		{
			Log.LogWarning((object)("[HazelStakes] Recipe '" + Recipe.Value + "' is invalid (" + error + "); keeping the current recipe."));
			return;
		}
		List<Requirement> list = new List<Requirement>();
		foreach (KeyValuePair<string, int> item in recipe)
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Key);
			ItemDrop val = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.LogWarning((object)("[HazelStakes] Recipe item '" + item.Key + "' is not a known item; keeping the current recipe."));
				return;
			}
			list.Add(new Requirement
			{
				m_resItem = val,
				m_amount = item.Value,
				m_recover = true
			});
		}
		_itemRecipe.m_resources = list.ToArray();
		Log.LogInfo((object)("[HazelStakes] workbench recipe applied: " + FormatRecipe(recipe)));
	}

	internal static bool TryParseRecipe(string text, out List<KeyValuePair<string, int>> recipe, out string error)
	{
		recipe = new List<KeyValuePair<string, int>>();
		error = null;
		if (string.IsNullOrWhiteSpace(text))
		{
			error = "empty";
			return false;
		}
		string[] array = text.Split(new char[1] { ',' });
		foreach (string text2 in array)
		{
			string[] array2 = text2.Split(new char[1] { ':' });
			if (array2.Length != 2 || string.IsNullOrWhiteSpace(array2[0]) || !int.TryParse(array2[1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 1 || result > 999)
			{
				error = "'" + text2.Trim() + "' is not 'Item:amount' with an amount from 1 to 999";
				return false;
			}
			recipe.Add(new KeyValuePair<string, int>(array2[0].Trim(), result));
		}
		return true;
	}

	private static string FormatRecipe(IEnumerable<KeyValuePair<string, int>> recipe)
	{
		return string.Join(", ", recipe.Select((KeyValuePair<string, int> r) => $"{r.Value} {r.Key}"));
	}
}
internal sealed class StakeArtwork : IDisposable
{
	private const string PrefabPath = "assets/hazelstakes/generated/hedgerowvisual.prefab";

	private const string IconPath = "assets/hazelstakes/source/hedgerow-icon.png";

	private const string PieceShader = "Custom/Piece";

	private readonly GameObject _visual;

	private readonly Sprite _icon;

	private readonly Material _material;

	private StakeArtwork(GameObject visual, Sprite icon, Material material)
	{
		_visual = visual;
		_icon = icon;
		_material = material;
	}

	internal static StakeArtwork Load(GameObject pole)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Invalid comparison between Unknown and I4
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Invalid comparison between Unknown and I4
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Invalid comparison between Unknown and I4
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Invalid comparison between Unknown and I4
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Invalid comparison between Unknown and I4
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Expected O, but got Unknown
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0296: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
		RuntimePlatform platform = Application.platform;
		string text;
		if ((int)platform <= 2)
		{
			if ((int)platform != 1)
			{
				if ((int)platform == 2)
				{
					goto IL_0035;
				}
				goto IL_003d;
			}
			text = "HazelStakes.Art.hazelstakes-osx";
		}
		else
		{
			if ((int)platform != 13 && (int)platform != 43)
			{
				if ((int)platform == 44)
				{
					goto IL_0035;
				}
				goto IL_003d;
			}
			text = "HazelStakes.Art.hazelstakes-linux";
		}
		goto IL_0057;
		IL_003d:
		throw new PlatformNotSupportedException($"Hazel Stakes artwork supports macOS, Linux and Windows; running on {Application.platform}");
		IL_0057:
		AssetBundle val = null;
		Material val2 = null;
		try
		{
			byte[] array;
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text))
			{
				if (stream == null)
				{
					throw new InvalidOperationException("Missing embedded artwork resource '" + text + "'");
				}
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				array = memoryStream.ToArray();
			}
			val = AssetBundle.LoadFromMemory(array);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Could not load artwork bundle '" + text + "'");
			}
			GameObject obj = val.LoadAsset<GameObject>("assets/hazelstakes/generated/hedgerowvisual.prefab");
			Sprite val3 = val.LoadAsset<Sprite>("assets/hazelstakes/source/hedgerow-icon.png");
			ValidateVisual(obj);
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.texture))
			{
				throw new InvalidOperationException("Artwork bundle has no usable Sprite at 'assets/hazelstakes/source/hedgerow-icon.png'");
			}
			Shader val4 = (from candidate in pole.GetComponentsInChildren<Renderer>(true).SelectMany((Renderer renderer) => renderer.sharedMaterials)
				where Object.op_Implicit((Object)(object)candidate) && Object.op_Implicit((Object)(object)candidate.shader) && ((Object)candidate.shader).name == "Custom/Piece"
				select candidate.shader).FirstOrDefault();
			bool flag = (int)SystemInfo.graphicsDeviceType == 4;
			if (!Object.op_Implicit((Object)(object)val4) && !flag)
			{
				throw new InvalidOperationException("wood_pole2 has no loaded 'Custom/Piece' shader");
			}
			Material sharedMaterial = ((Renderer)obj.GetComponentInChildren<MeshRenderer>(true)).sharedMaterial;
			if (!Object.op_Implicit((Object)(object)sharedMaterial) || !Object.op_Implicit((Object)(object)sharedMaterial.mainTexture))
			{
				throw new InvalidOperationException("Hedgerow material has no colour atlas");
			}
			val2 = new Material(sharedMaterial)
			{
				name = "HazelStake_Hedgerow"
			};
			if (Object.op_Implicit((Object)(object)val4))
			{
				val2.shader = val4;
			}
			val2.SetColor("_EmissionColor", Color.black);
			val2.DisableKeyword("_EMISSION");
			Mesh sharedMesh = obj.GetComponentInChildren<MeshFilter>(true).sharedMesh;
			ManualLogSource log = HazelStakesPlugin.Log;
			string text2 = $"[HazelStakes] artwork platform {Application.platform}, resource '{text}' ";
			object arg = array.Length;
			Shader shader = val2.shader;
			string text3 = $"({arg} bytes), shader '{((shader != null) ? ((Object)shader).name : null)}', headless {flag}, ";
			string text4 = $"mesh '{((Object)sharedMesh).name}' vertices {sharedMesh.vertexCount}, local bounds {sharedMesh.bounds}, ";
			Rect rect = val3.rect;
			object arg2 = ((Rect)(ref rect)).width;
			rect = val3.rect;
			log.LogInfo((object)(text2 + text3 + text4 + $"icon {arg2}x{((Rect)(ref rect)).height}"));
			return new StakeArtwork(obj, val3, val2);
		}
		catch
		{
			if (Object.op_Implicit((Object)(object)val2))
			{
				Object.Destroy((Object)(object)val2);
			}
			throw;
		}
		finally
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				val.Unload(false);
			}
		}
		IL_0035:
		text = "HazelStakes.Art.hazelstakes-windows";
		goto IL_0057;
	}

	private static void ValidateVisual(GameObject visual)
	{
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_013d: 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_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)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)visual) || ((Object)visual).name != "HedgerowVisual")
		{
			throw new InvalidOperationException("Artwork bundle has no HedgerowVisual at 'assets/hazelstakes/generated/hedgerowvisual.prefab'");
		}
		Renderer[] componentsInChildren = visual.GetComponentsInChildren<Renderer>(true);
		MeshFilter[] componentsInChildren2 = visual.GetComponentsInChildren<MeshFilter>(true);
		Collider[] componentsInChildren3 = visual.GetComponentsInChildren<Collider>(true);
		if (componentsInChildren.Length == 1 && componentsInChildren[0] is MeshRenderer && componentsInChildren2.Length == 1 && Object.op_Implicit((Object)(object)componentsInChildren2[0].sharedMesh) && componentsInChildren2[0].sharedMesh.vertexCount != 0 && componentsInChildren[0].sharedMaterials.Length == 1 && componentsInChildren3.Length == 1)
		{
			Collider obj = componentsInChildren3[0];
			BoxCollider val = (BoxCollider)(object)((obj is BoxCollider) ? obj : null);
			if (val != null && !((Object)(object)((Component)val).gameObject == (Object)(object)visual) && !((Collider)val).isTrigger && ((Collider)val).enabled)
			{
				if (visual.GetComponentsInChildren<MonoBehaviour>(true).Length != 0 || visual.GetComponentsInChildren<Rigidbody>(true).Length != 0)
				{
					throw new InvalidOperationException("HedgerowVisual must not contain scripts or rigidbodies");
				}
				if (!visual.activeSelf || !componentsInChildren[0].enabled || !((Component)componentsInChildren[0]).gameObject.activeSelf || !((Component)val).gameObject.activeSelf)
				{
					throw new InvalidOperationException("HedgerowVisual mesh and collider must be active");
				}
				Vector3 val2 = visual.transform.InverseTransformPoint(((Component)val).transform.TransformPoint(val.center - Vector3.up * val.size.y * 0.5f));
				Vector3 val3 = visual.transform.InverseTransformPoint(((Component)val).transform.TransformPoint(val.center + Vector3.up * val.size.y * 0.5f));
				if (Mathf.Abs(val2.y) > 0.001f || Mathf.Abs(val3.y - 1.45f) > 0.001f || val.size.x <= 0f || val.size.z <= 0f)
				{
					throw new InvalidOperationException($"Hedgerow collider must run from ground 0 to 1.45 m; found {val2.y} to {val3.y}");
				}
				return;
			}
		}
		throw new InvalidOperationException("HedgerowVisual must have one mesh, one material and one solid child BoxCollider");
	}

	internal void ApplyItem(GameObject prefab)
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Expected O, but got Unknown
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		if (prefab.activeInHierarchy)
		{
			throw new InvalidOperationException("Item artwork must be applied before activation");
		}
		LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
		}
		Transform[] array = ((IEnumerable)prefab.transform).Cast<Transform>().ToArray();
		for (int i = 0; i < array.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)((Component)array[i]).gameObject);
		}
		Collider[] components = prefab.GetComponents<Collider>();
		for (int i = 0; i < components.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)components[i]);
		}
		GameObject val = new GameObject("attach");
		val.transform.SetParent(prefab.transform, false);
		GameObject val2 = Object.Instantiate<GameObject>(_visual, val.transform, false);
		val2.transform.localPosition = new Vector3(0f, -0.65f, 0f);
		val2.transform.localRotation = Quaternion.identity;
		val2.transform.localScale = Vector3.one;
		int layer = LayerMask.NameToLayer("item");
		array = val2.GetComponentsInChildren<Transform>(true);
		for (int i = 0; i < array.Length; i++)
		{
			((Component)array[i]).gameObject.layer = layer;
		}
		((Renderer)val2.GetComponentInChildren<MeshRenderer>(true)).sharedMaterial = _material;
		prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { _icon };
	}

	internal void Apply(GameObject prefab)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		if (prefab.activeInHierarchy)
		{
			throw new InvalidOperationException("Artwork must be applied before the stake prefab is activated");
		}
		WearNTear component = prefab.GetComponent<WearNTear>();
		Piece component2 = prefab.GetComponent<Piece>();
		if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)prefab.GetComponent<ZNetView>()))
		{
			throw new InvalidOperationException("Stake behavior template is missing Piece, WearNTear or ZNetView");
		}
		int num = LayerMask.NameToLayer("piece");
		if (num < 0)
		{
			throw new InvalidOperationException("Valheim piece layer is unavailable");
		}
		LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
		}
		Transform[] array = ((IEnumerable)prefab.transform).Cast<Transform>().ToArray();
		for (int i = 0; i < array.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)((Component)array[i]).gameObject);
		}
		Renderer[] components = prefab.GetComponents<Renderer>();
		for (int i = 0; i < components.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)components[i]);
		}
		MeshFilter[] components2 = prefab.GetComponents<MeshFilter>();
		for (int i = 0; i < components2.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)components2[i]);
		}
		Collider[] components3 = prefab.GetComponents<Collider>();
		for (int i = 0; i < components3.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)components3[i]);
		}
		GameObject val = Object.Instantiate<GameObject>(_visual, prefab.transform, false);
		((Object)val).name = "HedgerowVisual";
		val.transform.localPosition = Vector3.zero;
		val.transform.localRotation = Quaternion.identity;
		val.transform.localScale = Vector3.one;
		array = val.GetComponentsInChildren<Transform>(true);
		for (int i = 0; i < array.Length; i++)
		{
			((Component)array[i]).gameObject.layer = num;
		}
		((Renderer)val.GetComponentInChildren<MeshRenderer>(true)).sharedMaterial = _material;
		component.m_new = val;
		component.m_worn = val;
		component.m_broken = val;
		component.m_wet = null;
		component.m_snow = null;
		component.m_snowWorn = null;
		component.m_snowBroken = null;
		component.m_nonSolidRenderers.Clear();
		component.m_fragmentRoots = (GameObject[])(object)new GameObject[1] { val };
		component2.m_icon = _icon;
	}

	public void Dispose()
	{
		if (Object.op_Implicit((Object)(object)_material))
		{
			Object.Destroy((Object)(object)_material);
		}
	}
}
internal static class TerritoryOverlay
{
	private static HazelStake _hovered;

	private static float _hoverTime;

	private static HazelStake _pinned;

	private static HazelStake _ghost;

	private static bool _ghostShown;

	private static readonly HashSet<HazelStake> Shown = new HashSet<HazelStake>();

	private static readonly HashSet<HazelStake> Wanted = new HashSet<HazelStake>();

	private static readonly List<HazelStake> Stale = new List<HazelStake>();

	private static readonly List<HazelStake> Drawn = new List<HazelStake>();

	private static readonly List<Vector3> Neighbours = new List<Vector3>();

	private const float EdgeTolerance = 0.05f;

	private static readonly FieldRef<CircleProjector, List<GameObject>> SegmentsOf = AccessTools.FieldRefAccess<CircleProjector, List<GameObject>>("m_segments");

	internal static HazelStake Ghost => _ghost;

	internal static bool IsPinned => Object.op_Implicit((Object)(object)_pinned);

	internal static void NoteHover(HazelStake stake)
	{
		_hovered = stake;
		_hoverTime = Time.time;
	}

	internal static void TogglePin(HazelStake stake)
	{
		_pinned = (Object.op_Implicit((Object)(object)_pinned) ? null : stake);
	}

	internal static void SetGhost(HazelStake ghost)
	{
		if (Object.op_Implicit((Object)(object)_ghost) && (Object)(object)_ghost != (Object)(object)ghost)
		{
			_ghost.SetMarker(visible: false);
		}
		_ghost = ghost;
		_ghostShown = false;
	}

	internal static void Forget(HazelStake stake)
	{
		if ((Object)(object)_hovered == (Object)(object)stake)
		{
			_hovered = null;
		}
		if ((Object)(object)_pinned == (Object)(object)stake)
		{
			_pinned = null;
		}
		if ((Object)(object)_ghost == (Object)(object)stake)
		{
			_ghost = null;
		}
		Shown.Remove(stake);
	}

	internal static void Reset()
	{
		foreach (HazelStake item in Shown)
		{
			if (Object.op_Implicit((Object)(object)item))
			{
				item.SetMarker(visible: false);
			}
		}
		Shown.Clear();
		if (Object.op_Implicit((Object)(object)_ghost))
		{
			_ghost.SetMarker(visible: false);
		}
		_hovered = null;
		_pinned = null;
		_ghost = null;
		_ghostShown = false;
	}

	internal static void Tick()
	{
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: 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_016c: 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_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)localPlayer))
		{
			if (Shown.Count > 0 || Object.op_Implicit((Object)(object)_hovered) || Object.op_Implicit((Object)(object)_pinned) || Object.op_Implicit((Object)(object)_ghost) || _ghostShown)
			{
				Reset();
			}
			return;
		}
		float value = HazelStakesPlugin.OverlayRange.Value;
		float num = value * value;
		if (!Object.op_Implicit((Object)(object)_hovered))
		{
			_hovered = null;
		}
		if (!Object.op_Implicit((Object)(object)_ghost))
		{
			_ghost = null;
		}
		if (!Object.op_Implicit((Object)(object)_pinned))
		{
			_pinned = null;
		}
		if (!Object.op_Implicit((Object)(object)_hovered) || !(Time.time - _hoverTime <= HazelStakesPlugin.HoverLinger.Value))
		{
			_hovered = null;
		}
		if (Object.op_Implicit((Object)(object)_pinned))
		{
			Vector3 val = ((Component)localPlayer).transform.position - ((Component)_pinned).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude > num)
			{
				_pinned = null;
			}
		}
		bool flag = Object.op_Implicit((Object)(object)_ghost) && ((Component)_ghost).gameObject.activeInHierarchy;
		Wanted.Clear();
		if (Object.op_Implicit((Object)(object)_hovered) || Object.op_Implicit((Object)(object)_pinned) || flag)
		{
			foreach (HazelStake item in HazelStake.Placed)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					Vector3 position = ((Component)item).transform.position;
					if ((Object.op_Implicit((Object)(object)_hovered) && Near(_hovered, position, num)) || (Object.op_Implicit((Object)(object)_pinned) && Near(_pinned, position, num)) || (flag && Near(_ghost, position, num)))
					{
						Wanted.Add(item);
					}
				}
			}
		}
		Stale.Clear();
		foreach (HazelStake item2 in Shown)
		{
			if (!Wanted.Contains(item2))
			{
				Stale.Add(item2);
			}
		}
		foreach (HazelStake item3 in Stale)
		{
			if (Object.op_Implicit((Object)(object)item3))
			{
				item3.SetMarker(visible: false);
			}
			Shown.Remove(item3);
		}
		foreach (HazelStake item4 in Wanted)
		{
			if (Shown.Add(item4))
			{
				item4.SetMarker(visible: true);
			}
		}
		if (Object.op_Implicit((Object)(object)_ghost) && flag != _ghostShown)
		{
			_ghost.SetMarker(flag);
			_ghostShown = flag;
		}
		TrimToOutline(HazelStakesPlugin.Radius.Value);
	}

	private static void TrimToOutline(float radius)
	{
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: 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_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		Drawn.Clear();
		foreach (HazelStake item in Shown)
		{
			if (Object.op_Implicit((Object)(object)item))
			{
				Drawn.Add(item);
			}
		}
		if (Object.op_Implicit((Object)(object)_ghost) && _ghostShown)
		{
			Drawn.Add(_ghost);
		}
		if (Drawn.Count == 0)
		{
			return;
		}
		float num = Mathf.Max(0f, radius - 0.05f);
		float num2 = num * num;
		float num3 = 4f * radius * radius;
		foreach (HazelStake item2 in Drawn)
		{
			CircleProjector projector = item2.Projector;
			List<GameObject> list = (Object.op_Implicit((Object)(object)projector) ? SegmentsOf.Invoke(projector) : null);
			if (list == null)
			{
				continue;
			}
			Vector3 position = ((Component)item2).transform.position;
			Neighbours.Clear();
			foreach (HazelStake item3 in Drawn)
			{
				if (!((Object)(object)item3 == (Object)(object)item2))
				{
					Vector3 position2 = ((Component)item3).transform.position;
					if (FlatSqr(position2, position) < num3)
					{
						Neighbours.Add(position2);
					}
				}
			}
			foreach (GameObject item4 in list)
			{
				if (!Object.op_Implicit((Object)(object)item4))
				{
					continue;
				}
				bool flag = true;
				Vector3 position3 = item4.transform.position;
				foreach (Vector3 neighbour in Neighbours)
				{
					if (FlatSqr(neighbour, position3) < num2)
					{
						flag = false;
						break;
					}
				}
				if (item4.activeSelf != flag)
				{
					item4.SetActive(flag);
				}
			}
		}
	}

	private static float FlatSqr(Vector3 a, Vector3 b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		float num = a.x - b.x;
		float num2 = a.z - b.z;
		return num * num + num2 * num2;
	}

	private static bool Near(HazelStake anchor, Vector3 position, float rangeSqr)
	{
		//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_0011: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = ((Component)anchor).transform.position - position;
		return ((Vector3)(ref val)).sqrMagnitude <= rangeSqr;
	}
}
internal static class ModBuildVersion
{
	internal const string Value = "0.1.0";
}