Decompiled source of TorvaldsAffordablePavers v1.2.0

plugins/torvalds-pavers.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

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

public class LevelingLever : MonoBehaviour, Interactable, Hoverable
{
	private PavingCartPaver _paver;

	private ZNetView _znv;

	private Transform _leverVisual;

	private bool _lastKnownState = true;

	private void Awake()
	{
		_paver = ((Component)this).GetComponentInParent<PavingCartPaver>();
		_znv = ((Component)this).GetComponentInParent<ZNetView>();
		_leverVisual = ((Component)this).transform.Find("LeverVisual");
		if ((Object)(object)_leverVisual == (Object)null)
		{
			_leverVisual = ((Component)this).transform.Find("FallbackLeverVisual");
		}
		if ((Object)(object)_leverVisual == (Object)null)
		{
			CreateLeverVisual();
		}
	}

	private void Start()
	{
		if (Object.op_Implicit((Object)(object)_znv) && _znv.IsValid())
		{
			UpdateLeverRotation(_lastKnownState = _znv.GetZDO().GetBool("level_enabled", true));
		}
	}

	private void UpdateLeverRotation(bool isActive)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_leverVisual == (Object)null))
		{
			if (isActive)
			{
				_leverVisual.localRotation = Quaternion.Euler(-45f, 0f, 0f);
			}
			else
			{
				_leverVisual.localRotation = Quaternion.Euler(-90f, 0f, 0f);
			}
		}
	}

	private void Update()
	{
		if (Object.op_Implicit((Object)(object)_znv) && _znv.IsValid())
		{
			bool flag = _znv.GetZDO().GetBool("level_enabled", true);
			if (flag != _lastKnownState)
			{
				_lastKnownState = flag;
				UpdateLeverRotation(flag);
			}
		}
	}

	public string GetHoverText()
	{
		if (!Object.op_Implicit((Object)(object)_paver) || !Object.op_Implicit((Object)(object)_znv) || !_znv.IsValid())
		{
			return "⚙\ufe0f Leveling Control";
		}
		bool num = _znv.GetZDO().GetBool("pave_enabled", false);
		bool flag = _znv.GetZDO().GetBool("level_enabled", true);
		if (!num)
		{
			return "⚙\ufe0f <color=yellow>Leveling Control</color>\\n<color=grey>Inactive (enable paving first)</color>";
		}
		if (flag)
		{
			return "⚙\ufe0f <color=yellow>Leveling Control</color>\\nStatus: <color=green>ACTIVE</color>\\nMode: Level + Smooth + Paint\\n[<color=yellow>E</color>] Disable Leveling";
		}
		return "⚙\ufe0f <color=yellow>Leveling Control</color>\\nStatus: <color=red>INACTIVE</color>\\nMode: Paint Texture Only\\n[<color=yellow>E</color>] Enable Leveling";
	}

	public string GetHoverName()
	{
		return "Leveling Control";
	}

	public float GetHoverOffset()
	{
		return 0f;
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		if (!Object.op_Implicit((Object)(object)_paver) || !Object.op_Implicit((Object)(object)_znv) || !_znv.IsValid())
		{
			return false;
		}
		if (hold)
		{
			return false;
		}
		if (!_znv.GetZDO().GetBool("pave_enabled", false))
		{
			((Character)user).Message((MessageType)2, "⚠\ufe0f Enable paving first!", 0, (Sprite)null, false);
			return false;
		}
		bool flag = !_znv.GetZDO().GetBool("level_enabled", true);
		_znv.InvokeRPC(ZNetView.Everybody, "RPC_PavingCart_SetLevelingEnabled", new object[1] { flag });
		UpdateLeverRotation(flag);
		if (flag)
		{
			((Character)user).Message((MessageType)2, "\ud83d\udd28 Leveling enabled - will modify terrain height", 0, (Sprite)null, false);
		}
		else
		{
			((Character)user).Message((MessageType)2, "\ud83c\udfa8 Leveling disabled - will only paint texture overlay", 0, (Sprite)null, false);
		}
		return true;
	}

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

	private void CreateLeverVisual()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_004d: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		GameObject prefab = PrefabManager.Instance.GetPrefab("Club");
		if (Object.op_Implicit((Object)(object)prefab))
		{
			GameObject val = new GameObject("LeverVisual");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.Euler(-45f, 0f, 0f);
			MeshFilter componentInChildren = prefab.GetComponentInChildren<MeshFilter>();
			MeshRenderer componentInChildren2 = prefab.GetComponentInChildren<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren2))
			{
				val.AddComponent<MeshFilter>().mesh = componentInChildren.sharedMesh;
				((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)componentInChildren2).sharedMaterials;
				Logger.LogInfo((object)"Successfully used Club model for leveling lever");
				_leverVisual = val.transform;
			}
			else
			{
				Logger.LogWarning((object)"Could not find Club mesh components - leveling lever will be invisible");
			}
		}
		else
		{
			Logger.LogWarning((object)"Could not find Club prefab - leveling lever will be invisible");
		}
	}
}
public class PavingCartLever : MonoBehaviour, Interactable, Hoverable
{
	private PavingCartPaver _paver;

	private PavingCartSmoke _smoke;

	private ZNetView _znv;

	private Transform _leverVisual;

	private bool _lastKnownState;

	private void Awake()
	{
		_paver = ((Component)this).GetComponentInParent<PavingCartPaver>();
		_smoke = ((Component)this).GetComponentInParent<PavingCartSmoke>();
		_znv = ((Component)this).GetComponentInParent<ZNetView>();
		_leverVisual = ((Component)this).transform.Find("LeverVisual");
		if ((Object)(object)_leverVisual == (Object)null)
		{
			_leverVisual = ((Component)this).transform.Find("FallbackLeverVisual");
		}
		if ((Object)(object)_leverVisual == (Object)null)
		{
			CreateLeverVisual();
		}
	}

