Decompiled source of WardsPlus v1.0.0

plugins/WardsPlus.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using WardsPlus.Components;
using WardsPlus.Config;
using WardsPlus.Pieces;
using WardsPlus.UI;
using WardsPlus.Util;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WardsPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ffc2e54edd5e0549e7dfd11227973991777332e0")]
[assembly: AssemblyProduct("WardsPlus")]
[assembly: AssemblyTitle("WardsPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WardsPlus
{
	[BepInPlugin("visteus.wardsplus", "WardsPlus", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("visteus.wardsplus");

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginConfig.Bind(((BaseUnityPlugin)this).Config);
			Translations.Load();
			WardPieces.Init();
			PluginConfig.RememberPanelPosition.SettingChanged += delegate
			{
				WardPanel.OnRememberPositionChanged();
			};
			_harmony.PatchAll();
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}
	}
	internal static class ModInfo
	{
		public const string Guid = "visteus.wardsplus";

		public const string Name = "WardsPlus";

		public const string Author = "Visteus";

		public const string Version = "1.0.0";
	}
}
namespace WardsPlus.Util
{
	internal static class DebugLog
	{
		private static readonly Dictionary<string, float> s_lastWrite = new Dictionary<string, float>();

		private static Dictionary<int, string> s_keyNames;

		public static bool Enabled
		{
			get
			{
				if (PluginConfig.DebugLogging != null)
				{
					return PluginConfig.DebugLogging.Value;
				}
				return false;
			}
		}

		public static void Write(string message)
		{
			if (Enabled)
			{
				Plugin.Log.LogInfo((object)("[debug] " + message));
			}
		}

		public static void WriteThrottled(string key, float seconds, string message)
		{
			if (Enabled)
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (!s_lastWrite.TryGetValue(key, out var value) || !(realtimeSinceStartup - value < seconds))
				{
					s_lastWrite[key] = realtimeSinceStartup;
					Write(message);
				}
			}
		}

		public static string Name(string kind, ZNetView view)
		{
			ZDO val = ((Object.op_Implicit((Object)(object)view) && view.IsValid()) ? view.GetZDO() : null);
			if (val == null)
			{
				return kind;
			}
			return $"{kind} {((ZDOID)(ref val.m_uid)).UserID}:{((ZDOID)(ref val.m_uid)).ID}";
		}

		public static string Distance(Vector3 a, Vector3 b)
		{
			//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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = a - b;
			val.y = 0f;
			return $"{((Vector3)(ref val)).magnitude:0.0}m";
		}

		public static string KeyName(int key)
		{
			if (s_keyNames == null)
			{
				s_keyNames = new Dictionary<int, string>();
				FieldInfo[] fields = typeof(ZdoKeys).GetFields(BindingFlags.Static | BindingFlags.Public);
				foreach (FieldInfo fieldInfo in fields)
				{
					if (fieldInfo.FieldType == typeof(int))
					{
						s_keyNames[(int)fieldInfo.GetValue(null)] = fieldInfo.Name;
					}
				}
			}
			if (!s_keyNames.TryGetValue(key, out var value))
			{
				return key.ToString();
			}
			return value;
		}
	}
	internal static class NameLists
	{
		public static IEnumerable<string> Parse(string source)
		{
			if (string.IsNullOrEmpty(source))
			{
				yield break;
			}
			string[] array = source.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length > 0)
				{
					yield return text;
				}
			}
		}

		public static string Join(IEnumerable<string> names)
		{
			List<string> list = new List<string>(names);
			list.Sort(StringComparer.Ordinal);
			return string.Join(",", list);
		}
	}
	internal static class Translations
	{
		private const string ResourcePrefix = "WardsPlus.Translations.";

		public static void Load()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (!text.StartsWith("WardsPlus.Translations.") || !text.EndsWith(".json"))
				{
					continue;
				}
				string text2 = text.Substring("WardsPlus.Translations.".Length, text.Length - "WardsPlus.Translations.".Length - ".json".Length);
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				using StreamReader streamReader = new StreamReader(stream);
				localization.AddJsonFile(text2, streamReader.ReadToEnd());
			}
		}
	}
	internal static class ZdoKeys
	{
		public static readonly int Enabled = StringExtensionMethods.GetStableHashCode("WP_Enabled");

		public static readonly int Range = StringExtensionMethods.GetStableHashCode("WP_Range");

		public static readonly int Charges = StringExtensionMethods.GetStableHashCode("WP_Charges");

		public static readonly int RepairBelow = StringExtensionMethods.GetStableHashCode("WP_RepairBelow");

		public static readonly int Denied = StringExtensionMethods.GetStableHashCode("WP_Deny");

		public static readonly int DeniedInit = StringExtensionMethods.GetStableHashCode("WP_DenyInit");

		public static readonly int Order = StringExtensionMethods.GetStableHashCode("WP_Order");

		public static readonly int Creature = StringExtensionMethods.GetStableHashCode("WP_Creature");

		public static readonly KeyValuePair<int, int> Summon = ZDO.GetHashZDOID("WP_Summon");

		public static readonly int SummonTime = StringExtensionMethods.GetStableHashCode("WP_SummonTime");

		public static readonly KeyValuePair<int, int> SummonOf = ZDO.GetHashZDOID("WP_SummonOf");

		public static readonly int DepositRange = StringExtensionMethods.GetStableHashCode("WP_DepositRange");

		public static readonly int DepositDenied = StringExtensionMethods.GetStableHashCode("WP_DepositDeny");

		public static readonly int DepositDeniedInit = StringExtensionMethods.GetStableHashCode("WP_DepositDenyInit");

		public static readonly int DepositOrder = StringExtensionMethods.GetStableHashCode("WP_DepositOrder");

		public static readonly int PlayerDropped = StringExtensionMethods.GetStableHashCode("WP_PlayerDropped");
	}
	internal static class WardRpcs
	{
		public const string SetBool = "WP_SetBool";

		public const string SetFloat = "WP_SetFloat";

		public const string RepairFx = "WP_RepairFx";

		public const string SetDenied = "WP_SetDenied";

		public const string MoveType = "WP_MoveType";

		public const string StationFuel = "WP_StationFuel";

		public const string StationInput = "WP_StationInput";

		public const string Refund = "WP_Refund";

		public const string SetCreature = "WP_SetCreature";

		public const string SummonFx = "WP_SummonFx";

		public const string SetDepositDenied = "WP_SetDepositDenied";

		public const string MoveDepositType = "WP_MoveDepositType";

		public const string ContainerDeposit = "WP_ContainerDeposit";

		public const string DepositRefund = "WP_DepositRefund";
	}
}
namespace WardsPlus.UI
{
	internal sealed class ArrowGraphic : MaskableGraphic
	{
		public bool PointsUp = true;

