Decompiled source of Wagonborn v1.3.3

Wagonborn.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("blackhearthx")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Your wagon is a truck now.")]
[assembly: AssemblyFileVersion("1.3.3.0")]
[assembly: AssemblyInformationalVersion("1.3.3+a1cf276b77986285ccfe81360dc321bb19dc61a4")]
[assembly: AssemblyProduct("Wagonborn")]
[assembly: AssemblyTitle("Wagonborn")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.3.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 Wagonborn
{
	[HarmonyPatch]
	internal static class CartCrew
	{
		private const string BetterCartsGuid = "TastyChickenLegs.BetterCarts";

		private static bool? _betterCartsPresent;

		private static readonly List<Player> PlayerBuffer = new List<Player>();

		internal static bool OwnCrewActive()
		{
			if (!_betterCartsPresent.HasValue)
			{
				_betterCartsPresent = Chainloader.PluginInfos != null && Chainloader.PluginInfos.ContainsKey("TastyChickenLegs.BetterCarts");
				if (_betterCartsPresent == true)
				{
					Logger.LogInfo((object)"Wagonborn: BetterCarts detected — buddy mass deferred to it (Hauling XP for helpers still runs).");
				}
			}
			return _betterCartsPresent != true;
		}

		internal static int CountHelpers(Vagon cart)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cart == (Object)null || !PluginConfig.EnableBuddyHelp.Value || !cart.IsAttached())
			{
				return 0;
			}
			PlayerBuffer.Clear();
			Player.GetPlayersInRange(((Component)cart).transform.position, PluginConfig.BuddyRange.Value, PlayerBuffer);
			int num = 0;
			bool flag = false;
			for (int i = 0; i < PlayerBuffer.Count; i++)
			{
				Player val = PlayerBuffer[i];
				if (!((Object)(object)val == (Object)null))
				{
					if (cart.IsAttached((Character)(object)val))
					{
						flag = true;
					}
					else
					{
						num++;
					}
				}
			}
			bool flag2 = (Object)(object)cart.m_nview != (Object)null && cart.m_nview.IsOwner();
			if (!flag && !flag2 && num > 0)
			{
				num--;
			}
			return Mathf.Min(num, PluginConfig.MaxBuddies.Value);
		}

		internal static float GetBuddyMassMultiplier(Vagon cart)
		{
			if (!OwnCrewActive() || !PluginConfig.EnableBuddyHelp.Value)
			{
				return 1f;
			}
			int num = CountHelpers(cart);
			if (num <= 0)
			{
				return 1f;
			}
			float num2 = (float)num * Mathf.Clamp01(PluginConfig.BuddyMassReduction.Value);
			return Mathf.Max(0.1f, 1f - num2);
		}

		internal static Vagon FindCartBeingHelped(Player local)
		{
			//IL_005a: 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)
			if ((Object)(object)local == (Object)null || !PluginConfig.EnableBuddyHelp.Value)
			{
				return null;
			}
			float value = PluginConfig.BuddyRange.Value;
			List<Vagon> instances = Vagon.m_instances;
			Vagon result = null;
			float num = value;
			for (int i = 0; i < instances.Count; i++)
			{
				Vagon val = instances[i];
				if (!((Object)(object)val == (Object)null) && val.IsAttached() && !val.IsAttached((Character)(object)local))
				{
					float num2 = Vector3.Distance(((Component)local).transform.position, ((Component)val).transform.position);
					if (num2 <= num)
					{
						num = num2;
						result = val;
					}
				}
			}
			return result;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Vagon), "CanAttach")]
		private static bool CanAttachPrefix(Vagon __instance, GameObject go, ref bool __result)
		{
			//IL_0064: 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_0088: 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)
			if (!OwnCrewActive() || !PluginConfig.AllowOutOfPlaceAttach.Value)
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)go != (Object)(object)((Component)localPlayer).gameObject || (Object)(object)__instance == (Object)null || (Object)(object)__instance.m_attachPoint == (Object)null)
			{
				return true;
			}
			if (__instance.IsAttached((Character)(object)localPlayer) || __instance.IsAttached())
			{
				return true;
			}
			if (((Component)__instance).transform.up.y < 0.1f)
			{
				return true;
			}
			float num = Vector3.Distance(go.transform.position + __instance.m_attachOffset, __instance.m_attachPoint.position);
			__result = !((Character)localPlayer).IsTeleporting() && !((Character)localPlayer).InDodge() && num < PluginConfig.AttachDistance.Value;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class CartMapPin
	{
		private sealed class TrackedPin
		{
			public Vagon Cart;

			public PinData Pin;

			public Minimap Map;
		}

		private struct Pending
		{
			public bool Hidden;

			public float Until;
		}

		private const string HiddenKeyPrefix = "Wagonborn_PinHidden_";

		private const string RpcSetHidden = "Wagonborn_SetPinHidden";

		private const string CartPrefab = "Cart";

		private const float PinUiScale = 0.85f;

		private const float ResyncInterval = 0.5f;

		private const float PendingHold = 3f;

		private static readonly Dictionary<ZDOID, TrackedPin> Pins = new Dictionary<ZDOID, TrackedPin>();

		private static readonly Dictionary<ZDOID, Vagon> Loaded = new Dictionary<ZDOID, Vagon>();

		private static readonly HashSet<ZDOID> WorldCarts = new HashSet<ZDOID>();

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

		private static readonly List<ZDOID> ScratchRemove = new List<ZDOID>();

		private static readonly List<ZDO> ScanBuffer = new List<ZDO>();

		private static readonly Dictionary<ZDOID, Pending> PendingChoice = new Dictionary<ZDOID, Pending>();

		private static FieldRef<Minimap, bool> s_pinUpdateRequired;

		private static Sprite _wheelSprite;

		private static float _resyncAt;

		private static int _scanIndex;

		internal static bool IsEnabled()
		{
			if (PluginConfig.EnableCartMapPin != null)
			{
				return PluginConfig.EnableCartMapPin.Value;
			}
			return false;
		}

		private static string HiddenKey(long playerId)
		{
			return "Wagonborn_PinHidden_" + playerId;
		}

		private static bool IsHiddenForMe(ZDO zdo)
		{
			//IL_001a: 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)
			Player localPlayer = Player.m_localPlayer;
			if (zdo == null || (Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			if (PendingChoice.TryGetValue(zdo.m_uid, out var value))
			{
				if (Time.time < value.Until)
				{
					return value.Hidden;
				}
				PendingChoice.Remove(zdo.m_uid);
			}
			return zdo.GetBool(HiddenKey(localPlayer.GetPlayerID()), false);
		}

		internal static bool IsMarked(Vagon cart)
		{
			if ((Object)(object)cart == (Object)null || (Object)(object)cart.m_nview == (Object)null || !cart.m_nview.IsValid())
			{
				return false;
			}
			return !IsHiddenForMe(cart.m_nview.GetZDO());
		}

		internal static void ToggleMarked(Vagon cart)
		{
			//IL_0050: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (IsEnabled() && !((Object)(object)cart == (Object)null) && !((Object)(object)localPlayer == (Object)null) && !((Object)(object)cart.m_nview == (Object)null) && cart.m_nview.IsValid())
			{
				bool flag = !IsMarked(cart);
				ZDOID uid = cart.m_nview.GetZDO().m_uid;
				PendingChoice[uid] = new Pending
				{
					Hidden = !flag,
					Until = Time.time + 3f
				};
				cart.m_nview.InvokeRPC("Wagonborn_SetPinHidden", new object[2]
				{
					localPlayer.GetPlayerID(),
					!flag
				});
				_resyncAt = 0f;
				string text = (flag ? "$wagonborn_mappin_on" : "$wagonborn_mappin_off");
				string text2 = ((Localization.instance != null) ? Localization.instance.Localize(text) : (flag ? "On the map" : "Off the map"));
				((Character)localPlayer).Message((MessageType)2, text2, 0, (Sprite)null, false);
			}
		}

		private static void RPC_SetHidden(Vagon cart, long playerId, bool hidden)
		{
			if (!((Object)(object)cart == (Object)null) && !((Object)(object)cart.m_nview == (Object)null) && cart.m_nview.IsValid() && cart.m_nview.IsOwner())
			{
				ZDO zDO = cart.m_nview.GetZDO();
				string text = HiddenKey(playerId);
				if (hidden)
				{
					zDO.Set(text, true);
				}
				else if (zDO.GetBool(text, false))
				{
					zDO.Set(text, false);
				}
			}
		}

		internal static void Tick()
		{
			if (!IsEnabled())
			{
				ClearAll();
				return;
			}
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || ZDOMan.instance == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				ClearAll();
				return;
			}
			if (Time.time >= _resyncAt)
			{
				_resyncAt = Time.time + 0.5f;
				AdvanceWorldScan();
				Resync(instance);
			}
			UpdatePinPositions(instance);
		}

		internal static void LateTickUi()
		{
			if (!IsEnabled() || Pins.Count == 0)
			{
				return;
			}
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			foreach (TrackedPin value in Pins.Values)
			{
				if (value?.Pin != null)
				{
					ApplyWheelIcon(value.Pin);
					ApplyPinUiSize(value.Pin, instance);
				}
			}
		}

		private static void AdvanceWorldScan()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			bool allZDOsWithPrefabIterative;
			try
			{
				allZDOsWithPrefabIterative = ZDOMan.instance.GetAllZDOsWithPrefabIterative("Cart", ScanBuffer, ref _scanIndex);
			}
			catch
			{
				ScanBuffer.Clear();
				_scanIndex = 0;
				return;
			}
			if (!allZDOsWithPrefabIterative)
			{
				return;
			}
			WorldCarts.Clear();
			for (int i = 0; i < ScanBuffer.Count; i++)
			{
				ZDO val = ScanBuffer[i];
				if (val != null && val.IsValid())
				{
					WorldCarts.Add(val.m_uid);
				}
			}
			ScanBuffer.Clear();
			_scanIndex = 0;
		}

		private static void Resync(Minimap map)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			Loaded.Clear();
			Wanted.Clear();
			List<Vagon> instances = Vagon.m_instances;
			for (int i = 0; i < instances.Count; i++)
			{
				Vagon val = instances[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.m_nview == (Object)null) && val.m_nview.IsValid())
				{
					ZDO zDO = val.m_nview.GetZDO();
					Loaded[zDO.m_uid] = val;
					if (!IsHiddenForMe(zDO))
					{
						Wanted.Add(zDO.m_uid);
					}
				}
			}
			foreach (ZDOID worldCart in WorldCarts)
			{
				if (!Wanted.Contains(worldCart) && !Loaded.ContainsKey(worldCart))
				{
					ZDO zDO2 = ZDOMan.instance.GetZDO(worldCart);
					if (zDO2 != null && zDO2.IsValid() && !IsHiddenForMe(zDO2))
					{
						Wanted.Add(worldCart);
					}
				}
			}
			ScratchRemove.Clear();
			foreach (KeyValuePair<ZDOID, TrackedPin> pin in Pins)
			{
				if (!Wanted.Contains(pin.Key) || (Object)(object)pin.Value.Map != (Object)(object)map)
				{
					ScratchRemove.Add(pin.Key);
				}
			}
			for (int j = 0; j < ScratchRemove.Count; j++)
			{
				RemoveTracked(ScratchRemove[j]);
			}
			foreach (ZDOID item in Wanted)
			{
				Loaded.TryGetValue(item, out var value);
				Vector3 pos;
				if (Pins.TryGetValue(item, out var value2))
				{
					value2.Cart = value;
				}
				else if (TryGetPosition(item, value, out pos))
				{
					AddPin(item, value, pos, map);
				}
			}
		}

		private static bool TryGetPosition(ZDOID id, Vagon cart, out Vector3 pos)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cart != (Object)null && Object.op_Implicit((Object)(object)cart))
			{
				pos = ((Component)cart).transform.position;
				return true;
			}
			ZDO val = ((ZDOMan.instance != null) ? ZDOMan.instance.GetZDO(id) : null);
			if (val != null && val.IsValid())
			{
				pos = val.GetPosition();
				return true;
			}
			pos = Vector3.zero;
			return false;
		}

		private static void AddPin(ZDOID id, Vagon cart, Vector3 pos, Minimap map)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			string text = ((Localization.instance != null) ? Localization.instance.Localize("$wagonborn_mappin_name") : "Cart");
			try
			{
				PinData val = map.AddPin(pos, (PinType)3, text, false, false, 0L, default(PlatformUserID));
				val.m_doubleSize = false;
				ApplyWheelIcon(val);
				ApplyPinUiSize(val, map);
				RequestPinUiRefresh(map);
				Pins[id] = new TrackedPin
				{
					Cart = cart,
					Pin = val,
					Map = map
				};
			}
			catch
			{
			}
		}

		private static void UpdatePinPositions(Minimap map)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			ScratchRemove.Clear();
			bool flag = false;
			foreach (KeyValuePair<ZDOID, TrackedPin> pin in Pins)
			{
				TrackedPin value = pin.Value;
				Vector3 pos;
				if (value?.Pin == null || (Object)(object)value.Map != (Object)(object)map)
				{
					ScratchRemove.Add(pin.Key);
				}
				else if (!TryGetPosition(pin.Key, value.Cart, out pos))
				{
					ScratchRemove.Add(pin.Key);
				}
				else if (value.Pin.m_pos != pos)
				{
					value.Pin.m_pos = pos;
					flag = true;
				}
			}
			for (int i = 0; i < ScratchRemove.Count; i++)
			{
				RemoveTracked(ScratchRemove[i]);
			}
			if (flag)
			{
				RequestPinUiRefresh(map);
			}
		}

		private static void RemoveTracked(ZDOID id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!Pins.TryGetValue(id, out var value))
			{
				return;
			}
			Pins.Remove(id);
			if (value?.Pin == null || !((Object)(object)Minimap.instance != (Object)null))
			{
				return;
			}
			try
			{
				Minimap.instance.RemovePin(value.Pin);
				RequestPinUiRefresh(Minimap.instance);
			}
			catch
			{
			}
		}

		private static void ClearAll()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (Pins.Count == 0)
			{
				return;
			}
			ScratchRemove.Clear();
			foreach (ZDOID key in Pins.Keys)
			{
				ScratchRemove.Add(key);
			}
			for (int i = 0; i < ScratchRemove.Count; i++)
			{
				RemoveTracked(ScratchRemove[i]);
			}
		}

		private static void RequestPinUiRefresh(Minimap map)
		{
			if ((Object)(object)map == (Object)null)
			{
				return;
			}
			if (s_pinUpdateRequired == null)
			{
				try
				{
					s_pinUpdateRequired = AccessTools.FieldRefAccess<Minimap, bool>("m_pinUpdateRequired");
				}
				catch
				{
					s_pinUpdateRequired = null;
				}
			}
			if (s_pinUpdateRequired != null)
			{
				s_pinUpdateRequired.Invoke(map) = true;
			}
		}

		private static void ApplyWheelIcon(PinData pin)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (pin == null)
			{
				return;
			}
			Sprite orCreateWheelSprite = GetOrCreateWheelSprite();
			if (!((Object)(object)orCreateWheelSprite == (Object)null))
			{
				pin.m_doubleSize = false;
				pin.m_icon = orCreateWheelSprite;
				if ((Object)(object)pin.m_iconElement != (Object)null)
				{
					pin.m_iconElement.sprite = orCreateWheelSprite;
					((Graphic)pin.m_iconElement).color = Color.white;
				}
			}
		}

		private static void ApplyPinUiSize(PinData pin, Minimap map)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			if (!((Object)(object)pin?.m_uiElement == (Object)null) && !((Object)(object)map == (Object)null))
			{
				float num = (((int)map.m_mode == 2) ? map.m_pinSizeLarge : map.m_pinSizeSmall) * 0.85f;
				pin.m_uiElement.SetSizeWithCurrentAnchors((Axis)0, num);
				pin.m_uiElement.SetSizeWithCurrentAnchors((Axis)1, num);
			}
		}

		private static Sprite GetOrCreateWheelSprite()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_wheelSprite != (Object)null)
			{
				return _wheelSprite;
			}
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			float num = 15.5f;
			float num2 = 15.5f;
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.78f, 0.52f, 0.22f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.55f, 0.34f, 0.14f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.62f, 0.62f, 0.66f, 1f);
			Color clear = Color.clear;
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					float num3 = (float)j - num;
					float num4 = (float)i - num2;
					float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4);
					Color val5 = clear;
					if (num5 < 14.5f && num5 > 11.5f)
					{
						val5 = val2;
					}
					else if (num5 <= 11.5f && num5 > 3.5f)
					{
						val5 = ((Mathf.Abs(Mathf.Sin(Mathf.Atan2(num4, num3) * 4f)) > 0.72f) ? val3 : clear);
					}
					if (num5 <= 3.5f)
					{
						val5 = val4;
					}
					if (num5 <= 1.4f)
					{
						((Color)(ref val5))..ctor(0.22f, 0.22f, 0.24f, 1f);
					}
					val.SetPixel(j, i, val5);
				}
			}
			val.Apply(false, true);
			_wheelSprite = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f);
			((Object)_wheelSprite).name = "Wagonborn_MapWheel";
			return _wheelSprite;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Vagon), "Awake")]
		private static void VagonAwakePostfix(Vagon __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.GetZDO() != null)
			{
				Vagon cart = __instance;
				cart.m_nview.Register<long, bool>("Wagonborn_SetPinHidden", (Action<long, long, bool>)delegate(long sender, long playerId, bool hidden)
				{
					RPC_SetHidden(cart, playerId, hidden);
				});
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Vagon), "Interact")]
		private static bool InteractPrefix(Vagon __instance, Humanoid character, bool hold, bool alt)
		{
			if (!alt || hold || !IsEnabled() || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)character != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			ToggleMarked(__instance);
			return false;
		}
	}
	internal static class CartMass
	{
		internal static float GetMultiplier(Player player)
		{
			float level = HaulingSkill.GetLevel(player);
			float num = Mathf.Clamp01(PluginConfig.MaxSkillMassReduction.Value) * (level / 100f);
			return 1f - num;
		}

		internal static int GetPullWeightPercent(Player player)
		{
			return Mathf.RoundToInt(GetMultiplier(player) * 100f);
		}
	}
	[HarmonyPatch(typeof(Vagon))]
	internal static class CartPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("SetMass")]
		private static void SetMassPrefix(Vagon __instance, ref float mass)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsOwner())
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null && __instance.IsAttached((Character)(object)localPlayer))
				{
					mass *= CartMass.GetMultiplier(localPlayer);
				}
				mass *= CartCrew.GetBuddyMassMultiplier(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("AttachTo")]
		private static void AttachToPostfix(Vagon __instance)
		{
			RefreshMass(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Detach")]
		private static void DetachPostfix(Vagon __instance)
		{
			RefreshMass(__instance);
		}

		private static void RefreshMass(Vagon cart)
		{
			if (!((Object)(object)cart == (Object)null) && !((Object)(object)cart.m_nview == (Object)null) && cart.m_nview.IsValid() && cart.m_nview.IsOwner())
			{
				cart.UpdateMass();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverTextPostfix(Vagon __instance, ref string __result)
		{
			if (!((Object)(object)__instance == (Object)null) && !string.IsNullOrEmpty(__result))
			{
				Player localPlayer = Player.m_localPlayer;
				string text = Mathf.FloorToInt(HaulingSkill.GetLevel(localPlayer)).ToString();
				string text2 = CartMass.GetPullWeightPercent(localPlayer).ToString();
				__result = __result + "\n" + L("$wagonborn_hover", text, text2);
				if (CartPortal.IsActive() && (Object)(object)localPlayer != (Object)null && __instance.IsAttached((Character)(object)localPlayer))
				{
					__result = __result + "\n" + L("$wagonborn_cart_portal_hint");
				}
				int num = CartCrew.CountHelpers(__instance);
				if (num > 0)
				{
					__result = __result + "\n" + L("$wagonborn_buddy_hover", num.ToString());
				}
				if (CartMapPin.IsEnabled())
				{
					__result = __result + "\n" + (CartMapPin.IsMarked(__instance) ? L("$wagonborn_mappin_hover_on") : L("$wagonborn_mappin_hover_off"));
				}
			}
		}

		private static string L(string key, params string[] args)
		{
			if (Localization.instance == null)
			{
				return key;
			}
			if (args == null || args.Length == 0)
			{
				return Localization.instance.Localize(key);
			}
			return Localization.instance.Localize(key, args);
		}
	}
	[HarmonyPatch]
	internal static class CartPortal
	{
		private const float ExitExtraDistance = 3f;

		private const string TeleportEverythingGuid = "zenox.teleporteverything";

		private static readonly Collider[] ColliderBuffer = (Collider[])(object)new Collider[512];

		private static readonly Action<Vagon, GameObject> AttachTo = AccessTools.MethodDelegate<Action<Vagon, GameObject>>(AccessTools.Method(typeof(Vagon), "AttachTo", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Vagon, GameObject, bool> CanAttach = AccessTools.MethodDelegate<Func<Vagon, GameObject, bool>>(AccessTools.Method(typeof(Vagon), "CanAttach", (Type[])null, (Type[])null), (object)null, true);

		private static readonly HashSet<Vagon> SeenBuffer = new HashSet<Vagon>();

		private static ZDOID? _pendingReattachCartId;

		private static Vagon _pendingCart;

		private static bool? _teleportEverythingPresent;

		internal static bool IsActive()
		{
			if (PluginConfig.EnableCartPortal.Value)
			{
				return !TeleportEverythingPresent();
			}
			return false;
		}

		private static bool TeleportEverythingPresent()
		{
			if (!_teleportEverythingPresent.HasValue)
			{
				_teleportEverythingPresent = Chainloader.PluginInfos != null && Chainloader.PluginInfos.ContainsKey("zenox.teleporteverything");
				if (_teleportEverythingPresent == true)
				{
					Logger.LogInfo((object)"Wagonborn: TeleportEverything detected — cart portal transport deferred to it.");
				}
			}
			return _teleportEverythingPresent == true;
		}

		private static Vagon FindAttachedCart(Vector3 pos, Character player)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(pos, PluginConfig.CartSearchRadius.Value, ColliderBuffer);
			Vagon result = null;
			SeenBuffer.Clear();
			for (int i = 0; i < num; i++)
			{
				if (!((Object)(object)ColliderBuffer[i] == (Object)null))
				{
					Vagon componentInParent = ((Component)ColliderBuffer[i]).GetComponentInParent<Vagon>();
					if (!((Object)(object)componentInParent == (Object)null) && SeenBuffer.Add(componentInParent) && componentInParent.IsAttached(player))
					{
						result = componentInParent;
						break;
					}
				}
			}
			return result;
		}

		private static Vagon FindCartByZdoid(Vector3 pos, ZDOID id)
		{
			//IL_0000: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(pos, PluginConfig.CartSearchRadius.Value, ColliderBuffer);
			for (int i = 0; i < num; i++)
			{
				if ((Object)(object)ColliderBuffer[i] == (Object)null)
				{
					continue;
				}
				Vagon componentInParent = ((Component)ColliderBuffer[i]).GetComponentInParent<Vagon>();
				if (!((Object)(object)componentInParent == (Object)null))
				{
					ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
					if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().m_uid == id)
					{
						return componentInParent;
					}
				}
			}
			return null;
		}

		private static void PlaceCartForAttach(Vagon cart, Vector3 referencePos, Quaternion referenceRot)
		{
			//IL_001e: 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_002e: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0067: 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)
			//IL_0071: 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_00a0: 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_00ad: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cart == (Object)null || (Object)(object)cart.m_attachPoint == (Object)null)
			{
				return;
			}
			Vector3 val = Quaternion.Inverse(((Component)cart).transform.rotation) * (cart.m_attachPoint.position - ((Component)cart).transform.position);
			Vector3 val2 = referencePos + cart.m_attachOffset - referenceRot * val - ((Component)cart).transform.position;
			Rigidbody component = ((Component)cart).GetComponent<Rigidbody>();
			Rigidbody[] componentsInChildren = ((Component)cart).GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody val3 in componentsInChildren)
			{
				val3.isKinematic = true;
				Transform transform = ((Component)val3).transform;
				transform.position += val2;
				val3.linearVelocity = Vector3.zero;
				val3.angularVelocity = Vector3.zero;
				if ((Object)(object)val3 == (Object)(object)component)
				{
					((Component)val3).transform.rotation = referenceRot;
				}
			}
			((Component)cart).transform.rotation = referenceRot;
			Physics.SyncTransforms();
		}

		private static void TransportAttachedCart(Vector3 fromPos, Player player, Vector3 targetPos, Quaternion targetRot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			Vagon val = FindAttachedCart(fromPos, (Character)(object)player);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			if (!component.IsOwner())
			{
				component.ClaimOwnership();
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				PlaceCartForAttach(val, targetPos, targetRot);
				zDO.SetPosition(((Component)val).transform.position);
				_pendingReattachCartId = zDO.m_uid;
				_pendingCart = val;
				Logger.LogInfo((object)$"Wagonborn: cart '{((Object)val).name}' teleported with player to {((Component)val).transform.position}");
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)1, (Localization.instance != null) ? Localization.instance.Localize("$wagonborn_cart_portal") : "Cart travels with you", 0, (Sprite)null, false, true);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static void TeleportToClearancePrefix(Player __instance, ref Vector3 pos, Quaternion rot)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (IsActive() && !((Object)(object)__instance == (Object)null) && !((Object)(object)FindAttachedCart(((Component)__instance).transform.position, (Character)(object)__instance) == (Object)null))
			{
				pos += rot * Vector3.forward * 3f;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static void TeleportToTransportPostfix(Player __instance, Vector3 pos, Quaternion rot, bool __result)
		{
			//IL_001a: 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)
			if (__result && IsActive() && !((Object)(object)__instance == (Object)null))
			{
				TransportAttachedCart(((Component)__instance).transform.position, __instance, pos, rot);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		private static void UpdateTeleportReattachPostfix(Player __instance, bool ___m_teleporting)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if (___m_teleporting || !_pendingReattachCartId.HasValue || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			ZDOID value = _pendingReattachCartId.Value;
			Vagon pendingCart = _pendingCart;
			_pendingReattachCartId = null;
			_pendingCart = null;
			Vagon val = FindCartByZdoid(((Component)__instance).transform.position, value);
			if ((Object)(object)val == (Object)null && (Object)(object)pendingCart != (Object)null && Object.op_Implicit((Object)(object)pendingCart))
			{
				val = pendingCart;
			}
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogInfo((object)"Wagonborn: cart reattach skipped — cart not found after teleport.");
				return;
			}
			PlaceCartForAttach(val, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation);
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				ZDO zDO = component.GetZDO();
				if (zDO != null)
				{
					zDO.SetPosition(((Component)val).transform.position);
				}
			}
			if (CanAttach != null && AttachTo != null && CanAttach(val, ((Component)__instance).gameObject))
			{
				AttachTo(val, ((Component)__instance).gameObject);
				Logger.LogInfo((object)("Wagonborn: re-attached cart '" + ((Object)val).name + "' after portal."));
			}
			else
			{
				Logger.LogInfo((object)("Wagonborn: could not re-attach cart '" + ((Object)val).name + "' (CanAttach failed)."));
			}
			Rigidbody[] componentsInChildren = ((Component)val).GetComponentsInChildren<Rigidbody>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].isKinematic = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Vagon), "Update")]
		private static void VagonUpdatePreventDetachPrefix(Vagon __instance, out float __state)
		{
			__state = (((Object)(object)__instance != (Object)null) ? __instance.m_detachDistance : 0f);
			if (PluginConfig.PreventCartAutoDetach.Value && !TeleportEverythingPresent() && !((Object)(object)__instance == (Object)null))
			{
				float detachDistance = Mathf.Max(__state, PluginConfig.AttachLeash.Value);
				__instance.m_detachDistance = detachDistance;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Vagon), "Update")]
		private static void VagonUpdatePreventDetachPostfix(Vagon __instance, float __state)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				__instance.m_detachDistance = __state;
			}
		}
	}
	internal static class HaulingProgress
	{
		private const float RescanInterval = 0.5f;

		private const float MaxPlausibleSpeed = 20f;

		private static Vagon _cart;

		private static bool _pulling;

		private static Vector3 _lastPos;

		private static float _speed;

		private static float _rescanAt;

		internal static void Tick()
		{
			//IL_0000: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			if ((int)HaulingSkill.SkillType == 0)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				SetCart(null, pulling: false);
				return;
			}
			if (!IsStillEarning(localPlayer))
			{
				if (Time.time < _rescanAt)
				{
					return;
				}
				_rescanAt = Time.time + 0.5f;
				Vagon val = FindAttachedCart(localPlayer);
				if ((Object)(object)val != (Object)null)
				{
					SetCart(val, pulling: true);
				}
				else
				{
					SetCart(CartCrew.FindCartBeingHelped(localPlayer), pulling: false);
				}
				if ((Object)(object)_cart == (Object)null)
				{
					return;
				}
			}
			float deltaTime = Time.deltaTime;
			if (!(deltaTime <= 0f))
			{
				Vector3 position = ((Component)_cart).transform.position;
				float num = Vector3.Distance(position, _lastPos) / deltaTime;
				_lastPos = position;
				if (num > 20f)
				{
					num = 0f;
				}
				_speed = Mathf.Lerp(_speed, num, 0.2f);
				if (!(_speed < PluginConfig.MinSpeedForXp.Value))
				{
					float num2 = CartLoadMass(_cart);
					float num3 = Mathf.Max(1f, num2 / Mathf.Max(1f, PluginConfig.LoadXpScale.Value));
					float num4 = (_pulling ? 1f : PluginConfig.BuddyXpMultiplier.Value);
					((Character)localPlayer).RaiseSkill(HaulingSkill.SkillType, PluginConfig.XpPerSecond.Value * deltaTime * num3 * num4);
				}
			}
		}

		internal static float CartLoadMass(Vagon cart)
		{
			float num = cart.m_baseMass;
			Inventory val = (((Object)(object)cart.m_container != (Object)null) ? cart.m_container.GetInventory() : null);
			if (val != null)
			{
				num += val.GetTotalWeight() * cart.m_itemWeightMassFactor;
			}
			return num;
		}

		private static bool IsStillEarning(Player player)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_cart == (Object)null || !Object.op_Implicit((Object)(object)_cart))
			{
				return false;
			}
			if (_pulling)
			{
				return _cart.IsAttached((Character)(object)player);
			}
			if (PluginConfig.EnableBuddyHelp.Value && _cart.IsAttached() && !_cart.IsAttached((Character)(object)player))
			{
				return Vector3.Distance(((Component)player).transform.position, ((Component)_cart).transform.position) <= PluginConfig.BuddyRange.Value;
			}
			return false;
		}

		private static void SetCart(Vagon cart, bool pulling)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cart != (Object)(object)_cart)
			{
				_speed = 0f;
				if ((Object)(object)cart != (Object)null)
				{
					_lastPos = ((Component)cart).transform.position;
				}
			}
			_cart = cart;
			_pulling = pulling;
		}

		private static Vagon FindAttachedCart(Player player)
		{
			List<Vagon> instances = Vagon.m_instances;
			for (int i = 0; i < instances.Count; i++)
			{
				Vagon val = instances[i];
				if ((Object)(object)val != (Object)null && val.IsAttached((Character)(object)player))
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class HaulingSkill
	{
		internal const string Identifier = "com.blackhearthx.wagonborn.hauling";

		internal static SkillType SkillType { get; private set; }

		internal static void Register()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
		}

		private static void OnVanillaPrefabsAvailable()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_004b: 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_006f: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			SkillType = SkillManager.Instance.AddSkill(new SkillConfig
			{
				Identifier = "com.blackhearthx.wagonborn.hauling",
				Name = "$skill_wagonborn_hauling",
				Description = "$skill_wagonborn_hauling_desc",
				IncreaseStep = 1f,
				Icon = (FindCartIcon() ?? CreateWheelIcon())
			});
		}

		internal static float GetLevel(Player player)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (int)SkillType == 0)
			{
				return 0f;
			}
			return ((Character)player).GetSkillFactor(SkillType) * 100f;
		}

		private static Sprite FindCartIcon()
		{
			string[] array = new string[3] { "Cart", "piece_cart", "CartWood" };
			for (int i = 0; i < array.Length; i++)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(array[i]);
				if (!((Object)(object)prefab == (Object)null))
				{
					Piece component = prefab.GetComponent<Piece>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.m_icon != (Object)null)
					{
						return component.m_icon;
					}
				}
			}
			return null;
		}

		private static Sprite CreateWheelIcon()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)5, false);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			float num = 31.5f;
			float num2 = 31.5f;
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.45f, 0.28f, 0.12f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.72f, 0.5f, 0.26f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.55f, 0.55f, 0.58f, 1f);
			Color clear = Color.clear;
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num3 = (float)j - num;
					float num4 = (float)i - num2;
					float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4);
					Color val5 = clear;
					if (num5 < 30f && num5 > 24f)
					{
						val5 = val2;
					}
					else if (num5 <= 24f && num5 > 8f)
					{
						val5 = ((Mathf.Abs(Mathf.Sin(Mathf.Atan2(num4, num3) * 4f)) > 0.72f) ? val3 : clear);
					}
					if (num5 <= 8f)
					{
						val5 = val4;
					}
					if (num5 <= 3.2f)
					{
						((Color)(ref val5))..ctor(0.25f, 0.25f, 0.27f, 1f);
					}
					val.SetPixel(j, i, val5);
				}
			}
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f);
		}
	}
	[HarmonyPatch]
	internal static class HaulingSkillBackup
	{
		private const string BackupKey = "Wagonborn_HaulingBackup";

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "Save")]
		private static void SavePrefix(Player __instance)
		{
			//IL_001c: 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)
			Skills val = (((Object)(object)__instance != (Object)null) ? __instance.m_skills : null);
			if (!((Object)(object)val == (Object)null) && (int)HaulingSkill.SkillType != 0)
			{
				float num = 0f;
				float num2 = 0f;
				if (val.m_skillData.TryGetValue(HaulingSkill.SkillType, out var value) && value != null)
				{
					num = value.m_level;
					num2 = value.m_accumulator;
				}
				__instance.m_customData["Wagonborn_HaulingBackup"] = num.ToString("R", CultureInfo.InvariantCulture) + "|" + num2.ToString("R", CultureInfo.InvariantCulture);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "Load")]
		private static void LoadPostfix(Player __instance)
		{
			//IL_001c: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			Skills val = (((Object)(object)__instance != (Object)null) ? __instance.m_skills : null);
			if ((Object)(object)val == (Object)null || (int)HaulingSkill.SkillType == 0 || !__instance.m_customData.TryGetValue("Wagonborn_HaulingBackup", out var value) || !TryParse(value, out var level, out var accumulator) || level <= 0f)
			{
				return;
			}
			val.m_skillData.TryGetValue(HaulingSkill.SkillType, out var value2);
			if (value2 == null || !(value2.m_level >= level))
			{
				Skill val2 = value2 ?? val.GetSkill(HaulingSkill.SkillType);
				if (val2 != null)
				{
					float num = value2?.m_level ?? 0f;
					val2.m_level = level;
					val2.m_accumulator = accumulator;
					Logger.LogInfo((object)$"Wagonborn: Hauling restored from backup ({num:0.#} -> {level:0.#}).");
				}
			}
		}

		private static bool TryParse(string raw, out float level, out float accumulator)
		{
			level = 0f;
			accumulator = 0f;
			if (string.IsNullOrEmpty(raw))
			{
				return false;
			}
			string[] array = raw.Split(new char[1] { '|' });
			if (!float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out level))
			{
				return false;
			}
			if (array.Length > 1)
			{
				float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out accumulator);
			}
			return true;
		}
	}
	internal static class ModLocalization
	{
		internal static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			Add(localization, "English", "Hauling", "Earned by pulling or helping push a moving cart. Higher Hauling makes carts easier to pull.", "Hauling $1 — pull weight $2%", "Cart travels with you", "Portals take the cart", "Friends nearby lighten the load — and train Hauling");
			Add(localization, "Portuguese_Brazilian", "Carreto", "Sobe puxando ou ajudando a empurrar uma carroça em movimento. Quanto maior o nível, mais leve ela fica.", "Carreto $1 — peso de puxar $2%", "Carroça vem junto", "Portais levam a carroça", "Amigos por perto aliviam o peso — e sobem Carreto");
			Add(localization, "Portuguese_European", "Carreto", "Aumenta ao puxar ou ajudar a empurrar um carro em movimento. Quanto mais alto o nível, mais leve fica.", "Carreto $1 — peso a puxar $2%", "Carro vem consigo", "Portais levam o carro", "Amigos por perto aliviam o peso — e sobem Carreto");
			Add(localization, "Spanish", "Acarrero", "Sube al tirar o ayudar a empujar un carro en movimiento. A más nivel, más fácil de arrastrar.", "Acarrero $1 — peso de tiro $2%", "El carro viaja contigo", "Los portales llevan el carro", "Amigos cerca alivian la carga — y suben Acarrero");
			Add(localization, "French", "Traction", "Augmente en tirant ou en aidant à pousser une charrette en mouvement. Plus le niveau est élevé, plus elle est légère.", "Traction $1 — poids de traction $2%", "La charrette voyage avec vous", "Les portails emportent la charrette", "Les amis proches allègent la charge — et montent Traction");
			Add(localization, "German", "Ziehen", "Steigt, wenn du einen fahrenden Karren ziehst oder mitschiebst. Höheres Level macht ihn leichter.", "Ziehen $1 — Zuggewicht $2%", "Karren reist mit", "Portale nehmen den Karren mit", "Freunde in der Nähe erleichtern die Last — und trainieren Ziehen");
			Add(localization, "Italian", "Traino", "Sale tirando o aiutando a spingere un carro in movimento. Più alto è il livello, più è leggero.", "Traino $1 — peso di traino $2%", "Il carro viaggia con te", "I portali portano il carro", "Amici vicini alleggeriscono il carico — e allenano Traino");
			Add(localization, "Dutch", "Slepen", "Stijgt door een rijdende kar te trekken of mee te duwen. Hoe hoger, hoe lichter de kar.", "Slepen $1 — trekkgewicht $2%", "Kar reist mee", "Portalen nemen de kar mee", "Vrienden in de buurt verlichten de last — en trainen Slepen");
			Add(localization, "Swedish", "Dragning", "Ökar när du drar eller hjälper till att knuffa en vagn i rörelse. Högre nivå gör den lättare.", "Dragning $1 — dragvikt $2%", "Vagnen följer med", "Portaler tar vagnen", "Vänner nära lättar lasten — och tränar Dragning");
			Add(localization, "Polish", "Wożenie", "Rośnie podczas ciągnięcia lub pomocy w pchaniu jadącego wozu. Wyższy poziom ułatwia ciągnięcie.", "Wożenie $1 — ciężar ciągu $2%", "Wóz podróżuje z tobą", "Portale zabierają wóz", "Znajomi w pobliżu odciążają — i trenują Wożenie");
			Add(localization, "Russian", "Возка", "Растёт, когда вы везёте телегу или помогаете толкать. Чем выше навык, тем легче тянуть.", "Возка $1 — вес тяги $2%", "Телега идёт с вами", "Порталы забирают телегу", "Друзья рядом облегчают груз — и качают Возку");
			Add(localization, "Ukrainian", "Перевезення", "Зростає, коли ви тягнете віз або допомагаєте штовхати. Вищий рівень робить його легшим.", "Перевезення $1 — вага тяги $2%", "Віз іде з вами", "Портали забирають віз", "Друзі поруч полегшують вагу — і качають Перевезення");
			Add(localization, "Czech", "Tahání", "Stoupá tažením nebo pomocí tlačení jedoucího vozu. Vyšší úroveň ho odlehčí.", "Tahání $1 — tahová váha $2%", "Vůz cestuje s tebou", "Portály berou vůz", "Přátelé poblíž odlehčí náklad — a trénují Tahání");
			Add(localization, "Hungarian", "Húzás", "Mozgó szekér húzásával vagy tolásával nő. Magasabb szint könnyebbé teszi.", "Húzás $1 — húzósúly $2%", "A szekér veled utazik", "A portálok elviszik a szekeret", "Közeli barátok könnyítik a terhet — és fejlesztik a Húzást");
			Add(localization, "Romanian", "Transport", "Crește trăgând sau ajutând la împins un car în mișcare. Nivelul mai mare îl face mai ușor.", "Transport $1 — greutate de tracțiune $2%", "Carul călătorește cu tine", "Portalurile iau carul", "Prietenii apropiați ușurează sarcina — și antrenează Transport");
			Add(localization, "Turkish", "Çekme", "Hareket halindeki arabayı çekerek veya itmeye yardım ederek artar. Seviye yükseldikçe araba hafifler.", "Çekme $1 — çekiş ağırlığı $2%", "Araba seninle gider", "Portallar arabayı alır", "Yakındaki dostlar yükü hafifletir — ve Çekme yükseltir");
			Add(localization, "Chinese", "拉车", "拉动或帮忙推动行驶中的推车可提升。等级越高,推车越轻。", "拉车 $1 — 牵引重量 $2%", "推车与你同行", "传送门带走推车", "附近的朋友减轻负担 — 也提升拉车");
			Add(localization, "Chinese_Trad", "拉車", "拉動或幫忙推動行進中的推車可提升。等級越高,推車越輕。", "拉車 $1 — 牽引重量 $2%", "推車與你同行", "傳送門帶走推車", "附近的朋友減輕負擔 — 也提升拉車");
			Add(localization, "Japanese", "運搬", "動いている荷車を引く、または押す手伝いをすると上がる。レベルが高いほど引きやすくなる。", "運搬 $1 — 引き重さ $2%", "荷車も一緒に移動", "ポータルで荷車も運ぶ", "近くの仲間が負担を軽くする — 運搬も上がる");
			Add(localization, "Korean", "운반", "움직이는 수레를 끌거나 밀어 도우면 오른다. 레벨이 높을수록 수레가 가벼워진다.", "운반 $1 — 견인 무게 $2%", "수레가 함께 이동", "포털이 수레를 데려감", "근처 친구가 짐을 덜어 줌 — 운반도 오른다");
			AddMapPin(localization, "English", "On the map  [<color=yellow><b>Shift+E</b></color>] hide", "Off the map  [<color=yellow><b>Shift+E</b></color>] show", "On the map", "Off the map", "Cart", "$1 nearby — lighter haul");
			AddMapPin(localization, "Portuguese_Brazilian", "No mapa  [<color=yellow><b>Shift+E</b></color>] tirar", "Fora do mapa  [<color=yellow><b>Shift+E</b></color>] marcar", "No mapa", "Fora do mapa", "Carroça", "$1 por perto — carga mais leve");
			AddMapPin(localization, "Portuguese_European", "No mapa  [<color=yellow><b>Shift+E</b></color>] tirar", "Fora do mapa  [<color=yellow><b>Shift+E</b></color>] marcar", "No mapa", "Fora do mapa", "Carro", "$1 por perto — carga mais leve");
			AddMapPin(localization, "Spanish", "En el mapa  [<color=yellow><b>Shift+E</b></color>] quitar", "Fuera del mapa  [<color=yellow><b>Shift+E</b></color>] marcar", "En el mapa", "Fuera del mapa", "Carro", "$1 cerca — carga más ligera");
			AddMapPin(localization, "French", "Sur la carte  [<color=yellow><b>Shift+E</b></color>] retirer", "Hors carte  [<color=yellow><b>Shift+E</b></color>] afficher", "Sur la carte", "Hors carte", "Charrette", "$1 proches — charge plus légère");
			AddMapPin(localization, "German", "Auf der Karte  [<color=yellow><b>Shift+E</b></color>] ausblenden", "Nicht auf der Karte  [<color=yellow><b>Shift+E</b></color>] zeigen", "Auf der Karte", "Nicht auf der Karte", "Karren", "$1 in der Nähe — leichtere Last");
			AddMapPin(localization, "Italian", "Sulla mappa  [<color=yellow><b>Shift+E</b></color>] nascondi", "Fuori mappa  [<color=yellow><b>Shift+E</b></color>] mostra", "Sulla mappa", "Fuori mappa", "Carro", "$1 vicini — carico più leggero");
			AddMapPin(localization, "Dutch", "Op de kaart  [<color=yellow><b>Shift+E</b></color>] verbergen", "Niet op de kaart  [<color=yellow><b>Shift+E</b></color>] tonen", "Op de kaart", "Niet op de kaart", "Kar", "$1 dichtbij — lichtere vracht");
			AddMapPin(localization, "Swedish", "På kartan  [<color=yellow><b>Shift+E</b></color>] dölj", "Inte på kartan  [<color=yellow><b>Shift+E</b></color>] visa", "På kartan", "Inte på kartan", "Vagn", "$1 nära — lättare last");
			AddMapPin(localization, "Polish", "Na mapie  [<color=yellow><b>Shift+E</b></color>] ukryj", "Poza mapą  [<color=yellow><b>Shift+E</b></color>] pokaż", "Na mapie", "Poza mapą", "Wóz", "$1 w pobliżu — lżejszy ładunek");
			AddMapPin(localization, "Russian", "На карте  [<color=yellow><b>Shift+E</b></color>] скрыть", "Не на карте  [<color=yellow><b>Shift+E</b></color>] показать", "На карте", "Не на карте", "Телега", "Рядом: $1 — груз легче");
			AddMapPin(localization, "Ukrainian", "На мапі  [<color=yellow><b>Shift+E</b></color>] сховати", "Не на мапі  [<color=yellow><b>Shift+E</b></color>] показати", "На мапі", "Не на мапі", "Віз", "Поруч: $1 — вантаж легший");
			AddMapPin(localization, "Czech", "Na mapě  [<color=yellow><b>Shift+E</b></color>] skrýt", "Mimo mapu  [<color=yellow><b>Shift+E</b></color>] zobrazit", "Na mapě", "Mimo mapu", "Vůz", "$1 poblíž — lehčí náklad");
			AddMapPin(localization, "Hungarian", "A térképen  [<color=yellow><b>Shift+E</b></color>] elrejt", "Nincs a térképen  [<color=yellow><b>Shift+E</b></color>] mutat", "A térképen", "Nincs a térképen", "Szekér", "$1 a közelben — könnyebb teher");
			AddMapPin(localization, "Romanian", "Pe hartă  [<color=yellow><b>Shift+E</b></color>] ascunde", "Nu e pe hartă  [<color=yellow><b>Shift+E</b></color>] arată", "Pe hartă", "Nu e pe hartă", "Car", "$1 aproape — încărcătură mai ușoară");
			AddMapPin(localization, "Turkish", "Haritada  [<color=yellow><b>Shift+E</b></color>] gizle", "Haritada değil  [<color=yellow><b>Shift+E</b></color>] göster", "Haritada", "Haritada değil", "Araba", "Yakında $1 kişi — yük hafif");
			AddMapPin(localization, "Chinese", "在地图上  [<color=yellow><b>Shift+E</b></color>] 隐藏", "不在地图上  [<color=yellow><b>Shift+E</b></color>] 显示", "在地图上", "不在地图上", "推车", "附近 $1 人 — 负担更轻");
			AddMapPin(localization, "Chinese_Trad", "在地圖上  [<color=yellow><b>Shift+E</b></color>] 隱藏", "不在地圖上  [<color=yellow><b>Shift+E</b></color>] 顯示", "在地圖上", "不在地圖上", "推車", "附近 $1 人 — 負擔更輕");
			AddMapPin(localization, "Japanese", "地図に表示中  [<color=yellow><b>Shift+E</b></color>] 隠す", "地図に非表示  [<color=yellow><b>Shift+E</b></color>] 表示", "地図に表示", "地図から外した", "荷車", "近くに $1 人 — 荷が軽い");
			AddMapPin(localization, "Korean", "지도에 표시됨  [<color=yellow><b>Shift+E</b></color>] 숨기기", "지도에 없음  [<color=yellow><b>Shift+E</b></color>] 표시", "지도에 표시", "지도에서 숨김", "수레", "근처 $1명 — 짐이 가벼워짐");
		}

		private static void AddMapPin(CustomLocalization loc, string language, string hoverOn, string hoverOff, string on, string off, string name, string buddyHover)
		{
			loc.AddTranslation(ref language, new Dictionary<string, string>
			{
				{ "wagonborn_mappin_hover_on", hoverOn },
				{ "wagonborn_mappin_hover_off", hoverOff },
				{ "wagonborn_mappin_on", on },
				{ "wagonborn_mappin_off", off },
				{ "wagonborn_mappin_name", name },
				{ "wagonborn_buddy_hover", buddyHover }
			});
		}

		private static void Add(CustomLocalization loc, string language, string skill, string description, string hover, string cartPortal, string cartPortalHint, string buddyHint)
		{
			loc.AddTranslation(ref language, new Dictionary<string, string>
			{
				{ "skill_wagonborn_hauling", skill },
				{ "skill_wagonborn_hauling_desc", description },
				{ "wagonborn_hover", hover },
				{ "wagonborn_cart_portal", cartPortal },
				{ "wagonborn_cart_portal_hint", cartPortalHint },
				{ "wagonborn_buddy_hint", buddyHint }
			});
		}
	}
	internal static class PluginConfig
	{
		internal static ConfigEntry<float> MaxSkillMassReduction;

		internal static ConfigEntry<float> XpPerSecond;

		internal static ConfigEntry<float> MinSpeedForXp;

		internal static ConfigEntry<float> LoadXpScale;

		internal static ConfigEntry<bool> EnableCartPortal;

		internal static ConfigEntry<float> CartSearchRadius;

		internal static ConfigEntry<bool> PreventCartAutoDetach;

		internal static ConfigEntry<float> AttachLeash;

		internal static ConfigEntry<float> AttachDistance;

		internal static ConfigEntry<bool> AllowOutOfPlaceAttach;

		internal static ConfigEntry<bool> EnableBuddyHelp;

		internal static ConfigEntry<float> BuddyRange;

		internal static ConfigEntry<int> MaxBuddies;

		internal static ConfigEntry<float> BuddyMassReduction;

		internal static ConfigEntry<float> BuddyXpMultiplier;

		internal static ConfigEntry<bool> EnableCartMapPin;

		internal static void Bind(ConfigFile config)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected O, but got Unknown
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Expected O, but got Unknown
			MaxSkillMassReduction = config.Bind<float>("Hauling", "MaxSkillMassReduction", 0.5f, new ConfigDescription("Cart mass reduction at Hauling 100 (0.50 = 50%). Hills still matter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.8f), Array.Empty<object>()));
			XpPerSecond = config.Bind<float>("Hauling", "XpPerSecond", 0.35f, "Base Hauling XP per second while pulling a moving cart.");
			MinSpeedForXp = config.Bind<float>("Hauling", "MinSpeedForXp", 0.6f, "Cart must move faster than this (m/s) to grant XP.");
			LoadXpScale = config.Bind<float>("Hauling", "LoadXpScale", 240f, new ConfigDescription("A full cart teaches more. XP is multiplied by (cart + cargo weight) / this, never below 1. An empty cart weighs about 20.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 2000f), Array.Empty<object>()));
			EnableCartPortal = config.Bind<bool>("Portal", "EnableCartPortal", true, "Attached cart teleports with you through portals and dungeon rune stones.");
			CartSearchRadius = config.Bind<float>("Portal", "CartSearchRadius", 10f, new ConfigDescription("Meters around the teleport point to find your attached cart.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			PreventCartAutoDetach = config.Bind<bool>("Portal", "PreventCartAutoDetach", true, "While pulling, allow a longer leash before the cart auto-drops (see AttachLeash). Unhitch with Use (E) anytime.");
			AttachLeash = config.Bind<float>("Portal", "AttachLeash", 8f, new ConfigDescription("Max meters from the hitch before auto-detach when PreventCartAutoDetach is on (vanilla is ~2).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 20f), Array.Empty<object>()));
			AttachDistance = config.Bind<float>("Crew", "AttachDistance", 3f, new ConfigDescription("Max meters from the hitch point when attaching with Use (E).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			AllowOutOfPlaceAttach = config.Bind<bool>("Crew", "AllowOutOfPlaceAttach", true, "Allow attach with Use (E) when not perfectly lined up (uses AttachDistance).");
			EnableBuddyHelp = config.Bind<bool>("Crew", "EnableBuddyHelp", true, "Nearby friends lighten a pulled cart. Helpers also earn Hauling XP while it moves.");
			BuddyRange = config.Bind<float>("Crew", "BuddyRange", 5f, new ConfigDescription("Meters around the cart to count as helping.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 12f), Array.Empty<object>()));
			MaxBuddies = config.Bind<int>("Crew", "MaxBuddies", 4, new ConfigDescription("Max helpers (not counting the puller) that reduce mass.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
			BuddyMassReduction = config.Bind<float>("Crew", "BuddyMassReduction", 0.15f, new ConfigDescription("Mass cut per helper (0.15 = 15% each). Stacks up to MaxBuddies.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.4f), Array.Empty<object>()));
			BuddyXpMultiplier = config.Bind<float>("Crew", "BuddyXpMultiplier", 1f, new ConfigDescription("Hauling XP rate for helpers vs the puller (1 = same rate).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 1.5f), Array.Empty<object>()));
			EnableCartMapPin = config.Bind<bool>("Map", "EnableCartMapPin", true, "Every cart shows a live map pin by default. Shift+E on a cart hides or shows that one, just for you.");
		}
	}
	[BepInPlugin("com.blackhearthx.wagonborn", "Wagonborn", "1.3.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class WagonbornPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.blackhearthx.wagonborn";

		public const string PluginName = "Wagonborn";

		public const string PluginVersion = "1.3.3";

		internal static WagonbornPlugin Instance { get; private set; }

		internal static Harmony Harmony { get; private set; }

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			Instance = this;
			PluginConfig.Bind(((BaseUnityPlugin)this).Config);
			ModLocalization.Register();
			HaulingSkill.Register();
			Harmony = new Harmony("com.blackhearthx.wagonborn");
			try
			{
				Harmony.PatchAll(Assembly.GetExecutingAssembly());
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Harmony patch failed: {arg}");
			}
			Logger.LogInfo((object)"Wagonborn 1.3.3 loaded (com.blackhearthx.wagonborn)");
		}

		private void Update()
		{
			HaulingProgress.Tick();
			CartMapPin.Tick();
		}

		private void LateUpdate()
		{
			CartMapPin.LateTickUi();
		}

		private void OnDestroy()
		{
			Harmony harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}