	private void Start()
	{
		if (Object.op_Implicit((Object)(object)_znv) && _znv.IsValid())
		{
			UpdateLeverRotation(_lastKnownState = _znv.GetZDO().GetBool("pave_enabled", false));
		}
	}

	private void UpdateLeverRotation(bool isActive)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_leverVisual == (Object)null))
		{
			if (isActive)
			{
				_leverVisual.localRotation = Quaternion.Euler(-45f, 0f, 0f);
			}
			else
			{
				_leverVisual.localRotation = Quaternion.Euler(-90f, 0f, 0f);
			}
		}
	}

	private void Update()
	{
		if (Object.op_Implicit((Object)(object)_znv) && _znv.IsValid())
		{
			bool flag = _znv.GetZDO().GetBool("pave_enabled", false);
			if (flag != _lastKnownState)
			{
				_lastKnownState = flag;
				UpdateLeverRotation(flag);
			}
		}
	}

	public string GetHoverText()
	{
		if (!Object.op_Implicit((Object)(object)_paver) || !Object.op_Implicit((Object)(object)_znv) || !_znv.IsValid())
		{
			return "\ud83d\udd27 Paving Control";
		}
		if (_znv.GetZDO().GetBool("pave_enabled", false))
		{
			return "\ud83d\udd27 <color=yellow>Paving Control</color>\\nStatus: <color=green>ACTIVE</color>\\n[<color=yellow>E</color>] Turn OFF";
		}
		return "\ud83d\udd27 <color=yellow>Paving Control</color>\\nStatus: <color=red>INACTIVE</color>\\n[<color=yellow>E</color>] Turn ON";
	}

	public string GetHoverName()
	{
		return "Paving Control";
	}

	public float GetHoverOffset()
	{
		return 0f;
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		if (!Object.op_Implicit((Object)(object)_paver) || !Object.op_Implicit((Object)(object)_znv) || !_znv.IsValid())
		{
			return false;
		}
		if (hold)
		{
			return false;
		}
		bool flag = !_znv.GetZDO().GetBool("pave_enabled", false);
		_znv.InvokeRPC(ZNetView.Everybody, "RPC_PavingCart_SetEnabled", new object[1] { flag });
		UpdateLeverRotation(flag);
		if (flag)
		{
			((Character)user).Message((MessageType)2, "\ud83d\udee0\ufe0f Paving activated - pull cart to create stone paths", 0, (Sprite)null, false);
		}
		else
		{
			((Character)user).Message((MessageType)2, "⏹\ufe0f Paving deactivated", 0, (Sprite)null, false);
		}
		return true;
	}

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

	private void CreateLeverVisual()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_004d: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		GameObject prefab = PrefabManager.Instance.GetPrefab("Club");
		if (Object.op_Implicit((Object)(object)prefab))
		{
			GameObject val = new GameObject("LeverVisual");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.Euler(-90f, 0f, 0f);
			MeshFilter componentInChildren = prefab.GetComponentInChildren<MeshFilter>();
			MeshRenderer componentInChildren2 = prefab.GetComponentInChildren<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren2))
			{
				val.AddComponent<MeshFilter>().mesh = componentInChildren.sharedMesh;
				((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)componentInChildren2).sharedMaterials;
				Logger.LogInfo((object)"Successfully used Club model for paving lever");
				_leverVisual = val.transform;
			}
			else
			{
				Logger.LogWarning((object)"Could not find Club mesh components - lever will be invisible");
			}
		}
		else
		{
			Logger.LogWarning((object)"Could not find Club prefab - lever will be invisible");
		}
	}
}
public class PavingCartPaver : MonoBehaviour, Interactable, Hoverable
{
	public float CheckEveryMeters = 1f;

	public float PaveRadius = 1.2f;

	public int StonesPerStamp = 1;

	public string StoneItemName = "Stone";

	public bool StartEnabled;

	public float ClutterClearScale = 1.05f;

	private ZNetView _znv;

	private float lastOperationTime;

	private Vector3 lastOperationPosition = Vector3.zero;

	private const float OPERATION_COOLDOWN = 1f;

	private const float MIN_DISTANCE = 2f;

	private Container _container;

	private PavingCartSmoke _smoke;

	private Vector3 _lastStampPos;

	private bool _enabled;

	private bool _levelingEnabled;

	private bool _serverInitialized;

	private bool _rpcsRegistered;

	private const string ZDOKeyEnabled = "pave_enabled";

	private const string ZDOKeyLevelingEnabled = "level_enabled";

	private Vagon _vagon;

	[Conditional("DEBUG")]
	private static void DebugLog(string message)
	{
		Logger.LogInfo((object)("[PavingCart-Debug] " + message));
	}

	private void Awake()
	{
		_znv = ((Component)this).GetComponent<ZNetView>();
		_container = ((Component)this).GetComponentInChildren<Container>();
		_smoke = ((Component)this).GetComponent<PavingCartSmoke>();
		((MonoBehaviour)this).StartCoroutine(DelayedInitialization());
	}

	private void Start()
	{
		ApplyCartTint();
	}