		protected override void OnPopulateMesh(VertexHelper vh)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0066: 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_007b: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00ab: 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_00be: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			vh.Clear();
			Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect();
			float num = Mathf.Min(((Rect)(ref pixelAdjustedRect)).width, ((Rect)(ref pixelAdjustedRect)).height) * 0.7f;
			float num2 = num * 0.6f;
			Vector2 center = ((Rect)(ref pixelAdjustedRect)).center;
			float num3 = (PointsUp ? (num2 * 0.5f) : ((0f - num2) * 0.5f));
			UIVertex simpleVert = UIVertex.simpleVert;
			simpleVert.color = Color32.op_Implicit(((Graphic)this).color);
			simpleVert.position = Vector2.op_Implicit(new Vector2(center.x - num * 0.5f, center.y - num3));
			vh.AddVert(simpleVert);
			simpleVert.position = Vector2.op_Implicit(new Vector2(center.x + num * 0.5f, center.y - num3));
			vh.AddVert(simpleVert);
			simpleVert.position = Vector2.op_Implicit(new Vector2(center.x, center.y + num3));
			vh.AddVert(simpleVert);
			vh.AddTriangle(0, 1, 2);
		}
	}
	internal sealed class PanelDragger : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler
	{
		private RectTransform _window;

		private Vector3 _grabOffset;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			_window = (RectTransform)((Component)this).transform;
		}

		public void OnBeginDrag(PointerEventData eventData)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (ScreenToWorld(eventData.position, eventData.pressEventCamera, out var world))
			{
				_grabOffset = ((Transform)_window).position - world;
			}
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Camera pressEventCamera = eventData.pressEventCamera;
			if (ScreenToWorld(eventData.position, pressEventCamera, out var world))
			{
				((Transform)_window).position = world + _grabOffset;
				KeepOnScreen(pressEventCamera);
			}
		}

		private void KeepOnScreen(Camera cam)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_0108: 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)
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			_window.GetWorldCorners(array);
			Vector2 val = RectTransformUtility.WorldToScreenPoint(cam, array[0]);
			Vector2 val2 = val;
			for (int i = 1; i < 4; i++)
			{
				Vector2 val3 = RectTransformUtility.WorldToScreenPoint(cam, array[i]);
				val = Vector2.Min(val, val3);
				val2 = Vector2.Max(val2, val3);
			}
			Vector2 zero = Vector2.zero;
			if (val2.x > (float)Screen.width)
			{
				zero.x = (float)Screen.width - val2.x;
			}
			if (val.x + zero.x < 0f)
			{
				zero.x = 0f - val.x;
			}
			if (val.y < 0f)
			{
				zero.y = 0f - val.y;
			}
			if (val2.y + zero.y > (float)Screen.height)
			{
				zero.y = (float)Screen.height - val2.y;
			}
			if (!(zero == Vector2.zero))
			{
				Vector2 val4 = RectTransformUtility.WorldToScreenPoint(cam, ((Transform)_window).position);
				if (ScreenToWorld(val4 + zero, cam, out var world))
				{
					((Transform)_window).position = world;
				}
			}
		}

		private bool ScreenToWorld(Vector2 screen, Camera cam, out Vector3 world)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Transform)_window).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				world = Vector2.op_Implicit(screen);
				return true;
			}
			return RectTransformUtility.ScreenPointToWorldPointInRectangle(val, screen, cam, ref world);
		}
	}
	internal sealed class ScrollGroup : MonoBehaviour
	{
		private const float ScrollbarWidth = 10f;

		private const float ScrollbarGap = 6f;

		private LayoutElement _layout;

		private float _maxHeight;

		public RectTransform Content { get; private set; }

		public static ScrollGroup Create(Transform parent, float maxHeight)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0031: 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_0089: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b2: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Expected O, but got Unknown
			GameObject val = new GameObject("ScrollGroup", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			((Graphic)val.AddComponent<Image>()).color = Color.clear;
			val.AddComponent<RectMask2D>();
			ScrollGroup scrollGroup = val.AddComponent<ScrollGroup>();
			scrollGroup._maxHeight = maxHeight;
			scrollGroup._layout = val.AddComponent<LayoutElement>();
			scrollGroup._layout.preferredHeight = 0f;
			GameObject val2 = new GameObject("Content", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			RectTransform val3 = (RectTransform)val2.transform;
			val3.anchorMin = new Vector2(0f, 1f);
			val3.anchorMax = new Vector2(1f, 1f);
			val3.pivot = new Vector2(0.5f, 1f);
			val3.offsetMin = new Vector2(0f, 0f);
			val3.offsetMax = new Vector2(-16f, 0f);
			VerticalLayoutGroup obj = val2.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			val2.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			scrollGroup.Content = val3;
			GUIManager instance = GUIManager.Instance;
			GameObject obj2 = DefaultControls.CreateScrollbar(instance.ValheimControlResources);
			obj2.transform.SetParent(val.transform, false);
			RectTransform val4 = (RectTransform)obj2.transform;
			val4.anchorMin = new Vector2(1f, 0f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(1f, 0.5f);
			val4.sizeDelta = new Vector2(10f, 0f);
			val4.anchoredPosition = Vector2.zero;
			Scrollbar component = obj2.GetComponent<Scrollbar>();
			component.direction = (Direction)2;
			instance.ApplyScrollbarStyle(component);
			ScrollRect obj3 = val.AddComponent<ScrollRect>();
			obj3.content = val3;
			obj3.viewport = (RectTransform)val.transform;
			obj3.horizontal = false;
			obj3.vertical = true;
			obj3.movementType = (MovementType)2;
			obj3.inertia = false;
			obj3.scrollSensitivity = 30f;
			obj3.verticalScrollbar = component;
			obj3.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			return scrollGroup;
		}

		private void LateUpdate()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Content))
			{
				return;
			}
			Rect rect = Content.rect;
			float num = Mathf.Min(((Rect)(ref rect)).height, _maxHeight);
			if (!(Mathf.Abs(_layout.preferredHeight - num) < 0.5f))
			{
				_layout.preferredHeight = num;
				Transform parent = ((Component)this).transform.parent;
				RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (val != null)
				{
					LayoutRebuilder.MarkLayoutForRebuild(val);
				}
			}
		}
	}
	internal sealed class SettingSlider
	{
		private const float SendInterval = 0.2f;

		private const float LocalEditGrace = 0.5f;

		private readonly Slider _slider;

		private readonly Text _valueText;

		private readonly int _key;

		private readonly Func<WardBase, float> _read;

		private readonly Func<float, string> _format;

		private WardBase _ward;

		private bool _hasPending;

		private float _pending;

		private float _nextSend;

		private float _lastEdit = -100f;

		private bool _stale;

		private bool _applying;

		public SettingSlider(Slider slider, Text valueText, int key, Func<WardBase, float> read, Func<float, string> format)
		{
			_slider = slider;
			_valueText = valueText;
			_key = key;
			_read = read;
			_format = format;
			((UnityEvent<float>)(object)_slider.onValueChanged).AddListener((UnityAction<float>)OnChanged);
		}

		public void Bind(WardBase ward, float min, float max)
		{
			Flush(force: true);
			_ward = ward;
			_hasPending = false;
			_lastEdit = -100f;
			_applying = true;
			try
			{
				_slider.minValue = Mathf.Min(min, max);
				_slider.maxValue = Mathf.Max(min, max);
			}
			finally
			{
				_applying = false;
			}
			Sync();
		}

		public void Unbind()
		{
			Flush(force: true);
			_ward = null;
			_hasPending = false;
		}

		public void Sync()
		{
			if (Object.op_Implicit((Object)(object)_ward) && Object.op_Implicit((Object)(object)_slider))
			{
				if (_hasPending || Time.time - _lastEdit <= 0.5f)
				{
					_stale = true;
					return;
				}
				_stale = false;
				float num = _read(_ward);
				_slider.SetValueWithoutNotify(num);
				_valueText.text = _format(num);
			}
		}

		public void Update()
		{
			Flush(force: false);
			if (_stale)
			{
				Sync();
			}
		}

		public void Flush(bool force)
		{
			if (_hasPending && Object.op_Implicit((Object)(object)_ward) && (force || !(Time.time < _nextSend)))
			{
				_ward.RequestSetFloat(_key, _pending);
				_hasPending = false;
				_nextSend = Time.time + 0.2f;
			}
		}

		private void OnChanged(float value)
		{
			if (!_applying && Object.op_Implicit((Object)(object)_ward))
			{
				_valueText.text = _format(value);
				_pending = value;
				_hasPending = true;
				_lastEdit = Time.time;
			}
		}
	}
	internal sealed class TypeToggleList
	{
		public const int DefaultMaxRows = 7;

		private readonly RectTransform m_content;

		private readonly PrefabDenyList m_denyList;

		private readonly PrefabPriorityList m_priority;

		private readonly string m_emptyNoteToken;

		private readonly Func<string, string> m_nameForMissing;

		private readonly Dictionary<string, Toggle> m_toggles = new Dictionary<string, Toggle>();

		private SortedDictionary<string, int> m_counts = new SortedDictionary<string, int>(StringComparer.Ordinal);

		private Dictionary<string, string> m_names = new Dictionary<string, string>();

		private string m_signature;

		private string m_priorityShown;

		private string m_focusPrefab;

		private bool m_focusUp;

		public bool IsAlive => Object.op_Implicit((Object)(object)m_content);

		private string PrioritySource => m_priority?.Source;

		public TypeToggleList(Transform parent, PrefabDenyList denyList, string emptyNoteToken, int maxRows = 7, PrefabPriorityList priority = null, Func<string, string> nameForMissing = null)
		{
			m_content = WardPanel.AddScrollGroup(parent, maxRows).Content;
			m_denyList = denyList;
			m_priority = priority;
			m_emptyNoteToken = emptyNoteToken;
			m_nameForMissing = nameForMissing ?? new Func<string, string>(PieceDisplayName);
		}

		public void SetVisible(bool visible)
		{
			Transform val = (Object.op_Implicit((Object)(object)m_content) ? ((Transform)m_content).parent : null);
			if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeSelf != visible)
			{
				((Component)val).gameObject.SetActive(visible);
			}
		}

		public void Rebuild(IEnumerable<KeyValuePair<string, string>> instances)
		{
			if (!IsAlive)
			{
				return;
			}
			SortedDictionary<string, int> sortedDictionary = new SortedDictionary<string, int>(StringComparer.Ordinal);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (KeyValuePair<string, string> instance in instances)
			{
				sortedDictionary.TryGetValue(instance.Key, out var value);
				sortedDictionary[instance.Key] = value + 1;
				if (!dictionary.ContainsKey(instance.Key))
				{
					dictionary[instance.Key] = instance.Value;
				}
			}
			foreach (string item in m_denyList.Denied)
			{
				if (!sortedDictionary.ContainsKey(item))
				{
					sortedDictionary[item] = 0;
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<string, int> item2 in sortedDictionary)
			{
				stringBuilder.Append(item2.Key).Append(':').Append(item2.Value)
					.Append(';');
			}
			if (!(stringBuilder.ToString() == m_signature) || !(PrioritySource == m_priorityShown))
			{
				m_signature = stringBuilder.ToString();
				m_counts = sortedDictionary;
				m_names = dictionary;
				BuildRows();
			}
		}

		public void SyncToggles()
		{
			if (!IsAlive)
			{
				return;
			}
			if (m_signature != null && PrioritySource != m_priorityShown)
			{
				BuildRows();
			}
			foreach (KeyValuePair<string, Toggle> toggle in m_toggles)
			{
				bool flag = !m_denyList.IsDenied(toggle.Key);
				if (Object.op_Implicit((Object)(object)toggle.Value) && toggle.Value.isOn != flag)
				{
					toggle.Value.SetIsOnWithoutNotify(flag);
				}
			}
		}

		private void BuildRows()
		{
			m_priorityShown = PrioritySource;
			WardPanel.ClearChildren((Transform)(object)m_content);
			m_toggles.Clear();
			if (m_counts.Count == 0)
			{
				m_focusPrefab = null;
				WardPanel.AddNote((Transform)(object)m_content, Localization.instance.Localize(m_emptyNoteToken));
				return;
			}
			List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
			foreach (KeyValuePair<string, int> count in m_counts)
			{
				string value;
				string text = (m_names.TryGetValue(count.Key, out value) ? value : m_nameForMissing(count.Key));
				if (count.Value > 1)
				{
					text += $" ×{count.Value}";
				}
				list.Add(new KeyValuePair<string, string>(count.Key, text));
			}
			list.Sort(delegate(KeyValuePair<string, string> a, KeyValuePair<string, string> b)
			{
				if (m_priority != null)
				{
					int num2 = m_priority.RankOf(a.Key).CompareTo(m_priority.RankOf(b.Key));
					if (num2 != 0)
					{
						return num2;
					}
				}
				return string.Compare(a.Value, b.Value, StringComparison.CurrentCultureIgnoreCase);
			});
			List<string> order = new List<string>(list.Count);
			foreach (KeyValuePair<string, string> item in list)
			{
				order.Add(item.Key);
			}
			Button val = null;
			for (int num = 0; num < list.Count; num++)
			{
				string prefab = list[num].Key;
				Toggle val2 = WardPanel.AddToggleRow((Transform)(object)m_content, list[num].Value, !m_denyList.IsDenied(prefab), delegate(bool on)
				{
					m_denyList.RequestSet(prefab, !on);
				});
				m_toggles[prefab] = val2;
				if (m_priority == null)
				{
					continue;
				}
				int index = num;
				int siblingIndex = ((Component)val2).transform.GetSiblingIndex();
				WardPanel.AddArrowButtons(((Component)val2).transform.parent, delegate
				{
					MoveUp(order, index, prefab, focusUp: true);
				}, delegate
				{
					MoveUp(order, index + 1, prefab, focusUp: false);
				}, out var up, out var down).SetSiblingIndex(siblingIndex);
				((Selectable)up).interactable = index > 0;
				((Selectable)down).interactable = index < list.Count - 1;
				if (prefab == m_focusPrefab)
				{
					val = (m_focusUp ? up : down);
					if (!((Selectable)val).interactable)
					{
						val = (m_focusUp ? down : up);
					}
				}
			}
			m_focusPrefab = null;
			if (Object.op_Implicit((Object)(object)val) && ((Selectable)val).interactable && Object.op_Implicit((Object)(object)EventSystem.current))
			{
				EventSystem.current.SetSelectedGameObject(((Component)val).gameObject);
			}
		}

		private void MoveUp(List<string> order, int index, string focusPrefab, bool focusUp)
		{
			if (index <= 0 || index >= order.Count)
			{
				return;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < index; i++)
			{
				if (!m_priority.IsRanked(order[i]))
				{
					list.Add(order[i]);
				}
			}
			m_focusPrefab = focusPrefab;
			m_focusUp = focusUp;
			m_priority.RequestMoveAbove(order[index], order[index - 1], list);
		}

		public static string PieceDisplayName(string prefab)
		{
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(prefab) : null);
			Piece val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Piece>() : null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				return prefab;
			}
			return Localization.instance.Localize(val2.m_name);
		}
	}
	internal static class WardPanel
	{
		private const float Width = 320f;

		private const float Gap = 12f;

		private static readonly Color LabelColor = new Color(0.86f, 0.86f, 0.86f);

		private static readonly Color NoteColor = new Color(0.7f, 0.7f, 0.7f);

		private static WardBase s_noContainerWard;

		private static GameObject s_root;

		private static Canvas s_canvas;

		private static bool s_sortedBelow;

		private static Text s_title;

		private static Toggle s_enabled;

		private static SettingSlider s_rangeSlider;

		private static RectTransform s_extras;

		private static readonly List<SettingSlider> s_extraSliders = new List<SettingSlider>();

		private static WardBase s_ward;

		private static uint s_lastRevision;

		private static Vector3 s_defaultPosition;

		private static WardType s_placedType;

		private static bool s_placed;

		private static readonly Dictionary<WardType, Vector3> s_dragOffsets = new Dictionary<WardType, Vector3>();

		public static bool IsOpen
		{
			get
			{
				if (Object.op_Implicit((Object)(object)s_root))
				{
					return s_root.activeSelf;
				}
				return false;
			}
		}

		public static void OpenWithoutContainer(WardBase ward)
		{
			InventoryGui instance = InventoryGui.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				s_noContainerWard = ward;
				instance.Show((Container)null, 1);
			}
		}

		public static void Tick(InventoryGui gui)
		{
			WardBase wardBase = ResolveWard(gui);
			if (!Object.op_Implicit((Object)(object)wardBase))
			{
				Hide();
				return;
			}
			EnsureCreated(gui);
			if (!Object.op_Implicit((Object)(object)s_root))
			{
				return;
			}
			if ((Object)(object)wardBase != (Object)(object)s_ward)
			{
				Bind(gui, wardBase);
			}
			if (!s_root.activeSelf)
			{
				s_root.SetActive(true);
				UpdateSorting(gui, force: true);
			}
			else
			{
				UpdateSorting(gui, force: false);
			}
			wardBase.ShowAreaMarker();
			if (wardBase.DataRevision != s_lastRevision)
			{
				SyncFromWard();
			}
			s_rangeSlider.Update();
			foreach (SettingSlider s_extraSlider in s_extraSliders)
			{
				s_extraSlider.Update();
			}
			wardBase.RefreshPanel();
		}

		private static WardBase ResolveWard(InventoryGui gui)
		{
			//IL_0066: 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)
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)gui) || !Object.op_Implicit((Object)(object)localPlayer) || !InventoryGui.IsVisible())
			{
				s_noContainerWard = null;
				return null;
			}
			if (Object.op_Implicit((Object)(object)gui.m_currentContainer))
			{
				s_noContainerWard = null;
				return ((Component)gui.m_currentContainer).GetComponentInParent<WardBase>();
			}
			if (Object.op_Implicit((Object)(object)s_noContainerWard))
			{
				if (s_noContainerWard.IsValid && Vector3.Distance(((Component)s_noContainerWard).transform.position, ((Component)localPlayer).transform.position) <= gui.m_autoCloseDistance)
				{
					return s_noContainerWard;
				}
				s_noContainerWard = null;
			}
			return null;
		}

		private static void Bind(InventoryGui gui, WardBase ward)
		{
			ClearExtras();
			s_rangeSlider.Bind(ward, ward.Config.MinRange.Value, ward.Config.MaxRange.Value);
			CaptureDragOffset();
			PlacePanel(gui, ward);
			s_ward = ward;
			s_title.text = Localization.instance.Localize(ward.m_name);
			SyncFromWard();
			ward.PopulatePanel(s_extras);
			((Component)s_extras).gameObject.SetActive(((Transform)s_extras).childCount > 0);
		}

		private static void Hide()
		{
			s_rangeSlider?.Unbind();
			s_ward = null;
			ClearExtras();
			if (Object.op_Implicit((Object)(object)s_root) && s_root.activeSelf)
			{
				CaptureDragOffset();
				s_root.SetActive(false);
			}
		}

		private static void SyncFromWard()
		{
			s_lastRevision = s_ward.DataRevision;
			s_enabled.SetIsOnWithoutNotify(s_ward.IsEnabled());
			s_rangeSlider.Sync();
			foreach (SettingSlider s_extraSlider in s_extraSliders)
			{
				s_extraSlider.Sync();
			}
		}

		private static void OnEnabledChanged(bool value)
		{
			if (Object.op_Implicit((Object)(object)s_ward))
			{
				s_ward.RequestSetBool(ZdoKeys.Enabled, value);
			}
		}

		private static void ClearExtras()
		{
			foreach (SettingSlider s_extraSlider in s_extraSliders)
			{
				s_extraSlider.Unbind();
			}
			s_extraSliders.Clear();
			ClearChildren((Transform)(object)s_extras);
		}

		public static void AddSlider(Transform parent, string labelToken, int key, float min, float max, Func<WardBase, float> read, Func<float, string> format)
		{
			Text valueText;
			SettingSlider settingSlider = new SettingSlider(CreateSliderControl(parent, labelToken, out valueText), valueText, key, read, format);
			s_extraSliders.Add(settingSlider);
			if (Object.op_Implicit((Object)(object)s_ward))
			{
				settingSlider.Bind(s_ward, min, max);
			}
		}

		public static Toggle AddToggleRow(Transform parent, string label, bool isOn, Action<bool> onChanged)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = CreateRow(parent, 28f);
			Text obj2 = CreateLabel(obj, label, GUIManager.Instance.AveriaSerifBold, 17, LabelColor, 28f);
			((Component)obj2).GetComponent<LayoutElement>().flexibleWidth = 1f;
			obj2.horizontalOverflow = (HorizontalWrapMode)0;
			obj2.verticalOverflow = (VerticalWrapMode)0;
			obj2.resizeTextForBestFit = true;
			obj2.resizeTextMaxSize = 17;
			obj2.resizeTextMinSize = 13;
			Toggle obj3 = CreateToggleControl(obj);
			obj3.SetIsOnWithoutNotify(isOn);
			((UnityEvent<bool>)(object)obj3.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				onChanged(value);
			});
			return obj3;
		}

		public static Transform AddArrowButtons(Transform row, Action onUp, Action onDown, out Button up, out Button down)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			GameObject val = new GameObject("Arrows", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(row, false);
			HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 0f;
			((LayoutGroup)obj).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			AddLayout(val, 36f, 28f);
			up = AddArrowButton(val.transform, up: true, onUp);
			down = AddArrowButton(val.transform, up: false, onDown);
			return val.transform;
		}

		private static Button AddArrowButton(Transform parent, bool up, Action onClick)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			GUIManager instance = GUIManager.Instance;
			GameObject val = new GameObject(up ? "MoveUp" : "MoveDown", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			ArrowGraphic arrowGraphic = val.AddComponent<ArrowGraphic>();
			arrowGraphic.PointsUp = up;
			((Graphic)arrowGraphic).color = Color.white;
			Button obj = val.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)arrowGraphic;
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).normalColor = LabelColor;
			((ColorBlock)(ref colors)).highlightedColor = instance.ValheimOrange;
			((ColorBlock)(ref colors)).selectedColor = instance.ValheimOrange;
			((ColorBlock)(ref colors)).pressedColor = instance.ValheimYellow;
			((ColorBlock)(ref colors)).disabledColor = new Color(0.4f, 0.4f, 0.4f, 0.4f);
			((ColorBlock)(ref colors)).colorMultiplier = 1f;
			((ColorBlock)(ref colors)).fadeDuration = 0.05f;
			((Selectable)obj).colors = colors;
			((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			AddLayout(val, 18f, 28f);
			return obj;
		}

		public static ScrollGroup AddScrollGroup(Transform parent, int maxRows)
		{
			return ScrollGroup.Create(parent, (float)maxRows * 28f + (float)(maxRows - 1) * 4f);
		}

		public static void ClearChildren(Transform parent)
		{
			if (Object.op_Implicit((Object)(object)parent))
			{
				for (int num = parent.childCount - 1; num >= 0; num--)
				{
					Object.DestroyImmediate((Object)(object)((Component)parent.GetChild(num)).gameObject);
				}
			}
		}

		public static Text AddNote(Transform parent, string text)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			Text obj = CreateLabel(parent, text, GUIManager.Instance.AveriaSerif, 15, NoteColor, -1f);
			obj.horizontalOverflow = (HorizontalWrapMode)0;
			obj.verticalOverflow = (VerticalWrapMode)1;
			return obj;
		}

		private static void EnsureCreated(InventoryGui gui)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: 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)
			//IL_02d0: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)s_root) && !GUIManager.IsHeadless() && Object.op_Implicit((Object)(object)gui.m_container))
			{
				RectTransform container = gui.m_container;
				GUIManager instance = GUIManager.Instance;
				s_root = instance.CreateWoodpanel(((Transform)container).parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 320f, 200f, false);
				((Object)s_root).name = "WardsPlus_WardPanel";
				RectTransform val = (RectTransform)s_root.transform;
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(0.5f, 0.5f);
				val.anchorMax = val2;
				val.anchorMin = val2;
				val.pivot = new Vector2(0f, 1f);
				s_placed = false;
				VerticalLayoutGroup obj = s_root.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)obj).padding = new RectOffset(20, 20, 16, 20);
				((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f;
				((LayoutGroup)obj).childAlignment = (TextAnchor)1;
				((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
				s_root.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
				s_root.AddComponent<PanelDragger>();
				s_canvas = s_root.AddComponent<Canvas>();
				s_root.AddComponent<GraphicRaycaster>();
				s_title = CreateLabel(s_root.transform, "", instance.NorseBold, 28, GUIManager.Instance.ValheimOrange, 36f);
				s_title.alignment = (TextAnchor)4;
				Transform obj2 = CreateRow(s_root.transform, 30f);
				((Component)CreateLabel(obj2, Localization.instance.Localize("$wp_panel_enabled"), instance.AveriaSerifBold, 18, LabelColor, 30f)).GetComponent<LayoutElement>().flexibleWidth = 1f;
				s_enabled = CreateToggleControl(obj2);
				((UnityEvent<bool>)(object)s_enabled.onValueChanged).AddListener((UnityAction<bool>)OnEnabledChanged);
				s_rangeSlider = new SettingSlider(CreateSliderControl(s_root.transform, "$wp_range", out var valueText), valueText, ZdoKeys.Range, (WardBase w) => w.GetRange(), (float v) => $"{v:0}m");
				GameObject val3 = new GameObject("Extras", new Type[1] { typeof(RectTransform) });
				val3.transform.SetParent(s_root.transform, false);
				VerticalLayoutGroup obj3 = val3.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)obj3).spacing = 6f;
				((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false;
				s_extras = (RectTransform)val3.transform;
				val3.SetActive(false);
				s_root.SetActive(false);
			}
		}

		private static void PlacePanel(InventoryGui gui, WardBase ward)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0042: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)s_root.transform;
			RectTransform val2 = (Object.op_Implicit((Object)(object)ward.m_container) ? gui.m_container : gui.m_player);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = gui.m_container;
			}
			s_defaultPosition = BottomLeftInParentSpace(val2, ((Transform)val).parent) + new Vector3(0f, -12f, 0f);
			s_dragOffsets.TryGetValue(ward.Type, out var value);
			((Transform)val).localPosition = s_defaultPosition + value;
			s_placedType = ward.Type;
			s_placed = true;
		}

		private static void UpdateSorting(InventoryGui gui, bool force)
		{
			if (!Object.op_Implicit((Object)(object)s_canvas))
			{
				return;
			}
			bool flag = IsVanillaDialogOpen(gui);
			if (!force && flag == s_sortedBelow)
			{
				return;
			}
			s_sortedBelow = flag;
			Canvas val = (Object.op_Implicit((Object)(object)((Component)s_canvas).transform.parent) ? ((Component)((Component)s_canvas).transform.parent).GetComponentInParent<Canvas>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				val = val.rootCanvas;
			}
			int num = (Object.op_Implicit((Object)(object)val) ? val.sortingOrder : 0);
			int sortingOrder;
			if (flag)
			{
				sortingOrder = num - 1;
			}
			else
			{
				int num2 = num;
				Canvas[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Canvas>(true);
				foreach (Canvas val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)(object)s_canvas && val2.overrideSorting)
					{
						num2 = Mathf.Max(num2, val2.sortingOrder);
					}
				}
				sortingOrder = num2 + 1;
			}
			s_canvas.overrideSorting = true;
			if (Object.op_Implicit((Object)(object)val))
			{
				s_canvas.sortingLayerID = val.sortingLayerID;
			}
			s_canvas.sortingOrder = sortingOrder;
		}

		private static bool IsVanillaDialogOpen(InventoryGui gui)
		{
			if ((!Object.op_Implicit((Object)(object)gui.m_textsDialog) || !((Component)gui.m_textsDialog).gameObject.activeSelf) && (!Object.op_Implicit((Object)(object)gui.m_skillsDialog) || !((Component)gui.m_skillsDialog).gameObject.activeSelf) && (!Object.op_Implicit((Object)(object)gui.m_trophiesPanel) || !gui.m_trophiesPanel.activeSelf) && (!Object.op_Implicit((Object)(object)gui.m_achievementsPanel) || !((Component)gui.m_achievementsPanel).gameObject.activeSelf) && (!Object.op_Implicit((Object)(object)gui.m_splitDialog) || !gui.m_splitDialog.IsActive))
			{
				if (Object.op_Implicit((Object)(object)gui.m_variantDialog))
				{
					return ((Component)gui.m_variantDialog).gameObject.activeSelf;
				}
				return false;
			}
			return true;
		}

		private static void CaptureDragOffset()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.RememberPanelPosition.Value)
			{
				s_dragOffsets.Clear();
			}
			else if (s_placed && Object.op_Implicit((Object)(object)s_root) && s_root.activeSelf)
			{
				s_dragOffsets[s_placedType] = s_root.transform.localPosition - s_defaultPosition;
			}
		}

		public static void OnRememberPositionChanged()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.RememberPanelPosition.Value)
			{
				s_dragOffsets.Clear();
				if (s_placed && Object.op_Implicit((Object)(object)s_root))
				{
					s_root.transform.localPosition = s_defaultPosition;
				}
			}
		}

		private static Vector3 BottomLeftInParentSpace(RectTransform rect, Transform space)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			rect.GetWorldCorners(array);
			return space.InverseTransformPoint(array[0]);
		}

		private static Toggle CreateToggleControl(Transform row)
		{
			GameObject obj = GUIManager.Instance.CreateToggle(row, 28f, 28f);
			Transform val = obj.transform.Find("Label");
			if (Object.op_Implicit((Object)(object)val))
			{
				Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
			}
			AddLayout(obj, 28f, 28f);
			return obj.GetComponent<Toggle>();
		}

		private static Slider CreateSliderControl(Transform parent, string labelToken, out Text valueText)
		{
			//IL_0026: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.Instance;
			Transform parent2 = CreateRow(parent, 26f);
			((Component)CreateLabel(parent2, Localization.instance.Localize(labelToken), instance.AveriaSerifBold, 18, LabelColor, 26f)).GetComponent<LayoutElement>().flexibleWidth = 1f;
			valueText = CreateLabel(parent2, "", instance.AveriaSerifBold, 18, instance.ValheimYellow, 26f);
			valueText.alignment = (TextAnchor)5;
			((Component)valueText).GetComponent<LayoutElement>().preferredWidth = 70f;
			GameObject obj = DefaultControls.CreateSlider(instance.ValheimControlResources);
			obj.transform.SetParent(parent, false);
			Slider component = obj.GetComponent<Slider>();
			instance.ApplySliderStyle(component);
			component.wholeNumbers = true;
			AddLayout(obj, -1f, 20f);
			return component;
		}

		private static Transform CreateRow(Transform parent, float height)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			GameObject val = new GameObject("Row", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 10f;
			((LayoutGroup)obj).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			AddLayout(val, -1f, height);
			return val.transform;
		}

		private static Text CreateLabel(Transform parent, string text, Font font, int size, Color color, float height)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GUIManager.Instance.CreateText(text, parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, font, size, color, true, Color.black, 100f, Mathf.Max(height, 20f), false);
			Text component = obj.GetComponent<Text>();
			component.alignment = (TextAnchor)3;
			AddLayout(obj, -1f, height);
			return component;
		}

		private static LayoutElement AddLayout(GameObject go, float width, float height)
		{
			LayoutElement val = go.GetComponent<LayoutElement>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = go.AddComponent<LayoutElement>();
			}
			if (width >= 0f)
			{
				val.preferredWidth = width;
			}
			if (height >= 0f)
			{
				val.preferredHeight = height;
			}
			return val;
		}
	}
}
namespace WardsPlus.Pieces
{
	internal static class WardPieces
	{
		private sealed class WardDefinition
		{
			public WardType Type;

