Decompiled source of TorvaldsAffordablePavers v1.1.0

plugins\torvalds-pavers.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
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.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TorvaldsPavers;

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 @bool = _znv.GetZDO().GetBool("pave_enabled", false);
			if (@bool != _lastKnownState)
			{
				_lastKnownState = @bool;
				UpdateLeverRotation(@bool);
			}
		}
	}

	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 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);
		}
		else
		{
			((Character)user).Message((MessageType)2, "⏹\ufe0f Paving deactivated", 0, (Sprite)null);
		}
		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
{
	[CompilerGenerated]
	private sealed class <DelayedInitialization>d__23 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public PavingCartPaver <>4__this;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DelayedInitialization>d__23(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			int num = <>1__state;
			PavingCartPaver pavingCartPaver = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				goto IL_0042;
			case 1:
				<>1__state = -1;
				goto IL_0042;
			case 2:
				{
					<>1__state = -1;
					break;
				}
				IL_0042:
				if ((Object)(object)ZNet.instance == (Object)null)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				break;
			}
			if ((Object)(object)pavingCartPaver._znv == (Object)null || !pavingCartPaver._znv.IsValid())
			{
				pavingCartPaver._znv = ((Component)pavingCartPaver).GetComponent<ZNetView>();
				<>2__current = null;
				<>1__state = 2;
				return true;
			}
			DebugLog($"DelayedInit: ZNetView now valid. IsOwner={pavingCartPaver._znv.IsOwner()}, ZDO ID={pavingCartPaver._znv.GetZDO()?.m_uid}, IsServer={ZNet.instance.IsServer()}");
			pavingCartPaver.RegisterRPCs();
			if (pavingCartPaver._znv.IsOwner())
			{
				pavingCartPaver._znv.GetZDO().Set("pave_enabled", pavingCartPaver.StartEnabled);
				DebugLog($"DelayedInit: Set initial enabled state to {pavingCartPaver.StartEnabled}");
			}
			pavingCartPaver._enabled = pavingCartPaver._znv.GetZDO().GetBool("pave_enabled", pavingCartPaver.StartEnabled);
			pavingCartPaver.UpdateVisuals();
			DebugLog($"DelayedInit: Cart enabled state is {pavingCartPaver._enabled}, initialization complete");
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	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 _serverInitialized;

	private bool _rpcsRegistered;

	private const string ZDOKeyEnabled = "pave_enabled";

	private static bool DebugLogging => false;

	private static void DebugLog(string message)
	{
		Logger.LogInfo((object)("[PavingCart-Debug] " + message));
		try
		{
			string path = Path.Combine(Application.dataPath, "..", "paving_cart_debug.log");
			string text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
			string contents = "[" + text + "] [PavingCart-Debug] " + message + "\n";
			File.AppendAllText(path, contents);
		}
		catch
		{
		}
	}

	private void Awake()
	{
		_znv = ((Component)this).GetComponent<ZNetView>();
		_container = ((Component)this).GetComponentInChildren<Container>();
		_smoke = ((Component)this).GetComponent<PavingCartSmoke>();
		ZNet instance = ZNet.instance;
		object arg = ((instance != null) ? new bool?(instance.IsServer()) : null);
		ZNet instance2 = ZNet.instance;
		DebugLog($"AWAKE: PavingCart component created. IsServer={arg}, IsDedicated={((instance2 != null) ? new bool?(instance2.IsDedicated()) : null)}, ZNet exists={(Object)(object)ZNet.instance != (Object)null}");
		((MonoBehaviour)this).StartCoroutine(DelayedInitialization());
	}

	private void Start()
	{
		ApplyCartTint();
	}

	[IteratorStateMachine(typeof(<DelayedInitialization>d__23))]
	private IEnumerator DelayedInitialization()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DelayedInitialization>d__23(0)
		{
			<>4__this = this
		};
	}

	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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_znv == (Object)null || !_znv.IsValid())
		{
			DebugLog("RegisterRPCs: ZNetView not valid, skipping RPC registration");
			return;
		}
		if (_rpcsRegistered)
		{
			DebugLog("RegisterRPCs: RPCs already registered, skipping");
			return;
		}
		ZDOID uid = _znv.GetZDO().m_uid;
		object arg = uid;
		ZNet instance = ZNet.instance;
		DebugLog($"RegisterRPCs: Registering RPCs for cart ZDOID={arg}, IsServer={((instance != null) ? new bool?(instance.IsServer()) : null)}");
		_znv.Register<bool>("RPC_PavingCart_SetEnabled", (Action<long, bool>)RPC_SetEnabled);
		if (ZRoutedRpc.instance == null)
		{
			DebugLog("RegisterRPCs: WARNING - ZRoutedRpc.instance is null!");
		}
		else
		{
			DebugLog("RegisterRPCs: Global routed RPCs handled by main plugin, skipping local registration");
		}
		_rpcsRegistered = true;
		DebugLog("RegisterRPCs: All RPCs registered successfully");
	}

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

	private void RPC_DoPave_Server(long sender, ZDOID cartZDOID, Vector3 pos, float radius)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		DebugLog($"RPC_DoPave_Server: Received from {sender} for cart {cartZDOID} at {pos} radius {radius}");
		if (!ZNet.instance.IsServer())
		{
			DebugLog("RPC_DoPave_Server: Not server, ignoring");
			return;
		}
		DebugLog("RPC_DoPave_Server: Server processing pave request (legacy path)");
		ApplyPave(pos, radius);
	}

	private void RPC_DoLevelOnly_Server(long sender, ZDOID cartZDOID, Vector3 pos, float radius)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		DebugLog($"RPC_DoLevelOnly_Server: Received from {sender} for cart {cartZDOID} at {pos} radius {radius}");
		if (!ZNet.instance.IsServer())
		{
			DebugLog("RPC_DoLevelOnly_Server: Not server, ignoring");
			return;
		}
		DebugLog("RPC_DoLevelOnly_Server: Server processing level request (legacy path)");
		ApplyLevelOnly(pos, radius);
	}

	public void ApplyPaveGlobal(Vector3 pos, float radius)
	{
		//IL_0005: 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)
		DebugLog($"ApplyPaveGlobal: Called from global handler at {pos} radius {radius}");
		if (!ZNet.instance.IsServer())
		{
			DebugLog("ApplyPaveGlobal: Not server, aborting");
		}
		else
		{
			ApplyPave(pos, radius);
		}
	}

	public void ApplyLevelOnlyGlobal(Vector3 pos, float radius)
	{
		//IL_0005: 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)
		DebugLog($"ApplyLevelOnlyGlobal: Called from global handler at {pos} radius {radius}");
		if (!ZNet.instance.IsServer())
		{
			DebugLog("ApplyLevelOnlyGlobal: Not server, aborting");
		}
		else
		{
			ApplyLevelOnly(pos, radius);
		}
	}

	private void OnEnable()
	{
		ZNet instance = ZNet.instance;
		DebugLog($"ONENABLE: Component enabled. IsServer={((instance != null) ? new bool?(instance.IsServer()) : null)}, ZNV exists={(Object)(object)_znv != (Object)null}");
	}

	private void InitializeServerSide()
	{
		ZNet instance = ZNet.instance;
		DebugLog($"InitializeServerSide: Ensuring server-side cart is properly set up. IsServer={((instance != null) ? new bool?(instance.IsServer()) : null)}");
		DebugLog("InitializeServerSide: RPCs already registered during initialization");
		_serverInitialized = true;
		DebugLog("InitializeServerSide: Server-side initialization complete");
	}

	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 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);
		DebugLog($"Interact: Toggling paving from {!flag} to {flag}");
		_znv.InvokeRPC(ZNetView.Everybody, "RPC_PavingCart_SetEnabled", new object[1] { flag });
		((Character)user).Message((MessageType)2, "Paving " + (flag ? "Enabled" : "Disabled"), 0, (Sprite)null);
		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_00a7: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: 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)
		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;
		}
		float num = Vector3.Distance(position, _lastStampPos);
		if (num < CheckEveryMeters)
		{
			return;
		}
		DebugLog($"Paving triggered: Distance={num:F2}m, Position={position}");
		Vector3 val = position + Vector3.down * 0.2f;
		if (HasStones(StonesPerStamp))
		{
			DebugLog($"Has stones, consuming and requesting full paving at {val}");
			if (TryConsumeStone(StonesPerStamp))
			{
				RPC_Pave(val, PaveRadius);
			}
			else
			{
				DebugLog("Stone consumption failed, falling back to level-only");
				RPC_LevelOnly(val, PaveRadius);
			}
		}
		else
		{
			DebugLog($"No stones, requesting level-only at {val}");
			RPC_LevelOnly(val, 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 inventory.GetAllItems().Where(delegate(ItemData item)
		{
			if (item.m_shared?.m_name == null)
			{
				return false;
			}
			string name = item.m_shared.m_name;
			return string.Equals(name, StoneItemName, StringComparison.OrdinalIgnoreCase) || string.Equals(name, "$" + StoneItemName, StringComparison.OrdinalIgnoreCase) || name.IndexOf("stone", StringComparison.OrdinalIgnoreCase) >= 0;
		}).ToList()
			.Sum((ItemData item) => item.m_stack) >= amount;
	}

	private bool TryConsumeStone(int amount)
	{
		DebugLog($"TryConsumeStone: Attempting to consume {amount} stones");
		if ((Object)(object)_container == (Object)null)
		{
			Logger.LogWarning((object)"PavingCart: No container for stone consumption");
			DebugLog("TryConsumeStone: No container found");
			return false;
		}
		Inventory inventory = _container.GetInventory();
		if (inventory == null)
		{
			Logger.LogWarning((object)"PavingCart: No inventory for stone consumption");
			DebugLog("TryConsumeStone: No inventory in container");
			return false;
		}
		List<ItemData> source = inventory.GetAllItems().Where(delegate(ItemData item)
		{
			if (item.m_shared?.m_name == null)
			{
				return false;
			}
			string name = item.m_shared.m_name;
			return string.Equals(name, StoneItemName, StringComparison.OrdinalIgnoreCase) || string.Equals(name, "$" + StoneItemName, StringComparison.OrdinalIgnoreCase) || name.IndexOf("stone", StringComparison.OrdinalIgnoreCase) >= 0;
		}).ToList();
		int num = source.Sum((ItemData item) => item.m_stack);
		DebugLog($"TryConsumeStone: Found {num} stones in inventory");
		if (num < amount)
		{
			DebugLog($"TryConsumeStone: Not enough stones ({num} < {amount})");
			return false;
		}
		int num2 = amount;
		foreach (ItemData item in source.OrderBy((ItemData x) => x.m_shared.m_name))
		{
			if (num2 <= 0)
			{
				break;
			}
			int num3 = Math.Min(num2, item.m_stack);
			inventory.RemoveItem(item.m_shared.m_name, num3, -1, true);
			num2 -= num3;
			DebugLog($"TryConsumeStone: Removed {num3} {item.m_shared.m_name}, {num2} left to remove");
		}
		_container.m_inventory.Changed();
		bool flag = num2 == 0;
		DebugLog("TryConsumeStone: Consumption " + (flag ? "successful" : "failed"));
		return flag;
	}

	private void RPC_Pave(Vector3 worldPos, float radius)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0073: 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)
		if ((Object)(object)_znv == (Object)null || !_znv.IsValid())
		{
			DebugLog("RPC_Pave: Invalid ZNetView, cannot send RPC");
			return;
		}
		ZDOID uid = _znv.GetZDO().m_uid;
		DebugLog($"RPC_Pave: Sending DoPave RPC to server for cart {uid} at {worldPos} radius {radius}");
		if (ZRoutedRpc.instance != null)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PavingCart_DoPave", new object[3] { uid, worldPos, radius });
		}
		else
		{
			DebugLog("RPC_Pave: ERROR - ZRoutedRpc.instance is null!");
		}
	}

	private void ApplyPave(Vector3 center, float radius)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		DebugLog($"ApplyPave: Starting at {center} radius {radius}");
		if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer())
		{
			Logger.LogWarning((object)"ApplyPave called on client - ignoring");
			DebugLog("ApplyPave: Not server, aborting");
			return;
		}
		DebugLog("ApplyPave: Server check passed, attempting stone consumption");
		if (!TryConsumeStone(StonesPerStamp))
		{
			DebugLog("ApplyPave: Stone consumption failed, falling back to level-only");
			ApplyLevelOnly(center, radius);
		}
		else
		{
			DebugLog("ApplyPave: Stone consumed successfully, applying paved terrain");
			Server_TerrainOp(center, radius, "Paved");
		}
	}

	private void Server_TerrainOp(Vector3 center, float radius, string paintName)
	{
		//IL_0005: 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)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		DebugLog($"Server_TerrainOp: Starting at {center} radius {radius} paint {paintName}");
		float time = Time.time;
		float num = time - lastOperationTime;
		float num2 = Vector3.Distance(center, lastOperationPosition);
		if (num < 1f)
		{
			DebugLog($"Server_TerrainOp: Skipping - cooldown active ({num:F2}s < {1f}s)");
			return;
		}
		if (num2 < 2f && lastOperationPosition != Vector3.zero)
		{
			DebugLog($"Server_TerrainOp: Skipping - too close to last op ({num2:F2}m < {2f}m)");
			return;
		}
		if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer())
		{
			DebugLog("Server_TerrainOp: Not server, aborting");
			return;
		}
		DebugLog("Server_TerrainOp: All checks passed, creating terrain piece");
		lastOperationTime = time;
		lastOperationPosition = center;
		CreateTerrainPiece(center, radius, paintName);
	}

	private void CreateTerrainPiece(Vector3 center, float radius, string paintName)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		DebugLog($"CreateTerrainPiece: Starting at {center} radius {radius} paint {paintName}");
		string text = "paved_road_v2";
		text = paintName.ToLower() switch
		{
			"dirt" => "mud_road_v2", 
			"path" => "path_v2", 
			_ => "paved_road_v2", 
		};
		DebugLog("CreateTerrainPiece: Using prefab " + text);
		GameObject prefab = PrefabManager.Instance.GetPrefab(text);
		if ((Object)(object)prefab == (Object)null)
		{
			Logger.LogError((object)("Could not find prefab: " + text));
			DebugLog("CreateTerrainPiece: ERROR - Prefab " + text + " not found!");
			return;
		}
		DebugLog("CreateTerrainPiece: Prefab found, instantiating");
		GameObject val = Object.Instantiate<GameObject>(prefab, center, Quaternion.identity);
		if ((Object)(object)val == (Object)null)
		{
			Logger.LogError((object)("Failed to instantiate terrain piece: " + text));
			DebugLog("CreateTerrainPiece: ERROR - Failed to instantiate " + text + "!");
			return;
		}
		DebugLog("CreateTerrainPiece: Terrain piece instantiated, configuring settings");
		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;
			}
			DebugLog($"CreateTerrainPiece: TerrainOp configured - level={settings.m_level}, levelRadius={settings.m_levelRadius}, smooth={settings.m_smooth}, smoothRadius={settings.m_smoothRadius}, paintRadius={settings.m_paintRadius}");
		}
		else
		{
			DebugLog("CreateTerrainPiece: WARNING - No TerrainOp component found on " + text);
		}
		float num = radius * ClutterClearScale;
		ClutterSystem instance = ClutterSystem.instance;
		if (instance != null)
		{
			instance.ResetGrass(center, num);
		}
		DebugLog($"CreateTerrainPiece: Completed successfully, clutter cleared at radius {num}");
	}

	private void RPC_LevelOnly(Vector3 worldPos, float radius)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0073: 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)
		if ((Object)(object)_znv == (Object)null || !_znv.IsValid())
		{
			DebugLog("RPC_LevelOnly: Invalid ZNetView, cannot send RPC");
			return;
		}
		ZDOID uid = _znv.GetZDO().m_uid;
		DebugLog($"RPC_LevelOnly: Sending DoLevelOnly RPC to server for cart {uid} at {worldPos} radius {radius}");
		if (ZRoutedRpc.instance != null)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PavingCart_DoLevelOnly", new object[3] { uid, worldPos, radius });
		}
		else
		{
			DebugLog("RPC_LevelOnly: ERROR - ZRoutedRpc.instance is null!");
		}
	}

	private void ApplyLevelOnly(Vector3 center, float radius)
	{
		//IL_0005: 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)
		DebugLog($"ApplyLevelOnly: Starting at {center} radius {radius}");
		if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer())
		{
			Logger.LogWarning((object)"ApplyLevelOnly called on client - ignoring");
			DebugLog("ApplyLevelOnly: Not server, aborting");
		}
		else
		{
			DebugLog("ApplyLevelOnly: Server check passed, applying dirt terrain");
			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;

	private void Update()
	{
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: 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_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: 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)
			{
				string name = item.m_shared.m_name;
				if (!string.Equals(name, StoneItemName, StringComparison.OrdinalIgnoreCase) && !string.Equals(name, "$" + StoneItemName, StringComparison.OrdinalIgnoreCase) && name.IndexOf("stone", StringComparison.OrdinalIgnoreCase) < 0 && 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));
		string name = item.m_shared.m_name;
		if (!string.Equals(name, "Stone", StringComparison.OrdinalIgnoreCase) && !string.Equals(name, "$Stone", StringComparison.OrdinalIgnoreCase) && name.IndexOf("stone", StringComparison.OrdinalIgnoreCase) < 0)
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, "⚠\ufe0f Paving Cart only accepts stone materials", 0, (Sprite)null);
			}
			__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.0.0")]