	private IEnumerator DelayedInitialization()
	{
		while ((Object)(object)ZNet.instance == (Object)null)
		{
			yield return null;
		}
		while ((Object)(object)_znv == (Object)null || !_znv.IsValid())
		{
			_znv = ((Component)this).GetComponent<ZNetView>();
			yield return null;
		}
		RegisterRPCs();
		if (_znv.IsOwner())
		{
			_znv.GetZDO().Set("pave_enabled", StartEnabled);
			_znv.GetZDO().Set("level_enabled", true);
		}
		_enabled = _znv.GetZDO().GetBool("pave_enabled", StartEnabled);
		_levelingEnabled = _znv.GetZDO().GetBool("level_enabled", true);
		UpdateVisuals();
	}

	private void ApplyCartTint()
	{
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			MeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshRenderer>();
			Color val = default(Color);
			((Color)(ref val))..ctor(1.9f, 1.8f, 1.95f, 1f);
			int num = 0;
			int num2 = 0;
			MeshRenderer[] array = componentsInChildren;
			foreach (MeshRenderer val2 in array)
			{
				Transform val3 = ((Component)val2).transform;
				bool flag = false;
				while ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)((Component)this).transform)
				{
					if (((Object)val3).name == "SurtlingCoreVisual" || ((Object)val3).name == "CoreVisual")
					{
						flag = true;
						break;
					}
					if (((Object)val3).name == "PavingLever" || ((Object)val3).name == "LeverVisual" || ((Object)val3).name == "FallbackLeverVisual")
					{
						flag = true;
						break;
					}
					val3 = val3.parent;
				}
				if (flag)
				{
					num++;
					continue;
				}
				Material[] materials = ((Renderer)val2).materials;
				bool flag2 = false;
				foreach (Material val4 in materials)
				{
					if (val4.HasProperty("_Color"))
					{
						val4.color = val;
						flag2 = true;
					}
					if (val4.HasProperty("_MainColor"))
					{
						val4.SetColor("_MainColor", val);
						flag2 = true;
					}
					if (val4.HasProperty("_TintColor"))
					{
						val4.SetColor("_TintColor", val);
						flag2 = true;
					}
					if (val4.HasProperty("_Metallic"))
					{
						val4.SetFloat("_Metallic", 0.2f);
						flag2 = true;
					}
					if (val4.HasProperty("_Smoothness"))
					{
						val4.SetFloat("_Smoothness", 0.3f);
						flag2 = true;
					}
					else if (val4.HasProperty("_Glossiness"))
					{
						val4.SetFloat("_Glossiness", 0.3f);
						flag2 = true;
					}
				}
				if (flag2)
				{
					((Renderer)val2).materials = materials;
					num2++;
				}
			}
			Logger.LogInfo((object)$"PavingCart: Applied bright silver tint to {num2} renderers, skipped {num} components");
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("PavingCart: Error applying tint: " + ex.Message));
		}
	}

	private void RegisterRPCs()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_znv == (Object)null) && _znv.IsValid() && !_rpcsRegistered)
		{
			_ = _znv.GetZDO().m_uid;
			_znv.Register<bool>("RPC_PavingCart_SetEnabled", (Action<long, bool>)RPC_SetEnabled);
			_znv.Register<bool>("RPC_PavingCart_SetLevelingEnabled", (Action<long, bool>)RPC_SetLevelingEnabled);
			_ = ZRoutedRpc.instance;
			_rpcsRegistered = true;
		}
	}

	private void RPC_SetEnabled(long sender, bool on)
	{
		_enabled = on;
		if (_znv.IsOwner())
		{
			_znv.GetZDO().Set("pave_enabled", on);
		}
		UpdateVisuals();
	}

	private void RPC_SetLevelingEnabled(long sender, bool on)
	{
		_levelingEnabled = on;
		if (_znv.IsOwner())
		{
			_znv.GetZDO().Set("level_enabled", on);
		}
	}

	public bool IsLevelingEnabled()
	{
		if (Object.op_Implicit((Object)(object)_znv) && _znv.IsValid())
		{
			return _znv.GetZDO().GetBool("level_enabled", true);
		}
		return true;
	}

	public void ApplyPaveGlobal(Vector3 pos, float radius)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		if (ZNet.instance.IsServer())
		{
			ApplyPave(pos, radius);
		}
	}

	public void ApplyLevelOnlyGlobal(Vector3 pos, float radius)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		if (ZNet.instance.IsServer())
		{
			ApplyLevelOnly(pos, radius);
		}
	}

	private void OnEnable()
	{
	}

	private void InitializeServerSide()
	{
		_serverInitialized = true;
	}

	private void UpdateVisuals()
	{
		_smoke?.SetActive(_enabled);
	}

	public string GetHoverText()
	{
		return "<color=yellow>Paving Cart</color>\\n[<color=yellow>Use (E)</color>] Toggle paving (" + (_enabled ? "On" : "Off") + ")";
	}

	public string GetHoverName()
	{
		return "Paving Cart";
	}

	public float GetHoverOffset()
	{
		if (!Object.op_Implicit((Object)(object)_vagon))
		{
			_vagon = ((Component)this).GetComponentInChildren<Vagon>();
		}
		if (!Object.op_Implicit((Object)(object)_vagon))
		{
			return 0f;
		}
		return _vagon.m_hoverOffset;
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		if (!Object.op_Implicit((Object)(object)_znv) || !_znv.IsValid())
		{
			return false;
		}
		if (hold)
		{
			return false;
		}
		bool flag = !_znv.GetZDO().GetBool("pave_enabled", StartEnabled);
		_znv.InvokeRPC(ZNetView.Everybody, "RPC_PavingCart_SetEnabled", new object[1] { flag });
		((Character)user).Message((MessageType)2, "Paving " + (flag ? "Enabled" : "Disabled"), 0, (Sprite)null, false);
		return true;
	}

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

	private void Update()
	{
		//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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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_0085: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)_znv) || !_znv.IsValid())
		{
			return;
		}
		if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !_serverInitialized)
		{
			InitializeServerSide();
		}
		if (!_znv.IsOwner())
		{
			return;
		}
		Vector3 position = ((Component)this).transform.position;
		if (!_enabled)
		{
			_lastStampPos = position;
			return;
		}
		if (_lastStampPos == Vector3.zero)
		{
			_lastStampPos = position;
		}
		if (Vector3.Distance(position, _lastStampPos) < CheckEveryMeters)
		{
			return;
		}
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(TorvaldsPavers.PavingOffsetX.Value, TorvaldsPavers.PavingOffsetY.Value, TorvaldsPavers.PavingOffsetZ.Value);
		Vector3 worldPos = position + val;
		if (HasStones(StonesPerStamp))
		{
			if (TryConsumeStone(StonesPerStamp))
			{
				RPC_Pave(worldPos, PaveRadius);
			}
			else
			{
				RPC_LevelOnly(worldPos, PaveRadius);
			}
		}
		else
		{
			RPC_LevelOnly(worldPos, PaveRadius);
		}
		_lastStampPos = position;
	}

	private bool HasStones(int amount)
	{
		if ((Object)(object)_container == (Object)null)
		{
			return false;
		}
		Inventory inventory = _container.GetInventory();
		if (inventory == null)
		{
			return false;
		}
		return (from item in inventory.GetAllItems()
			where item.m_shared?.m_name != null && StoneOnlyContainer.IsStoneItem(item.m_shared.m_name)
			select item).ToList().Sum((ItemData item) => item.m_stack) >= amount;
	}

	private bool TryConsumeStone(int amount)
	{
		if ((Object)(object)_container == (Object)null)
		{
			Logger.LogWarning((object)"PavingCart: No container for stone consumption");
			return false;
		}
		Inventory inventory = _container.GetInventory();
		if (inventory == null)
		{
			Logger.LogWarning((object)"PavingCart: No inventory for stone consumption");
			return false;
		}
		List<ItemData> source = (from item in inventory.GetAllItems()
			where item.m_shared?.m_name != null && StoneOnlyContainer.IsStoneItem(item.m_shared.m_name)
			select item).ToList();
		if (source.Sum((ItemData item) => item.m_stack) < amount)
		{
			return false;
		}
		int num = amount;
		foreach (ItemData item in source.OrderBy((ItemData x) => x.m_shared.m_name))
		{
			if (num <= 0)
			{
				break;
			}
			int num2 = Math.Min(num, item.m_stack);
			inventory.RemoveItem(item.m_shared.m_name, num2, -1, true);
			num -= num2;
		}
		_container.m_inventory.Changed(false, false);
		return num == 0;
	}

	private void RPC_Pave(Vector3 worldPos, float radius)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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)_znv == (Object)null) && _znv.IsValid())
		{
			ZDOID uid = _znv.GetZDO().m_uid;
			bool flag = _znv.GetZDO().GetBool("level_enabled", true);
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PavingCart_DoPave", new object[4] { uid, worldPos, radius, flag });
			}
		}
	}

	private void ApplyPave(Vector3 center, float radius)
	{
		//IL_003b: 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)
		if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer())
		{
			Logger.LogWarning((object)"ApplyPave called on client - ignoring");
		}
		else if (!TryConsumeStone(StonesPerStamp))
		{
			ApplyLevelOnly(center, radius);
		}
		else
		{
			Server_TerrainOp(center, radius, "Paved");
		}
	}

	private void Server_TerrainOp(Vector3 center, float radius, string paintName)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_005f: 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_0066: Unknown result type (might be due to invalid IL or missing references)
		float time = Time.time;
		float num = time - lastOperationTime;
		float num2 = Vector3.Distance(center, lastOperationPosition);
		if (!(num < 1f) && (!(num2 < 2f) || !(lastOperationPosition != Vector3.zero)) && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer())
		{
			lastOperationTime = time;
			lastOperationPosition = center;
			CreateTerrainPiece(center, radius, paintName);
		}
	}

	private void CreateTerrainPiece(Vector3 center, float radius, string paintName)
	{
		//IL_0077: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		string text = "paved_road_v2";
		text = paintName.ToLower() switch
		{
			"dirt" => "mud_road_v2", 
			"path" => "path_v2", 
			_ => "paved_road_v2", 
		};
		GameObject prefab = PrefabManager.Instance.GetPrefab(text);
		if ((Object)(object)prefab == (Object)null)
		{
			Logger.LogError((object)("Could not find prefab: " + text));
			return;
		}
		GameObject val = Object.Instantiate<GameObject>(prefab, center, Quaternion.identity);
		if ((Object)(object)val == (Object)null)
		{
			Logger.LogError((object)("Failed to instantiate terrain piece: " + text));
			return;
		}
		TerrainOp component = val.GetComponent<TerrainOp>();
		if ((Object)(object)component != (Object)null)
		{
			Settings settings = component.m_settings;
			settings.m_level = true;
			settings.m_levelRadius = radius;
			settings.m_smooth = true;
			settings.m_smoothRadius = radius;
			if (settings.m_paintRadius > 0f)
			{
				settings.m_paintRadius = radius;
			}
		}
		float num = radius * ClutterClearScale;
		ClutterSystem instance = ClutterSystem.instance;
		if (instance != null)
		{
			instance.ResetGrass(center, num);
		}
	}

	private void RPC_LevelOnly(Vector3 worldPos, float radius)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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)_znv == (Object)null) && _znv.IsValid())
		{
			ZDOID uid = _znv.GetZDO().m_uid;
			bool flag = _znv.GetZDO().GetBool("level_enabled", true);
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PavingCart_DoLevelOnly", new object[4] { uid, worldPos, radius, flag });
			}
		}
	}

	private void ApplyLevelOnly(Vector3 center, float radius)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer())
		{
			Logger.LogWarning((object)"ApplyLevelOnly called on client - ignoring");
		}
		else
		{
			Server_TerrainOp(center, radius, "Dirt");
		}
	}
}
public class PavingCartRunner : MonoBehaviour
{
	private static PavingCartRunner _instance;