			public string PrefabName;

			public string Token;

			public Type Component;

			public int ContainerWidth;

			public int ContainerHeight;

			public bool Distant;

			public bool SecondaryRing;
		}

		public const string CategoryName = "WardsPlus";

		private const string BasePrefab = "guard_stone";

		private const string BackgroundSourcePrefab = "piece_chest_wood";

		private static readonly WardDefinition[] Definitions = new WardDefinition[5]
		{
			new WardDefinition
			{
				Type = WardType.Repair,
				PrefabName = "WP_Ward_Repair",
				Token = "wp_ward_repair",
				Component = typeof(RepairWard),
				ContainerWidth = 4,
				ContainerHeight = 2
			},
			new WardDefinition
			{
				Type = WardType.Refuel,
				PrefabName = "WP_Ward_Refuel",
				Token = "wp_ward_refuel",
				Component = typeof(RefuelWard),
				ContainerWidth = 4,
				ContainerHeight = 2
			},
			new WardDefinition
			{
				Type = WardType.Gathering,
				PrefabName = "WP_Ward_Gathering",
				Token = "wp_ward_gathering",
				Component = typeof(GatheringWard),
				ContainerWidth = 5,
				ContainerHeight = 2,
				SecondaryRing = true
			},
			new WardDefinition
			{
				Type = WardType.Spawnproof,
				PrefabName = "WP_Ward_Spawnproof",
				Token = "wp_ward_spawnproof",
				Component = typeof(SpawnproofWard),
				Distant = true
			},
			new WardDefinition
			{
				Type = WardType.Defender,
				PrefabName = "WP_Ward_Defender",
				Token = "wp_ward_defender",
				Component = typeof(DefenderWard),
				ContainerWidth = 1,
				ContainerHeight = 1
			}
		};