[BepInDependency(/*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.0.0";

	private const string PavingCartPrefabName = "PavingCart";

	private const string VanillaCartPrefab = "Cart";

	private const string StoneItemName = "Stone";

	private Harmony _harmony;

	private static TorvaldsPavers _instance;

	private void Awake()
	{
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Expected O, but got Unknown
		_instance = this;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"TORVALDS PAVERS MOD LOADING - SERVER TEST");
		Console.WriteLine("TORVALDS PAVERS: MOD LOADING ON SERVER - CONSOLE TEST");
		try
		{
			string path = "torvalds_pavers_server_test.log";
			string text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
			object[] obj = new object[4] { text, null, null, null };
			ZNet instance = ZNet.instance;
			obj[1] = ((instance != null) ? new bool?(instance.IsServer()) : null);
			ZNet instance2 = ZNet.instance;
			obj[2] = ((instance2 != null) ? new bool?(instance2.IsDedicated()) : null);
			obj[3] = Directory.GetCurrentDirectory();
			string contents = string.Format("[{0}] TORVALDS PAVERS MOD AWAKE - IsServer={1}, IsDedicated={2}, WorkingDir={3}\n", obj);
			File.AppendAllText(path, contents);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Failed to write test log file: " + ex.Message));
			Console.WriteLine("TORVALDS PAVERS: Failed to write log file: " + ex.Message);
		}
		_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>("PavingCart_DoPave", (Action<long, ZDOID, Vector3, float>)_instance.GlobalRPC_DoPave);
				ZRoutedRpc.instance.Register<ZDOID, Vector3, float>("PavingCart_DoLevelOnly", (Action<long, ZDOID, Vector3, float>)_instance.GlobalRPC_DoLevelOnly);
				ZRoutedRpc.instance.Register<Vector3, float, string>("PavingCart_ExecuteTerrainOp", (Action<long, Vector3, float, string>)_instance.RPC_ExecuteTerrainOp);
			}
		};
	}

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

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

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

	private PavingCartPaver FindCartPaverByZDOID(ZDOID zdoid)
	{
		//IL_000b: 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_006b: 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_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"FindCartPaverByZDOID: Searching for cart with ZDOID {zdoid}");
		PavingCartPaver[] array = Object.FindObjectsByType<PavingCartPaver>((FindObjectsSortMode)0);
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"FindCartPaverByZDOID: Found {array.Length} cart pavers in scene");
		PavingCartPaver[] array2 = array;
		foreach (PavingCartPaver pavingCartPaver in array2)
		{
			ZNetView component = ((Component)pavingCartPaver).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				ZDOID uid = component.GetZDO().m_uid;
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"FindCartPaverByZDOID: Checking paver with ZDOID {uid}");
				if (uid == zdoid)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"FindCartPaverByZDOID: Found matching cart paver!");
					return pavingCartPaver;
				}
			}
		}
		((BaseUnityPlugin)this).Logger.LogWarning((object)$"FindCartPaverByZDOID: No matching cart found for ZDOID {zdoid}");
		return null;
	}

	private void CreateTerrainPieceLocal(Vector3 center, float radius, string paintName)
	{
		//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_0111: 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)("CreateTerrainPieceLocal: 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)("CreateTerrainPieceLocal: Failed to instantiate terrain piece: " + text3));
			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;
			}
			component.OnPlaced();
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("CreateTerrainPieceLocal: No TerrainOp component found on " + text3));
		}
		ClutterSystem instance = ClutterSystem.instance;
		if (instance != null)
		{
			instance.ResetGrass(center, radius * 1.5f);
		}
	}

	private void 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_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Expected O, but got Unknown
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Expected O, but got Unknown
		CreateTerrainStampPrefab();
		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);
		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 CreateTerrainStampPrefab()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Expected O, but got Unknown
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		GameObject val = new GameObject("Paver_TerrainStamp");
		val.AddComponent<ZNetView>().m_type = (ObjectType)0;
		TerrainModifier obj = val.AddComponent<TerrainModifier>();
		obj.m_level = true;
		obj.m_levelRadius = 2.4f;
		obj.m_levelOffset = 0f;
		obj.m_square = false;
		obj.m_paintRadius = 2.4f;
		obj.m_paintType = (PaintType)0;
		CustomPrefab val2 = new CustomPrefab(val, false);
		PrefabManager.Instance.AddPrefab(val2);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Terrain stamp prefab created and 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 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()) : null)}");
		}
	}
}