	public static void Ensure()
	{
		//IL_0013: 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_001e: Expected O, but got Unknown
		if (!((Object)(object)_instance != (Object)null))
		{
			GameObject val = new GameObject("PavingCartRunner");
			Object.DontDestroyOnLoad((Object)val);
			_instance = val.AddComponent<PavingCartRunner>();
		}
	}

	public static Coroutine Run(IEnumerator routine)
	{
		if ((Object)(object)_instance == (Object)null)
		{
			return null;
		}
		return ((MonoBehaviour)_instance).StartCoroutine(routine);
	}
}
public class PavingCartSmoke : MonoBehaviour
{
	public Vector3 LocalOffset = new Vector3(0f, 0.8f, 0f);

	private GameObject _smokeGO;

	private ParticleSystem _ps;

	private void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0033: 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_0063: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_00d2: 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_00df: 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_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Expected O, but got Unknown
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Expected O, but got Unknown
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: 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_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Expected O, but got Unknown
		_smokeGO = new GameObject("PavingCartSmoke");
		_smokeGO.transform.SetParent(((Component)this).transform, false);
		_smokeGO.transform.localPosition = LocalOffset;
		Logger.LogInfo((object)"Creating sparks particle effect for stone grinding");
		_ps = _smokeGO.AddComponent<ParticleSystem>();
		MainModule main = _ps.main;
		((MainModule)(ref main)).loop = true;
		((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.8f);
		((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(4f);
		((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.05f);
		((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(1f, 0.6f, 0.2f, 1f));
		((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
		EmissionModule emission = _ps.emission;
		((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(15f);
		((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1]
		{
			new Burst(0f, (short)3, (short)8, 1, 1f)
		});
		ShapeModule shape = _ps.shape;
		((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
		((ShapeModule)(ref shape)).angle = 30f;
		((ShapeModule)(ref shape)).radius = 0.15f;
		((ShapeModule)(ref shape)).rotation = new Vector3(-90f, 0f, 0f);
		VelocityOverLifetimeModule velocityOverLifetime = _ps.velocityOverLifetime;
		((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
		((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)0;
		((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = MinMaxCurve.op_Implicit(-2f);
		((VelocityOverLifetimeModule)(ref velocityOverLifetime)).radial = MinMaxCurve.op_Implicit(0.3f);
		SizeOverLifetimeModule sizeOverLifetime = _ps.sizeOverLifetime;
		((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
		AnimationCurve val = new AnimationCurve();
		val.AddKey(0f, 1f);
		val.AddKey(1f, 0.2f);
		((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val);
		ColorOverLifetimeModule colorOverLifetime = _ps.colorOverLifetime;
		((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
		Gradient val2 = new Gradient();
		val2.SetKeys((GradientColorKey[])(object)new GradientColorKey[3]
		{
			new GradientColorKey(new Color(1f, 0.8f, 0.3f), 0f),
			new GradientColorKey(new Color(1f, 0.4f, 0.1f), 0.5f),
			new GradientColorKey(new Color(0.8f, 0.2f, 0f), 1f)
		}, (GradientAlphaKey[])(object)new GradientAlphaKey[3]
		{
			new GradientAlphaKey(1f, 0f),
			new GradientAlphaKey(0.8f, 0.5f),
			new GradientAlphaKey(0f, 1f)
		});
		((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val2);
		ParticleSystemRenderer component = ((Component)_ps).GetComponent<ParticleSystemRenderer>();
		if ((Object)(object)component != (Object)null)
		{
			((Renderer)component).material = new Material(Shader.Find("Sprites/Default"));
		}
		SetActive(on: false);
	}

	public void SetActive(bool on)
	{
		//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 (!((Object)(object)_smokeGO == (Object)null) && !((Object)(object)_ps == (Object)null))
		{
			EmissionModule emission = _ps.emission;
			((EmissionModule)(ref emission)).enabled = on;
			if (on && !_ps.isPlaying)
			{
				_ps.Play(true);
			}
			if (!on && _ps.isPlaying)
			{
				_ps.Stop(true, (ParticleSystemStopBehavior)1);
			}
			_smokeGO.SetActive(on);
		}
	}
}
public class StoneOnlyContainer : MonoBehaviour
{
	public string StoneItemName = "Stone";

	public Container TargetContainer;

	private float _scanTimer;

	public static bool IsStoneItem(string itemName)
	{
		if (string.IsNullOrEmpty(itemName))
		{
			return false;
		}
		if (!string.Equals(itemName, "Stone", StringComparison.OrdinalIgnoreCase) && !string.Equals(itemName, "$Stone", StringComparison.OrdinalIgnoreCase))
		{
			return itemName.IndexOf("stone", StringComparison.OrdinalIgnoreCase) >= 0;
		}
		return true;
	}

	private void Update()
	{
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//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_00c6: 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)
		if (!Object.op_Implicit((Object)(object)TargetContainer))
		{
			return;
		}
		_scanTimer += Time.deltaTime;
		if (_scanTimer < 0.75f)
		{
			return;
		}
		_scanTimer = 0f;
		Inventory inventory = TargetContainer.GetInventory();
		if (inventory == null)
		{
			return;
		}
		foreach (ItemData item in inventory.GetAllItems().ToList())
		{
			if (item.m_shared != null && item.m_shared.m_name != null && !IsStoneItem(item.m_shared.m_name) && inventory.RemoveItem(item, item.m_stack))
			{
				Vector3 val = ((Component)TargetContainer).transform.position + Vector3.right * 0.5f;
				ItemDrop.DropItem(item, item.m_stack, val, Quaternion.identity);
			}
		}
	}
}
[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
public static class Inventory_AddItem_Patch
{
	private static bool Prefix(Inventory __instance, ItemData item, ref bool __result)
	{
		Container val = ((__instance.m_name == "Paving Cart") ? FindContainerForInventory(__instance) : null);
		if ((Object)(object)val == (Object)null || !((Object)((Component)val).gameObject).name.StartsWith("PavingCart"))
		{
			return true;
		}
		Logger.LogDebug((object)("Trying to add item: " + item.m_shared.m_name));
		if (!StoneOnlyContainer.IsStoneItem(item.m_shared.m_name))
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, "⚠\ufe0f Paving Cart only accepts stone materials", 0, (Sprite)null, false);
			}
			__result = false;
			return false;
		}
		return true;
	}

	private static Container FindContainerForInventory(Inventory inventory)
	{
		Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0);
		foreach (Container val in array)
		{
			if (val.GetInventory() == inventory)
			{
				return val;
			}
		}
		return null;
	}
}
[HarmonyPatch(typeof(Container), "GetHoverText")]
public static class Container_GetHoverText_Patch
{
	private static bool Prefix(Container __instance, ref string __result)
	{
		if (!((Object)((Component)__instance).gameObject).name.StartsWith("PavingCart"))
		{
			return true;
		}
		PavingCartPaver componentInParent = ((Component)__instance).GetComponentInParent<PavingCartPaver>();
		if (!Object.op_Implicit((Object)(object)componentInParent))
		{
			return true;
		}
		__result = componentInParent.GetHoverText();
		return false;
	}
}
[HarmonyPatch(typeof(Vagon), "GetHoverName")]
public static class Vagon_GetHoverName_Patch
{
	private static void Postfix(Vagon __instance, ref string __result)
	{
		if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)((Component)__instance).gameObject) && ((Object)((Component)__instance).gameObject).name.StartsWith("PavingCart"))
		{
			if (Localization.instance != null)
			{
				__result = Localization.instance.Localize("$piece_pavingcart_name");
			}
			else
			{
				__result = "Paving Cart";
			}
		}
	}
}
[BepInPlugin("com.torvald.pavers", "Torvald's Affordable Pavers", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class TorvaldsPavers : BaseUnityPlugin
{
	public const string PluginGUID = "com.torvald.pavers";

	public const string PluginName = "Torvald's Affordable Pavers";

	public const string PluginVersion = "1.2.0";

	private const string PavingCartPrefabName = "PavingCart";

	private const string VanillaCartPrefab = "Cart";

	private const string StoneItemName = "Stone";

	public static ConfigEntry<float> PavingOffsetX;

	public static ConfigEntry<float> PavingOffsetY;

	public static ConfigEntry<float> PavingOffsetZ;

	public static ConfigEntry<float> PavingLevelOffset;

	public static ConfigEntry<float> PavingLevelRadius;

	public static ConfigEntry<float> PavingSmoothRadius;

	public static ConfigEntry<float> PavingPaintRadius;

	private Harmony _harmony;

	private static TorvaldsPavers _instance;

	[Conditional("DEBUG")]
	private static void DebugLog(string message)
	{
		Logger.LogInfo((object)("[TorvaldsPavers-Debug] " + message));
	}

	private void Awake()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0050: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Expected O, but got Unknown
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Expected O, but got Unknown
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Expected O, but got Unknown
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Expected O, but got Unknown
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Expected O, but got Unknown
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Expected O, but got Unknown
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: 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_020d: Expected O, but got Unknown
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Expected O, but got Unknown
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Expected O, but got Unknown
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Expected O, but got Unknown
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Expected O, but got Unknown
		_instance = this;
		PavingLevelRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Paving", "LevelRadius", 1.2f, new ConfigDescription("Radius for terrain leveling (when leveling is enabled)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true,
			Order = 7
		} }));
		PavingSmoothRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Paving", "SmoothRadius", 1.2f, new ConfigDescription("Radius for terrain smoothing (when leveling is enabled)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true,
			Order = 6
		} }));
		PavingPaintRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Paving", "PaintRadius", 1.2f, new ConfigDescription("Radius for texture painting", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true,
			Order = 5
		} }));
		PavingOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Paving", "OffsetX", 0f, new ConfigDescription("X-axis offset for paving position (left/right from cart center)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true,
			Order = 4
		} }));
		PavingOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Paving", "OffsetY", -0.2f, new ConfigDescription("Y-axis offset for paving position (vertical from cart center)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true,
			Order = 3
		} }));
		PavingOffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("Paving", "OffsetZ", 0f, new ConfigDescription("Z-axis offset for paving position (forward/backward from cart center)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true,
			Order = 2
		} }));
		PavingLevelOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Paving", "LevelOffset", 0f, new ConfigDescription("Vertical offset for terrain leveling target height. Positive = raise terrain above stamp, Negative = lower below stamp. Use this to prevent 'digging in' on slopes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true,
			Order = 1
		} }));
		_harmony = new Harmony("com.torvald.pavers");
		_harmony.PatchAll();
		PavingCartRunner.Ensure();
		PrefabManager.OnVanillaPrefabsAvailable += OnVanillaReady;
		RegisterServerRPCs();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Torvald's Affordable Pavers has landed");
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaReady;
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}

	private void RegisterServerRPCs()
	{
		PrefabManager.OnPrefabsRegistered += delegate
		{
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<ZDOID, Vector3, float, bool>("PavingCart_DoPave", (Method<ZDOID, Vector3, float, bool>)_instance.GlobalRPC_DoPave);
				ZRoutedRpc.instance.Register<ZDOID, Vector3, float, bool>("PavingCart_DoLevelOnly", (Method<ZDOID, Vector3, float, bool>)_instance.GlobalRPC_DoLevelOnly);
				ZRoutedRpc.instance.Register<Vector3, float, string, bool>("PavingCart_ExecuteTerrainOp", (Method<Vector3, float, string, bool>)_instance.RPC_ExecuteTerrainOp);
			}
		};
	}

	private void GlobalRPC_DoPave(long sender, ZDOID cartZDOID, Vector3 pos, float radius, bool levelingEnabled)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (ZNet.instance.IsServer())
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PavingCart_ExecuteTerrainOp", new object[4] { pos, radius, "Paved", levelingEnabled });
		}
	}

	private void GlobalRPC_DoLevelOnly(long sender, ZDOID cartZDOID, Vector3 pos, float radius, bool levelingEnabled)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (ZNet.instance.IsServer())
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PavingCart_ExecuteTerrainOp", new object[4] { pos, radius, "Dirt", levelingEnabled });
		}
	}

	private void RPC_ExecuteTerrainOp(long sender, Vector3 pos, float radius, string paintName, bool levelingEnabled)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		CreateTerrainPieceLocal(pos, radius, paintName, levelingEnabled);
	}

	private void CreateTerrainPieceLocal(Vector3 center, float radius, string paintName, bool levelingEnabled)
	{
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		string text = paintName.ToLower();
		string text2 = ((text == "dirt") ? "mud_road_v2" : ((!(text == "path")) ? "paved_road_v2" : "path_v2"));
		string text3 = text2;
		GameObject prefab = PrefabManager.Instance.GetPrefab(text3);
		if ((Object)(object)prefab == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[CLIENT-TERRAIN] Could not find prefab: " + text3));
			return;
		}
		GameObject val = Object.Instantiate<GameObject>(prefab, center, Quaternion.identity);
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[CLIENT-TERRAIN] Failed to instantiate terrain piece: " + text3));
			return;
		}
		TerrainOp component = val.GetComponent<TerrainOp>();
		if ((Object)(object)component != (Object)null)
		{
			Settings settings = component.m_settings;
			if (levelingEnabled)
			{
				settings.m_level = true;
				settings.m_levelRadius = PavingLevelRadius.Value;
				settings.m_levelOffset = PavingLevelOffset.Value;
				settings.m_smooth = true;
				settings.m_smoothRadius = PavingSmoothRadius.Value;
			}
			else
			{
				settings.m_level = false;
				settings.m_smooth = false;
			}
			settings.m_paintRadius = PavingPaintRadius.Value;
			component.OnPlaced();
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("[CLIENT-TERRAIN] No TerrainOp component found on " + text3));
		}
		ClutterSystem instance = ClutterSystem.instance;
		if (instance != null)
		{
			instance.ResetGrass(center, radius * 1.5f);
		}
	}

	private void OnVanillaReady()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaReady;
		try
		{
			CreatePavingCart();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Paving Cart content registered.");
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to register paving cart content: {arg}");
		}
	}

	private void CreatePavingCart()
	{
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Expected O, but got Unknown
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Expected O, but got Unknown
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		string text = "English";
		localization.AddTranslation(ref text, new Dictionary<string, string>
		{
			{ "$piece_pavingcart_name", "Paving Cart" },
			{ "$piece_pavingcart_desc", "Load with stone, pull to lay paved path." }
		});
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Attempting to find vanilla cart prefab: Cart");
		GameObject prefab = PrefabManager.Instance.GetPrefab("Cart");
		if (!Object.op_Implicit((Object)(object)prefab))
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Vanilla Cart prefab not found");
			return;
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Creating cloned prefab: PavingCart");
		GameObject val = PrefabManager.Instance.CreateClonedPrefab("PavingCart", prefab);
		if (!Object.op_Implicit((Object)(object)val))
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Failed to clone cart prefab");
			return;
		}
		Piece component = val.GetComponent<Piece>();
		if (Object.op_Implicit((Object)(object)component))
		{
			component.m_name = "$piece_pavingcart_name";
			component.m_description = "$piece_pavingcart_desc";
		}
		if (!Object.op_Implicit((Object)(object)val.GetComponent<PavingCartPaver>()))
		{
			val.AddComponent<PavingCartPaver>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"=== PAVING CART PAVER COMPONENT ADDED ====");
		}
		if (!Object.op_Implicit((Object)(object)val.GetComponent<PavingCartSmoke>()))
		{
			val.AddComponent<PavingCartSmoke>();
		}
		CreatePavingLever(val);
		CreateLevelingLever(val);
		CreateSurtlingCoreVisual(val);
		Container componentInChildren = val.GetComponentInChildren<Container>();
		if (Object.op_Implicit((Object)(object)componentInChildren))
		{
			componentInChildren.m_name = "Paving Cart";
			if (!Object.op_Implicit((Object)(object)val.GetComponent<StoneOnlyContainer>()))
			{
				StoneOnlyContainer stoneOnlyContainer = val.AddComponent<StoneOnlyContainer>();
				stoneOnlyContainer.StoneItemName = "Stone";
				stoneOnlyContainer.TargetContainer = componentInChildren;
			}
		}
		((BaseUnityPlugin)this).Logger.LogDebug((object)"Paving Cart prefab created, registering as buildable piece");
		PieceConfig val2 = new PieceConfig
		{
			Name = "$piece_pavingcart_name",
			Description = "$piece_pavingcart_desc",
			PieceTable = "Hammer",
			Category = "Misc"
		};
		val2.AddRequirement("SurtlingCore", 2, true);
		val2.AddRequirement("ElderBark", 20, true);
		val2.AddRequirement("BronzeNails", 10, true);
		val2.AddRequirement("Iron", 2, true);
		val2.AddRequirement("Stone", 8, true);
		PieceManager.Instance.AddPiece(new CustomPiece(val, true, val2));
		((BaseUnityPlugin)this).Logger.LogDebug((object)"Paving Cart piece and recipe registered");
	}

	private void CreatePavingLever(GameObject cartClone)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("PavingLever");
		val.transform.SetParent(cartClone.transform, false);
		val.transform.localPosition = new Vector3(0.7f, 0.8f, 0f);
		val.transform.localRotation = Quaternion.identity;
		val.transform.localScale = Vector3.one;
		val.layer = cartClone.layer;
		SphereCollider obj = val.AddComponent<SphereCollider>();
		obj.radius = 0.5f;
		((Collider)obj).isTrigger = false;
		val.AddComponent<PavingCartLever>();
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Created paving control lever at position {val.transform.position}, layer {val.layer}");
	}

	private void CreateLevelingLever(GameObject cartClone)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("LevelingLever");
		val.transform.SetParent(cartClone.transform, false);
		val.transform.localPosition = new Vector3(-0.7f, 0.8f, 0f);
		val.transform.localRotation = Quaternion.identity;
		val.transform.localScale = Vector3.one;
		val.layer = cartClone.layer;
		SphereCollider obj = val.AddComponent<SphereCollider>();
		obj.radius = 0.5f;
		((Collider)obj).isTrigger = false;
		val.AddComponent<LevelingLever>();
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Created leveling control lever at position {val.transform.position}, layer {val.layer}");
	}

	private void CreateSurtlingCoreVisual(GameObject cartClone)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//IL_0060: 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)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("SurtlingCore");
			if ((Object)(object)prefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"SurtlingCore prefab not found - skipping visual");
				return;
			}
			GameObject val = new GameObject("SurtlingCoreVisual");
			val.transform.SetParent(cartClone.transform, false);
			val.transform.localPosition = new Vector3(0.7f, 0.6f, 0f);
			val.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
			if ((Object)(object)prefab.GetComponent<ItemDrop>() != (Object)null)
			{
				Transform val2 = null;
				foreach (Transform item in prefab.transform)
				{
					Transform val3 = item;
					if (((Object)val3).name.ToLower().Contains("attach") || (Object)(object)((Component)val3).GetComponentInChildren<MeshRenderer>() != (Object)null || (Object)(object)((Component)val3).GetComponentInChildren<ParticleSystem>() != (Object)null)
					{
						val2 = val3;
						break;
					}
				}
				if ((Object)(object)val2 == (Object)null && prefab.transform.childCount > 0)
				{
					val2 = prefab.transform.GetChild(0);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					GameObject val4 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val.transform);
					val4.transform.localPosition = Vector3.zero;
					val4.transform.localRotation = Quaternion.identity;
					((Object)val4).name = "CoreVisual";
					Collider[] componentsInChildren = val4.GetComponentsInChildren<Collider>();
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
					}
					ParticleSystem[] componentsInChildren2 = val4.GetComponentsInChildren<ParticleSystem>();
					for (int i = 0; i < componentsInChildren2.Length; i++)
					{
						componentsInChildren2[i].Play();
					}
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Successfully added SurtlingCore visual to paving cart");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find visual model in SurtlingCore prefab");
				}
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"SurtlingCore prefab missing ItemDrop component");
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to add SurtlingCore visual: " + ex.Message));
		}
	}
}
[HarmonyPatch(typeof(ZNetScene), "Awake")]
public static class ZNetScene_Awake_Patch
{
	public static void Postfix(ZNetScene __instance)
	{
		GameObject prefab = __instance.GetPrefab("PavingCart");
		if ((Object)(object)prefab != (Object)null)
		{
			EnsureServerComponents(prefab);
		}
	}

	private static void EnsureServerComponents(GameObject prefab)
	{
		if (!Object.op_Implicit((Object)(object)prefab.GetComponent<PavingCartPaver>()))
		{
			prefab.AddComponent<PavingCartPaver>();
			Logger.LogInfo((object)"[Server] Added PavingCartPaver component to prefab");
		}
	}
}
[HarmonyPatch(typeof(ZNetView), "Awake")]
public static class ZNetView_Awake_Patch
{
	public static void Postfix(ZNetView __instance)
	{
		if (((Object)__instance).name.StartsWith("PavingCart") && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PavingCartPaver>()))
		{
			((Component)__instance).gameObject.AddComponent<PavingCartPaver>();
			ZNet instance = ZNet.instance;
			Logger.LogInfo((object)$"[Server] Added PavingCartPaver to spawned cart instance. IsServer={((instance != null) ? new bool?(instance.IsServer()) : ((bool?)null))}");
		}
	}
}