		private static readonly HashSet<string> GlowOrbParts = new HashSet<string> { "flare", "glow" };

		public static void Init()
		{
			PrefabManager.OnVanillaPrefabsAvailable += RegisterAll;
		}

		private static void RegisterAll()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterAll;
			GameObject prefab = Cache.GetPrefab<GameObject>("piece_chest_wood");
			Sprite background = ((prefab == null) ? null : prefab.GetComponent<Container>()?.m_bkg);
			WardDefinition[] definitions = Definitions;
			foreach (WardDefinition wardDefinition in definitions)
			{
				try
				{
					Register(wardDefinition, background);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Failed to create {wardDefinition.PrefabName}: {arg}");
				}
			}
		}

		private static void Register(WardDefinition def, Sprite background)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_008d: 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_00b7: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			WardConfig wardConfig = PluginConfig.For(def.Type);
			if (!wardConfig.Enabled.Value)
			{
				Plugin.Log.LogInfo((object)(def.PrefabName + " is disabled in the config."));
				return;
			}
			string text = wardConfig.CraftingStation.Value?.Trim();
			PieceConfig val = new PieceConfig
			{
				Name = "$" + def.Token,
				Description = "$" + def.Token + "_desc",
				PieceTable = PieceTables.Hammer,
				Category = "WardsPlus",
				CraftingStation = (string.IsNullOrEmpty(text) ? null : text),
				Requirements = wardConfig.ParseRecipe()
			};
			CustomPiece val2 = new CustomPiece(def.PrefabName, "guard_stone", val);
			GameObject piecePrefab = val2.PiecePrefab;
			if ((Object)(object)piecePrefab == (Object)null)
			{
				Plugin.Log.LogError((object)("Could not clone 'guard_stone' for " + def.PrefabName + "."));
			}
			else if (ConvertToWard(piecePrefab, def, val.Name, wardConfig, background))
			{
				Sprite val3 = RenderManager.Instance.Render(piecePrefab, RenderManager.IsometricRotation);
				if (Object.op_Implicit((Object)(object)val3))
				{
					val2.Piece.m_icon = val3;
				}
				else
				{
					Plugin.Log.LogWarning((object)("Could not render an icon for " + def.PrefabName + "; using the vanilla ward icon."));
				}
				PieceManager.Instance.AddPiece(val2);
			}
		}

		private static bool ConvertToWard(GameObject prefab, WardDefinition def, string nameToken, WardConfig cfg, Sprite background)
		{
			//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_00d2: 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)
			Color value = cfg.Color.Value;
			PrivateArea component = prefab.GetComponent<PrivateArea>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				Plugin.Log.LogError((object)("'guard_stone' has no PrivateArea; cannot build " + def.PrefabName + "."));
				return false;
			}
			WardBase wardBase = (WardBase)(object)prefab.AddComponent(def.Component);
			wardBase.m_name = nameToken;
			wardBase.m_model = component.m_model;
			wardBase.m_enabledEffect = component.m_enabledEffect;
			wardBase.m_areaMarker = component.m_areaMarker;
			wardBase.m_hoverOffset = component.m_hoverOffset;
			if (Object.op_Implicit((Object)(object)component.m_areaMarker) && component.m_radius > 0f)
			{
				wardBase.m_markerSegmentsPerMeter = (float)component.m_areaMarker.m_nrOfSegments / (MathF.PI * 2f * component.m_radius);
			}
			DestroyIfChild(prefab, component.m_inRangeEffect);
			Object.DestroyImmediate((Object)(object)component);
			ApplyColor(prefab, wardBase, value);
			if (def.SecondaryRing)
			{
				if (Object.op_Implicit((Object)(object)wardBase.m_areaMarker) && cfg.SecondaryRingColor != null)
				{
					wardBase.m_secondaryMarker = AddSecondaryRing(def, wardBase.m_areaMarker, cfg.SecondaryRingColor.Value);
				}
				else
				{
					Plugin.Log.LogWarning((object)(def.PrefabName + ": no area marker or ring color config; it won't show a second ring."));
				}
			}
			if (def.ContainerWidth > 0 && def.ContainerHeight > 0)
			{
				wardBase.m_container = AddContainer(prefab, def, nameToken, background);
			}
			if (def.Distant)
			{
				ZNetView component2 = prefab.GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					component2.m_distant = true;
				}
			}
			return true;
		}

		private static CircleProjector AddSecondaryRing(WardDefinition def, CircleProjector marker, Color color)
		{
			//IL_003b: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)marker).transform;
			GameObject obj = Object.Instantiate<GameObject>(((Component)transform).gameObject, transform.parent, false);
			((Object)obj).name = ((Object)((Component)transform).gameObject).name + "_Secondary";
			obj.transform.localPosition = transform.localPosition;
			obj.transform.localRotation = transform.localRotation;
			obj.transform.localScale = transform.localScale;
			CircleProjector component = obj.GetComponent<CircleProjector>();
			if (Object.op_Implicit((Object)(object)marker.m_prefab))
			{
				GameObject val = PrefabManager.Instance.CreateClonedPrefab(def.PrefabName + "_RingSegment", marker.m_prefab);
				if (Object.op_Implicit((Object)(object)val))
				{
					TintSegment(val, color);
					component.m_prefab = val;
				}
				else
				{
					Plugin.Log.LogWarning((object)(def.PrefabName + ": couldn't copy the ring segment; its second ring keeps the vanilla color."));
				}
			}
			return component;
		}

		private static void TintSegment(GameObject segment, Color color)
		{
			//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_0071: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			Renderer[] componentsInChildren = segment.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = sharedMaterials[j];
					if (!Object.op_Implicit((Object)(object)val2))
					{
						continue;
					}
					if (!dictionary.TryGetValue(val2, out var value))
					{
						value = new Material(val2)
						{
							name = ((Object)val2).name + "_" + ((Object)segment).name
						};
						string[] array = new string[3] { "_Color", "_TintColor", "_BaseColor" };
						foreach (string text in array)
						{
							if (value.HasProperty(text))
							{
								value.SetColor(text, new Color(color.r, color.g, color.b, value.GetColor(text).a));
							}
						}
						dictionary[val2] = value;
					}
					sharedMaterials[j] = value;
				}
				val.sharedMaterials = sharedMaterials;
			}
		}

		private static void DestroyIfChild(GameObject prefab, GameObject child)
		{
			if (Object.op_Implicit((Object)(object)child) && child.transform.IsChildOf(prefab.transform) && (Object)(object)child != (Object)(object)prefab)
			{
				Object.DestroyImmediate((Object)(object)child);
			}
		}

		private static void ApplyColor(GameObject prefab, WardBase ward, Color color)
		{
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: 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_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_0098: 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_01bc: 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_01c8: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)ward.m_model))
			{
				Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
				Material[] sharedMaterials = ((Renderer)ward.m_model).sharedMaterials;
				foreach (Material val in sharedMaterials)
				{
					if (Object.op_Implicit((Object)(object)val) && !dictionary.ContainsKey(val) && val.HasProperty("_EmissionColor"))
					{
						Color color2 = val.GetColor("_EmissionColor");
						float maxColorComponent = ((Color)(ref color2)).maxColorComponent;
						if (!(maxColorComponent < 0.01f))
						{
							Material val2 = new Material(val)
							{
								name = ((Object)val).name + "_" + ((Object)prefab).name
							};
							val2.SetColor("_EmissionColor", color * maxColorComponent);
							val2.EnableKeyword("_EMISSION");
							dictionary[val] = val2;
						}
					}
				}
				Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val3 in componentsInChildren)
				{
					Material[] sharedMaterials2 = val3.sharedMaterials;
					bool flag = false;
					for (int j = 0; j < sharedMaterials2.Length; j++)
					{
						if (Object.op_Implicit((Object)(object)sharedMaterials2[j]) && dictionary.TryGetValue(sharedMaterials2[j], out var value))
						{
							sharedMaterials2[j] = value;
							flag = true;
						}
					}
					if (flag)
					{
						val3.sharedMaterials = sharedMaterials2;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)ward.m_enabledEffect))
			{
				return;
			}
			Light[] componentsInChildren2 = ward.m_enabledEffect.GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].color = color;
			}
			ParticleSystem[] componentsInChildren3 = ward.m_enabledEffect.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				MainModule main = componentsInChildren3[i].main;
				MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
				float num;
				if ((int)((MinMaxGradient)(ref startColor)).mode != 0)
				{
					num = 1f;
				}
				else
				{
					startColor = ((MainModule)(ref main)).startColor;
					num = ((MinMaxGradient)(ref startColor)).color.a;
				}
				float num2 = num;
				((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(color.r, color.g, color.b, num2));
			}
			if (!PluginConfig.ShowGlowOrb.Value)
			{
				HideGlowOrb(ward.m_enabledEffect);
			}
		}

		private static void HideGlowOrb(GameObject enabledEffect)
		{
			Transform[] componentsInChildren = enabledEffect.GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val) && GlowOrbParts.Contains(((Object)val).name))
				{
					Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
				}
			}
		}

		private static Container AddContainer(GameObject prefab, WardDefinition def, string nameToken, Sprite background)
		{
			//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_0049: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("WP_Inventory");
			val.transform.SetParent(prefab.transform, false);
			Container obj = val.AddComponent<Container>();
			obj.m_name = nameToken;
			obj.m_width = def.ContainerWidth;
			obj.m_height = def.ContainerHeight;
			obj.m_bkg = background;
			obj.m_privacy = (PrivacySetting)2;
			obj.m_checkGuardStone = true;
			obj.m_rootObjectOverride = prefab.GetComponent<ZNetView>();
			return obj;
		}
	}
}
namespace WardsPlus.Patches
{
	[HarmonyPatch]
	internal static class DefenderPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Game), "Start")]
		private static void GameStart()
		{
			TrophyMap.EnsureBuilt();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZNetScene), "OnDestroy")]
		private static void ZNetSceneDestroyed()
		{
			TrophyMap.Clear();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Character), "Awake")]
		private static void CharacterAwake(Character __instance)
		{
			DefenderSummon.AttachIfSummon(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
		private static bool GenerateDropList(CharacterDrop __instance, ref List<KeyValuePair<GameObject, int>> __result)
		{
			if (!DefenderSummon.IsSummon((Component)(object)__instance))
			{
				return true;
			}
			__result = new List<KeyValuePair<GameObject, int>>();
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "RaiseSkill")]
		private static bool RaiseSkill(Character __instance)
		{
			if (__instance.IsTamed())
			{
				return !DefenderSummon.IsSummon((Component)(object)__instance);
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Procreation), "Procreate")]
		private static bool Procreate(Procreation __instance)
		{
			return !DefenderSummon.IsSummon((Component)(object)__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Tameable), "Interact")]
		private static bool TameableInteract(Tameable __instance, ref bool __result)
		{
			if (!DefenderSummon.IsSummon((Component)(object)__instance))
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool Rejects(Inventory inventory, ItemData item)
		{
			if (item != null && DefenderWard.IsDefenderInventory(inventory))
			{
				return !TrophyMap.IsUsable(item);
			}
			return false;
		}

		private static void TellPlayer()
		{
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && InventoryGui.IsVisible())
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "$wp_defender_trophy_only", 0, (Sprite)null, false);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
		private static bool DropItem(InventoryGrid __instance, Inventory fromInventory, ItemData item, Vector2i pos, ref bool __result)
		{
			//IL_000e: 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)
			Inventory inventory = __instance.m_inventory;
			ItemData val = ((inventory != null) ? inventory.GetItemAt(pos.x, pos.y) : null);
			if (!Rejects(inventory, item) && (val == null || val == item || !Rejects(fromInventory, val)))
			{
				return true;
			}
			TellPlayer();
			__result = false;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		private static bool AddItem(Inventory __instance, ItemData item, ref bool __result)
		{
			return Allow(__instance, item, ref __result);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(Vector2i)
		})]
		private static bool AddItemAt(Inventory __instance, ItemData item, ref bool __result)
		{
			return Allow(__instance, item, ref __result);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		private static bool AddItemAmountAt(Inventory __instance, ItemData item, ref bool __result)
		{
			return Allow(__instance, item, ref __result);
		}

		private static bool Allow(Inventory inventory, ItemData item, ref bool result)
		{
			if (!Rejects(inventory, item))
			{
				return true;
			}
			TellPlayer();
			result = false;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class GatheringPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Container), "Awake")]
		private static void ContainerAwake(Container __instance)
		{
			ContainerRegistry.Track(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZNetScene), "OnDestroy")]
		private static void ZNetSceneDestroyed()
		{
			ContainerRegistry.Clear();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemDrop), "Start")]
		private static void ItemDropStart(ItemDrop __instance)
		{
			GatheringWard.OnItemSpawned(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemDrop), "OnPlayerDrop")]
		private static void OnPlayerDrop(ItemDrop __instance)
		{
			ZNetView val = (Object.op_Implicit((Object)(object)__instance) ? __instance.m_nview : null);
			if (Object.op_Implicit((Object)(object)val) && val.IsValid() && val.IsOwner())
			{
				val.GetZDO().Set(ZdoKeys.PlayerDropped, true);
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui))]
	internal static class InventoryGuiPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void UpdatePostfix(InventoryGui __instance)
		{
			WardPanel.Tick(__instance);
		}
	}
	[HarmonyPatch]
	internal static class SpawnPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SpawnSystem), "IsSpawnPointGood")]
		private static void IsSpawnPointGood(SpawnData spawn, ref Vector3 spawnPoint, ref bool __result)
		{
			//IL_000d: 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)
			if (__result && !spawn.m_insidePlayerBase && SpawnproofWard.IsProtected(spawnPoint))
			{
				__result = false;
				if (DebugLog.Enabled)
				{
					string text = (Object.op_Implicit((Object)(object)spawn.m_prefab) ? ((Object)spawn.m_prefab).name : "?");
					DebugLog.WriteThrottled("spawn:" + text, 10f, $"Spawnproof: blocked a world/raid spawn of {text} at {spawnPoint:F0} (repeats hidden for 10s).");
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CreatureSpawner), "UpdateSpawner")]
		private static bool UpdateSpawner(CreatureSpawner __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.m_spawnInPlayerBase || !SpawnproofWard.IsProtected(((Component)__instance).transform.position))
			{
				return true;
			}
			if (DebugLog.Enabled)
			{
				string arg = (Object.op_Implicit((Object)(object)__instance.m_creaturePrefab) ? ((Object)__instance.m_creaturePrefab).name : "?");
				DebugLog.WriteThrottled("spawner:" + ((Object)__instance).GetInstanceID(), 60f, $"Spawnproof: holding back a {arg} spawn point at {((Component)__instance).transform.position:F0} (repeats hidden for 60s).");
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class StationPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Fireplace), "Awake")]
		private static void FireplaceAwake(Fireplace __instance)
		{
			StationRegistry.Track(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Smelter), "Awake")]
		private static void SmelterAwake(Smelter __instance)
		{
			StationRegistry.Track(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CookingStation), "Awake")]
		private static void CookingStationAwake(CookingStation __instance)
		{
			StationRegistry.Track(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ShieldGenerator), "Start")]
		private static void ShieldGeneratorStart(ShieldGenerator __instance)
		{
			StationRegistry.Track(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZNetScene), "OnDestroy")]
		private static void ZNetSceneDestroyed()
		{
			StationRegistry.Clear();
		}
	}
}
namespace WardsPlus.Config
{
	public enum WardType
	{
		Repair,
		Refuel,
		Spawnproof,
		Defender,
		Gathering
	}
	internal sealed class WardConfig
	{
		public ConfigEntry<bool> Enabled;

		public ConfigEntry<string> Recipe;

		public ConfigEntry<string> CraftingStation;

		public ConfigEntry<float> DefaultRange;

		public ConfigEntry<float> MinRange;

		public ConfigEntry<float> MaxRange;

		public ConfigEntry<Color> Color;

		public ConfigEntry<Color> SecondaryRingColor;

		public float ClampRange(float value)
		{
			float num = Mathf.Min(MinRange.Value, MaxRange.Value);
			float num2 = Mathf.Max(MinRange.Value, MaxRange.Value);
			return Mathf.Clamp(value, num, num2);
		}

		public RequirementConfig[] ParseRecipe()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			List<RequirementConfig> list = new List<RequirementConfig>();
			foreach (KeyValuePair<string, int> item in PluginConfig.ParseItemAmounts(Recipe))
			{
				list.Add(new RequirementConfig(item.Key, item.Value, 0, true));
			}
			return list.ToArray();
		}
	}
	internal static class PluginConfig
	{
		private static readonly Dictionary<WardType, WardConfig> Wards = new Dictionary<WardType, WardConfig>();

		public static ConfigEntry<bool> ShowGlowOrb;

		public static ConfigEntry<bool> RememberPanelPosition;

		public static ConfigEntry<bool> DebugLogging;

		public static ConfigEntry<string> RepairFuel;

		public static ConfigEntry<float> RepairScanInterval;

		public static ConfigEntry<float> RepairInterval;

		public static ConfigEntry<float> RepairDefaultThreshold;

		public static ConfigEntry<string> RepairAlwaysRepair;

		public static ConfigEntry<float> RefuelScanInterval;

		public static ConfigEntry<string> RefuelDefaultDenied;

		public static ConfigEntry<string> RefuelInputStations;

		public static ConfigEntry<float> DefenderScanInterval;

		public static ConfigEntry<int> DefenderSummonLevel;

		public static ConfigEntry<float> DefenderSummonCooldown;

		public static ConfigEntry<float> DefenderIdleDespawn;

		public static ConfigEntry<string> DefenderDeniedCreatures;

		public static ConfigEntry<string> DefenderTrophyOverrides;

		public static ConfigEntry<float> GatheringScanInterval;

		public static ConfigEntry<float> GatheringPickupDelay;

		public static ConfigEntry<bool> GatheringIgnorePlayerDropped;

		public static ConfigEntry<string> GatheringIgnoredItems;

		public static ConfigEntry<float> GatheringDefaultDepositRange;

		public static ConfigEntry<float> GatheringMaxDepositRange;

		public static ConfigEntry<string> GatheringDefaultDeniedContainers;

		public static WardConfig For(WardType type)
		{
			return Wards[type];
		}

		public static void Bind(ConfigFile cfg)
		{
			//IL_0081: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			ShowGlowOrb = cfg.Bind<bool>("General", "Show Glow Orb", false, "Show the vanilla ward's spherical glow above active wards. When off, only the colored magic lines glow. Client-side. Requires a reload.");
			RememberPanelPosition = cfg.Bind<bool>("General", "Remember Panel Position", false, "Keep the ward settings panel where you last dragged it. When off, it always opens at its default spot, and turning this off clears the remembered position. Client-side, does NOT require a reload.");
			DebugLogging = cfg.Bind<bool>("General", "Debug Logging", false, "Write diagnostic \"[debug]\" lines to the BepInEx log for ward events: ticks, settings changes, pickups, deposits, refuels, repairs, summons, blocked spawns and refunds. Meant for testing and bug reports; it can be chatty. Only logs what happens on this machine (each ward runs on one player's game). Client-side, does NOT require a reload.");
			Wards[WardType.Repair] = BindWard(cfg, WardType.Repair, "RoundLog:10,Stone:10,GreydwarfEye:50", "piece_workbench", 20f, 5f, 40f, new Color(0.25f, 1f, 0.35f));
			BindRepair(cfg, $"{WardType.Repair} Ward");
			Wards[WardType.Refuel] = BindWard(cfg, WardType.Refuel, "FineWood:10,Stone:10,Coal:25,SurtlingCore:1", "piece_workbench", 20f, 5f, 40f, new Color(1f, 0.5f, 0.1f));
			BindRefuel(cfg, $"{WardType.Refuel} Ward");
			Wards[WardType.Spawnproof] = BindWard(cfg, WardType.Spawnproof, "ElderBark:10,Stone:50,SurtlingCore:1", "piece_workbench", 30f, 10f, 60f, new Color(0.2f, 0.6f, 1f));
			Wards[WardType.Defender] = BindWard(cfg, WardType.Defender, "YggdrasilWood:10,BlackMarble:10,BlackCore:1,DragonTear:5", "forge", 20f, 5f, 20f, new Color(0.7f, 0.3f, 1f));
			BindDefender(cfg, $"{WardType.Defender} Ward");
			Wards[WardType.Gathering] = BindWard(cfg, WardType.Gathering, "FineWood:10,Stone:10,SurtlingCore:1,Feathers:25", "piece_workbench", 10f, 2f, 20f, new Color(1f, 0.85f, 0.2f), new KeyValuePair<string, Color>("Deposit Ring Color", new Color(0.35f, 0.8f, 1f)));
			BindGathering(cfg, $"{WardType.Gathering} Ward");
		}

		private static void BindGathering(ConfigFile cfg, string section)
		{
			//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_000d: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			GatheringScanInterval = cfg.Bind<float>(section, "Scan Interval", 30f, new ConfigDescription("Seconds between full checks for loose items and deposits (varies by ±20% so wards don't sync up). New drops in range are noticed straight away; this catches anything else.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 600f), new object[1] { val }));
			GatheringPickupDelay = cfg.Bind<float>(section, "Pickup Delay", 2f, new ConfigDescription("Seconds a new drop lies on the ground before the ward picks it up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), new object[1] { val }));
			GatheringIgnorePlayerDropped = cfg.Bind<bool>(section, "Ignore Player-Dropped Items", true, new ConfigDescription("Leave items that a player dropped on purpose, like vanilla's auto-pickup does.", (AcceptableValueBase)null, new object[1] { val }));
			GatheringIgnoredItems = cfg.Bind<string>(section, "Ignored Items", "", new ConfigDescription("Item prefab names the ward never picks up (e.g. Stone,Wood). Eggs, fish, food placed on tables and items stuck in tar are never picked up. Comma separated.", (AcceptableValueBase)null, new object[1] { val }));
			GatheringDefaultDepositRange = cfg.Bind<float>(section, "Default Deposit Range", 10f, new ConfigDescription("Deposit range (m) a newly placed ward starts with. 0 means it doesn't deposit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[1] { val }));
			GatheringMaxDepositRange = cfg.Bind<float>(section, "Max Deposit Range", 20f, new ConfigDescription("Largest deposit range (m) players can set in the ward's panel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[1] { val }));
			GatheringDefaultDeniedContainers = cfg.Bind<string>(section, "Default Denied Containers", "", new ConfigDescription("Container prefab names a newly placed ward starts with turned off for deposits (e.g. piece_chest_wood). Players can change it per ward in its panel. Comma separated.", (AcceptableValueBase)null, new object[1] { val }));
		}

		private static void BindDefender(ConfigFile cfg, string section)
		{
			//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_000d: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			DefenderScanInterval = cfg.Bind<float>(section, "Scan Interval", 2f, new ConfigDescription("Seconds between checks for enemies in range (varies by ±20% so wards don't sync up).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[1] { val }));
			DefenderSummonLevel = cfg.Bind<int>(section, "Summon Level", 1, new ConfigDescription("Level of the summoned defender: 1 is a normal creature, 2 is one star, 3 is two stars.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), new object[1] { val }));
			DefenderSummonCooldown = cfg.Bind<float>(section, "Summon Cooldown", 30f, new ConfigDescription("Minimum seconds between two summons from the same ward, so a defender that dies isn't replaced instantly.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), new object[1] { val }));
			DefenderIdleDespawn = cfg.Bind<float>(section, "Idle Despawn", 10f, new ConfigDescription("Seconds a defender stays once it has nothing left to fight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 120f), new object[1] { val }));
			DefenderDeniedCreatures = cfg.Bind<string>(section, "Denied Creatures", "", new ConfigDescription("Creature prefab names that can never be summoned (e.g. Wolf,Lox). Bosses and water-only creatures never are. Comma separated.", (AcceptableValueBase)null, new object[1] { val }));
			DefenderTrophyOverrides = cfg.Bind<string>(section, "Trophy Overrides", "", new ConfigDescription("Trophy:Creature pairs (prefab names) that make a trophy summon that creature by default, e.g. TrophyDraugr:Draugr_Ranged. Also lets a trophy summon a creature that doesn't drop it. Comma separated.", (AcceptableValueBase)null, new object[1] { val }));
		}

		private static void BindRepair(ConfigFile cfg, string section)
		{
			//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_000d: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			RepairFuel = cfg.Bind<string>(section, "Fuel", "Resin:10,GreydwarfEye:10", new ConfigDescription("Items the ward burns as fuel, as Item:Repairs pairs (item prefab names), in the order they are used. Each item gives that many repairs; one repair fully heals one piece.", (AcceptableValueBase)null, new object[1] { val }));
			RepairScanInterval = cfg.Bind<float>(section, "Scan Interval", 30f, new ConfigDescription("Seconds between checks for damaged pieces while nothing needs repairing (varies by ±20% so wards don't sync up).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 600f), new object[1] { val }));
			RepairInterval = cfg.Bind<float>(section, "Repair Interval", 1f, new ConfigDescription("Seconds between repairs while damaged pieces are in range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 30f), new object[1] { val }));
			RepairDefaultThreshold = cfg.Bind<float>(section, "Default Repair Below", 100f, new ConfigDescription("Health % a newly placed ward starts with for 'Repair below'. Pieces are repaired only when their health is below it. 100 repairs any damage; lower values save fuel on wear from rain.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 100f), new object[1] { val }));
			RepairAlwaysRepair = cfg.Bind<string>(section, "Always Repair", "piece_sharpstakes,piece_dvergr_sharpstakes", new ConfigDescription("Piece prefab names repaired at any damage, ignoring each ward's 'Repair below' setting. Comma separated.", (AcceptableValueBase)null, new object[1] { val }));
		}

		private static void BindRefuel(ConfigFile cfg, string section)
		{
			//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_000d: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			RefuelScanInterval = cfg.Bind<float>(section, "Scan Interval", 30f, new ConfigDescription("Seconds between top-ups of the fires and smelters in range (varies by ±20% so wards don't sync up).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 600f), new object[1] { val }));
			RefuelDefaultDenied = cfg.Bind<string>(section, "Default Denied", "", new ConfigDescription("Piece prefab names a newly placed ward starts with turned off (e.g. piece_bathtub,smelter). Players can change it per ward in its panel. Comma separated.", (AcceptableValueBase)null, new object[1] { val }));
			RefuelInputStations = cfg.Bind<string>(section, "Input Stations", "charcoal_kiln", new ConfigDescription("Prefab names of stations with no fuel slot whose input the ward loads instead, like the charcoal kiln's wood. Fires and smelter fuel are always handled; smelter ore never is. Comma separated.", (AcceptableValueBase)null, new object[1] { val }));
		}

		public static List<KeyValuePair<string, int>> ParseItemAmounts(ConfigEntry<string> entry)
		{
			List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
			string[] array = (entry.Value ?? "").Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0)
				{
					string[] array2 = text.Split(':');
					if (array2.Length != 2 || array2[0].Trim().Length == 0 || !int.TryParse(array2[1].Trim(), out var result) || result <= 0)
					{
						Plugin.Log.LogWarning((object)("[" + ((ConfigEntryBase)entry).Definition.Section + "] " + ((ConfigEntryBase)entry).Definition.Key + ": ignoring invalid entry '" + text + "'. Expected Item:Amount."));
					}
					else
					{
						list.Add(new KeyValuePair<string, int>(array2[0].Trim(), result));
					}
				}
			}
			return list;
		}

		private static WardConfig BindWard(ConfigFile cfg, WardType type, string recipe, string station, float defaultRange, float minRange, float maxRange, Color color, KeyValuePair<string, Color>? secondaryRing = null)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_005e: 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_008e: 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_00a3: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00c9: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_0109: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			string text = $"{type} Ward";
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			AcceptableValueRange<float> val2 = new AcceptableValueRange<float>(1f, 200f);
			WardConfig wardConfig = new WardConfig();
			wardConfig.SecondaryRingColor = (secondaryRing.HasValue ? cfg.Bind<Color>(text, secondaryRing.Value.Key, secondaryRing.Value.Value, "Color of the ward's second range ring. Client-side. Requires a restart.") : null);
			wardConfig.Enabled = cfg.Bind<bool>(text, "Enabled", true, new ConfigDescription("Add this ward to the hammer. Requires a restart.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				Order = 10
			} }));
			wardConfig.Recipe = cfg.Bind<string>(text, "Recipe", recipe, new ConfigDescription("Build cost as Item:Amount pairs, comma separated (item prefab names). Requires a restart.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				Order = 9
			} }));
			wardConfig.CraftingStation = cfg.Bind<string>(text, "Crafting Station", station, new ConfigDescription("Prefab name of the station required nearby to build it (e.g. piece_workbench, forge, blackforge). Empty for none. Requires a restart.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				Order = 8
			} }));
			wardConfig.DefaultRange = cfg.Bind<float>(text, "Default Range", defaultRange, new ConfigDescription("Range (m) a newly placed ward starts with.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			wardConfig.MinRange = cfg.Bind<float>(text, "Min Range", minRange, new ConfigDescription("Smallest range (m) players can set in the ward's panel.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			wardConfig.MaxRange = cfg.Bind<float>(text, "Max Range", maxRange, new ConfigDescription("Largest range (m) players can set in the ward's panel.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			wardConfig.Color = cfg.Bind<Color>(text, "Glow Color", color, "Color of the ward's magic lines, glow and icon. Client-side. Requires a restart.");
			return wardConfig;
		}
	}
}
namespace WardsPlus.Components
{
	internal static class ContainerRegistry
	{
		internal sealed class Entry
		{
			public Container Container;

			public ZNetView View;

			public Piece Piece;

			public string Prefab;

			public bool IsGatheringWard;

			public string DisplayName
			{
				get
				{
					string text = ((Object.op_Implicit((Object)(object)Piece) && !string.IsNullOrEmpty(Piece.m_name)) ? Piece.m_name : Container.m_name);
					return Localization.instance.Localize(text);
				}
			}
		}

		private static readonly List<Entry> s_entries = new List<Entry>();

		private static readonly HashSet<Container> s_tracked = new HashSet<Container>();

		private static readonly HashSet<ZNetView> s_views = new HashSet<ZNetView>();

		private static ZNetScene s_seededFor;

		public static int Version { get; private set; }

		public static List<Entry> Entries
		{
			get
			{
				EnsureSeeded();
				for (int num = s_entries.Count - 1; num >= 0; num--)
				{
					if (!Object.op_Implicit((Ob