Decompiled source of HexWaterproofBuilding v1.5.0

plugins/HexWaterproofBuilding.dll

Decompiled 2 weeks ago
using System;
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 BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using HexWaterproofBuilding;
using HexWaterproofBuilding.Components;
using HexWaterproofBuilding.Core;
using HexWaterproofBuilding.Discovery;
using HexWaterproofBuilding.Rules;
using HexWaterproofBuilding.Utils;
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("HexWaterproofBuilding")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HexWaterproofBuilding")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("69555090-1b3b-4323-9007-2b83a7a50186")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(CraftingStation), "Start")]
internal static class PatchCraftingStation
{
	[HarmonyPrefix]
	internal static void Prefix(CraftingStation __instance)
	{
		if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsModEnabled && !Plugin.Instance.IsWorkBenchRequireRoof)
		{
			string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject);
			if (prefabName.Equals("piece_workbench") || prefabName.Equals("waterproof_piece_workbench", StringComparison.OrdinalIgnoreCase))
			{
				__instance.m_craftRequireRoof = false;
			}
		}
	}
}
namespace HexWaterproofBuilding
{
	[BepInPlugin("hex.waterproofbuilding", "HexWaterproofBuilding", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string PluginGuid = "hex.waterproofbuilding";

		private const string PluginName = "HexWaterproofBuilding";

		private const string PluginVersion = "1.5.0";

		private Harmony _harmony;

		private ConfigEntry<bool> _modEnabled;

		private ConfigEntry<bool> _extendedPlacementRangeEnabled;

		private ConfigEntry<bool> _extendedPlacementForVanillaPiecesEnabled;

		private ConfigEntry<bool> _workBenchRequireRoof;

		private ConfigEntry<bool> _woodAndBoneStacksTakeRainDamage;

		private CustomLocalization _localization;

		internal static Plugin Instance { get; private set; }

		internal bool IsModEnabled
		{
			get
			{
				if (_modEnabled != null)
				{
					return _modEnabled.Value;
				}
				return false;
			}
		}

		internal bool IsExtendedPlacementRangeEnabled
		{
			get
			{
				if (_extendedPlacementRangeEnabled != null)
				{
					return _extendedPlacementRangeEnabled.Value;
				}
				return false;
			}
		}

		internal bool IsExtendedPlacementForVanillaPiecesEnabled
		{
			get
			{
				if (_extendedPlacementForVanillaPiecesEnabled != null)
				{
					return _extendedPlacementForVanillaPiecesEnabled.Value;
				}
				return false;
			}
		}

		internal bool IsWorkBenchRequireRoof
		{
			get
			{
				if (_workBenchRequireRoof != null)
				{
					return _workBenchRequireRoof.Value;
				}
				return false;
			}
		}

		internal bool IsWoodAndBoneStacksTakeRainDamage
		{
			get
			{
				if (_woodAndBoneStacksTakeRainDamage != null)
				{
					return _woodAndBoneStacksTakeRainDamage.Value;
				}
				return false;
			}
		}

		internal AssetBundle AssetBundle { get; private set; }

		internal GameObject PierLog4Asset { get; private set; }

		private void Awake()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			Instance = this;
			LoadAssets();
			AddLocalizations();
			_modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable the Waterproof Building mod.");
			_extendedPlacementRangeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Extended Placement Range", "Enabled", true, "Enable extended placement range for waterproof pieces.");
			_extendedPlacementForVanillaPiecesEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Extended Placement Range", "VanillaPiecesEnabled", false, "Enable extended placement range for vanilla building pieces.");
			_workBenchRequireRoof = ((BaseUnityPlugin)this).Config.Bind<bool>("Workbenches", "WorkBenchRequireRoof", false, "Require a roof for workbenches to function.");
			_woodAndBoneStacksTakeRainDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Wood Stacks", "WoodAndBoneStacksTakeRainDamage", false, "Wood and bone stacks will take rain damage if this value is set to true.");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony = new Harmony("hex.waterproofbuilding");
			_harmony.PatchAll(executingAssembly);
			if (IsModEnabled)
			{
				PrefabManager.OnVanillaPrefabsAvailable += WaterproofPieceRegistrar.RegisterPieces;
			}
			Logger.LogInfo((object)"HexWaterproofBuilding v1.5.0 loaded.");
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"HexWaterproofBuilding v1.5.0 unloaded.");
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
			PrefabManager.OnVanillaPrefabsAvailable -= WaterproofPieceRegistrar.RegisterPieces;
			Instance = null;
		}

		private bool LoadAssets()
		{
			AssetBundle = AssetUtils.LoadAssetBundleFromResources("piersupport", Assembly.GetExecutingAssembly());
			if ((Object)(object)AssetBundle == (Object)null)
			{
				return false;
			}
			PierLog4Asset = AssetBundle.LoadAsset<GameObject>("hex_pier_log_4_vertical");
			return (Object)(object)PierLog4Asset != (Object)null;
		}

		private void AddLocalizations()
		{
			_localization = LocalizationManager.Instance.GetLocalization();
			CustomLocalization localization = _localization;
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "piece_hex_pier_log_4_vertical", "4m Vertical Pier Support" },
				{ "piece_hex_pier_log_4_vertical_desc", "A pier support that extends to the seabed. Cannot be placed on dry land." }
			});
		}
	}
}
namespace HexWaterproofBuilding.Utils
{
	internal static class PieceUtility
	{
		internal static bool IsWaterproofPiece(Piece piece)
		{
			if ((Object)(object)piece == (Object)null)
			{
				return false;
			}
			return ((Object)piece).name.Replace("(Clone)", "").StartsWith("Waterproof_");
		}

		internal static bool CanUseExtendedPlacementForPiece(Piece piece)
		{
			if ((Object)(object)piece == (Object)null)
			{
				return false;
			}
			if (IsWaterproofPiece(piece))
			{
				return true;
			}
			if (!FeatureFlags.CanUseExtendedPlacementForVanillaPieces())
			{
				return false;
			}
			return IsVanillaBuildingPiece(piece);
		}

		private static bool IsVanillaBuildingPiece(Piece piece)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			if ((Object)(object)piece == (Object)null)
			{
				return false;
			}
			string text = ((Object)piece).name.Replace("(Clone)", "");
			if (text.StartsWith("Waterproof_"))
			{
				return false;
			}
			bool num = text == "piece_workbench";
			bool flag = (int)piece.m_category == 2;
			return num || flag;
		}
	}
	internal static class FeatureFlags
	{
		internal static bool CanUseExtendedPlacement()
		{
			if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.IsModEnabled)
			{
				return Plugin.Instance.IsExtendedPlacementRangeEnabled;
			}
			return false;
		}

		internal static bool CanUseExtendedPlacementForVanillaPieces()
		{
			if (CanUseExtendedPlacement())
			{
				return Plugin.Instance.IsExtendedPlacementForVanillaPiecesEnabled;
			}
			return false;
		}
	}
}
namespace HexWaterproofBuilding.Discovery
{
	internal static class PrefabDiscovery
	{
		internal static IEnumerable<GameObject> GetPrefabs(Func<GameObject, bool> predicate)
		{
			Dictionary<string, Object> prefabs = Cache.GetPrefabs(typeof(GameObject));
			foreach (KeyValuePair<string, Object> item in prefabs)
			{
				Object value = item.Value;
				GameObject val = (GameObject)(object)((value is GameObject) ? value : null);
				if (!((Object)(object)val == (Object)null) && (predicate == null || predicate(val)))
				{
					yield return val;
				}
			}
		}

		internal static Dictionary<string, int> GetHammerPieceIndexes()
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			Object prefab = Cache.GetPrefab(typeof(GameObject), "Hammer");
			GameObject val = (GameObject)(object)((prefab is GameObject) ? prefab : null);
			if ((Object)(object)val == (Object)null)
			{
				return dictionary;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.m_itemData.m_shared.m_buildPieces == (Object)null || component.m_itemData.m_shared.m_buildPieces.m_pieces == null)
			{
				return dictionary;
			}
			List<GameObject> pieces = component.m_itemData.m_shared.m_buildPieces.m_pieces;
			for (int i = 0; i < pieces.Count; i++)
			{
				GameObject val2 = pieces[i];
				if (!((Object)(object)val2 == (Object)null) && !dictionary.ContainsKey(((Object)val2).name))
				{
					dictionary.Add(((Object)val2).name, i);
				}
			}
			return dictionary;
		}
	}
}
namespace HexWaterproofBuilding.Rules
{
	internal static class WaterproofPrefabRules
	{
		private static readonly string LowerWaterproofPrefabPrefix = "Waterproof".ToLowerInvariant();

		private static readonly string LowerPierPrefabPrefix = "hex_pier_".ToLowerInvariant();

		private static readonly string[] InvalidTokens = new string[6] { "stack", "spiral", "treasure", "dvergr", "old_", "turf" };

		internal static bool IsValidPrefab(GameObject prefab)
		{
			//IL_00a2: 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)
			//IL_009d: Invalid comparison between Unknown and I4
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			if ((Object)(object)prefab == (Object)null)
			{
				return false;
			}
			Piece component = prefab.GetComponent<Piece>();
			WearNTear component2 = prefab.GetComponent<WearNTear>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				return false;
			}
			string lowerName = ((Object)prefab).name.ToLowerInvariant();
			if (lowerName.StartsWith(LowerWaterproofPrefabPrefix) || lowerName.StartsWith(LowerPierPrefabPrefix))
			{
				return false;
			}
			if (InvalidTokens.Any((string token) => lowerName.Contains(token)))
			{
				return false;
			}
			if (((Object)component).name != "piece_workbench" && (int)component.m_category != 2)
			{
				return false;
			}
			if ((int)component2.m_materialType != 0)
			{
				return (int)component2.m_materialType == 3;
			}
			return true;
		}
	}
}
namespace HexWaterproofBuilding.Patches
{
	[HarmonyPatch(typeof(Player), "CopyPiece")]
	internal static class PatchPlayerCopyPiece
	{
		private static readonly FieldRef<Player, int> RemoveRayMaskRef = AccessTools.FieldRefAccess<Player, int>("m_removeRayMask");

		private static readonly FieldRef<Player, float> PlaceRotationDegreesRef = AccessTools.FieldRefAccess<Player, float>("m_placeRotationDegrees");

		private static readonly FieldRef<Player, int> PlaceRotationRef = AccessTools.FieldRefAccess<Player, int>("m_placeRotation");

		private static readonly FastInvokeHandler SetSelectedPieceRef = MethodInvoker.GetHandler(AccessTools.Method(typeof(Player), "SetSelectedPiece", new Type[1] { typeof(Piece) }, (Type[])null), false);

		[HarmonyPrefix]
		private static bool Prefix(Player __instance, ref bool __result)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || !FeatureFlags.CanUseExtendedPlacement())
			{
				return true;
			}
			if ((Object)(object)GameCamera.instance == (Object)null || (Object)(object)((Component)GameCamera.instance).transform == (Object)null)
			{
				return true;
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(transform.position, transform.forward, ref val, 100f, RemoveRayMaskRef.Invoke(__instance)) || (Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
			{
				__result = false;
				return false;
			}
			Piece val2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
			if ((Object)(object)val2 == (Object)null && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponent<Heightmap>() != (Object)null)
			{
				val2 = TerrainModifier.FindClosestModifierPieceInRange(((RaycastHit)(ref val)).point, 2.5f);
			}
			if (!PieceUtility.CanUseExtendedPlacementForPiece(val2))
			{
				return true;
			}
			if (!(bool)SetSelectedPieceRef.Invoke((object)__instance, new object[1] { val2 }))
			{
				((Character)__instance).Message((MessageType)2, "$msg_missingrequirement", 0, (Sprite)null);
				__result = false;
				return false;
			}
			float num = PlaceRotationDegreesRef.Invoke(__instance);
			if (num <= 0f)
			{
				__result = true;
				return false;
			}
			Quaternion rotation = ((Component)val2).transform.rotation;
			PlaceRotationRef.Invoke(__instance) = (int)Math.Round(((Quaternion)(ref rotation)).eulerAngles.y / num);
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "PieceRayTest")]
	internal static class PatchPlayerPieceRayTest
	{
		private static readonly FieldRef<Player, GameObject> PlacementGhostRef = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

		private static readonly FieldRef<Player, int> PlaceRayMaskRef = AccessTools.FieldRefAccess<Player, int>("m_placeRayMask");

		private static readonly FieldRef<Player, int> PlaceWaterRayMaskRef = AccessTools.FieldRefAccess<Player, int>("m_placeWaterRayMask");

		private static readonly int WaterLayer = LayerMask.NameToLayer("Water");

		private static bool Prefix(Player __instance, ref bool __result, out Vector3 point, out Vector3 normal, out Piece piece, out Heightmap heightmap, out Collider waterSurface, bool water)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			point = Vector3.zero;
			normal = Vector3.zero;
			piece = null;
			heightmap = null;
			waterSurface = null;
			if ((Object)(object)__instance == (Object)null || !FeatureFlags.CanUseExtendedPlacement())
			{
				return true;
			}
			GameObject val = PlacementGhostRef.Invoke(__instance);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			if (!PieceUtility.CanUseExtendedPlacementForPiece(val.GetComponent<Piece>()))
			{
				return true;
			}
			int num = (water ? PlaceWaterRayMaskRef.Invoke(__instance) : PlaceRayMaskRef.Invoke(__instance));
			if ((Object)(object)GameCamera.instance == (Object)null)
			{
				return true;
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(transform.position, transform.forward, ref val2, 100f, num))
			{
				__result = false;
				return false;
			}
			if ((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null || (Object)(object)((RaycastHit)(ref val2)).collider.attachedRigidbody != (Object)null)
			{
				__result = false;
				return false;
			}
			point = ((RaycastHit)(ref val2)).point;
			normal = ((RaycastHit)(ref val2)).normal;
			piece = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Piece>();
			heightmap = ((Component)((RaycastHit)(ref val2)).collider).GetComponent<Heightmap>();
			waterSurface = ((WaterLayer >= 0 && ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer == WaterLayer) ? ((RaycastHit)(ref val2)).collider : null);
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "RemovePiece")]
	internal static class PatchPlayerRemovePiece
	{
		private static readonly FieldRef<Player, int> RemoveRayMaskRef = AccessTools.FieldRefAccess<Player, int>("m_removeRayMask");

		private static readonly FieldRef<Player, EffectList> RemoveEffectsRef = AccessTools.FieldRefAccess<Player, EffectList>("m_removeEffects");

		private static readonly FieldRef<Player, ItemData> RightItemRef = AccessTools.FieldRefAccess<Player, ItemData>("m_rightItem");

		private static readonly FieldRef<Character, ZSyncAnimation> ZanimRef = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim");

		private static readonly FastInvokeHandler CheckCanRemovePieceRef = MethodInvoker.GetHandler(AccessTools.Method(typeof(Player), "CheckCanRemovePiece", (Type[])null, (Type[])null), false);

		private static readonly FastInvokeHandler FaceLookDirectionRef = MethodInvoker.GetHandler(AccessTools.Method(typeof(Player), "FaceLookDirection", (Type[])null, (Type[])null), false);

		private static bool Prefix(Player __instance, ref bool __result)
		{
			//IL_003d: 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_0051: 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_00b2: 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_00e4: 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_00f1: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: 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_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null || !FeatureFlags.CanUseExtendedPlacement())
			{
				return true;
			}
			if ((Object)(object)GameCamera.instance == (Object)null || (Object)(object)((Component)GameCamera.instance).transform == (Object)null)
			{
				return true;
			}
			Vector3 position = ((Component)GameCamera.instance).transform.position;
			Vector3 forward = ((Component)GameCamera.instance).transform.forward;
			int num = RemoveRayMaskRef.Invoke(__instance);
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(position, forward, ref val, 100f, num))
			{
				return true;
			}
			if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
			{
				return true;
			}
			Piece val2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
			Heightmap component = ((Component)((RaycastHit)(ref val)).collider).GetComponent<Heightmap>();
			if ((Object)(object)val2 == (Object)null && (Object)(object)component != (Object)null)
			{
				val2 = TerrainModifier.FindClosestModifierPieceInRange(((RaycastHit)(ref val)).point, 2.5f);
			}
			if (!PieceUtility.CanUseExtendedPlacementForPiece(val2))
			{
				return true;
			}
			if (!val2.m_canBeRemoved)
			{
				__result = false;
				return false;
			}
			Vector3 position2 = ((Component)val2).transform.position;
			Quaternion rotation = ((Component)val2).transform.rotation;
			Transform transform = ((Component)val2).transform;
			if (Location.IsInsideNoBuildLocation(position2))
			{
				((Character)__instance).Message((MessageType)2, "$msg_nobuildzone", 0, (Sprite)null);
				__result = false;
				return false;
			}
			if (!PrivateArea.CheckAccess(position2, 0f, true, false))
			{
				((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null);
				__result = false;
				return false;
			}
			if (!(bool)CheckCanRemovePieceRef.Invoke((object)__instance, new object[1] { val2 }))
			{
				__result = false;
				return false;
			}
			ZNetView component2 = ((Component)val2).GetComponent<ZNetView>();
			if ((Object)(object)component2 == (Object)null)
			{
				__result = false;
				return false;
			}
			if (!val2.CanBeRemoved())
			{
				((Character)__instance).Message((MessageType)2, "$msg_cantremovenow", 0, (Sprite)null);
				__result = false;
				return false;
			}
			IRemoved component3 = ((Component)val2).GetComponent<IRemoved>();
			if (component3 != null)
			{
				component3.OnRemoved();
			}
			WearNTear component4 = ((Component)val2).GetComponent<WearNTear>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.Remove(false);
			}
			else
			{
				Character component5 = ((Component)val2).GetComponent<Character>();
				if ((Object)(object)component5 != (Object)null)
				{
					component5.Damage(new HitData(1E+10f));
				}
				else
				{
					ZLog.Log((object)("Removing non WNT object with hammer " + ((Object)val2).name));
					component2.ClaimOwnership();
					val2.DropResources((HitData)null);
					val2.m_placeEffect.Create(position2, rotation, transform, 1f, -1);
					RemoveEffectsRef.Invoke(__instance).Create(position2, Quaternion.identity, (Transform)null, 1f, -1);
					ZNetScene.instance.Destroy(((Component)val2).gameObject);
				}
			}
			ItemData val3 = RightItemRef.Invoke(__instance);
			if (val3 != null)
			{
				FaceLookDirectionRef.Invoke((object)__instance, Array.Empty<object>());
				ZSyncAnimation val4 = ZanimRef.Invoke((Character)(object)__instance);
				if ((Object)(object)val4 != (Object)null)
				{
					val4.SetTrigger(val3.m_shared.m_attack.m_attackAnimation);
				}
			}
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateWearNTearHover")]
	internal static class PatchPlayerUpdateWearNTearHover
	{
		private static readonly FieldRef<Player, int> RemoveRayMaskRef = AccessTools.FieldRefAccess<Player, int>("m_removeRayMask");

		private static readonly FieldRef<Player, Piece> HoveringPieceRef = AccessTools.FieldRefAccess<Player, Piece>("m_hoveringPiece");

		private static void Postfix(Player __instance)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || !FeatureFlags.CanUseExtendedPlacement() || !((Character)__instance).InPlaceMode() || (Object)(object)GameCamera.instance == (Object)null || (Object)(object)((Component)GameCamera.instance).transform == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)GameCamera.instance).transform.position;
			Vector3 forward = ((Component)GameCamera.instance).transform.forward;
			int num = RemoveRayMaskRef.Invoke(__instance);
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(position, forward, ref val, 100f, num) || (Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
			{
				return;
			}
			Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
			if (PieceUtility.CanUseExtendedPlacementForPiece(componentInParent))
			{
				HoveringPieceRef.Invoke(__instance) = componentInParent;
				WearNTear component = ((Component)componentInParent).GetComponent<WearNTear>();
				if (!((Object)(object)component == (Object)null))
				{
					component.Highlight();
				}
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "Awake")]
	internal static class PatchWearNTearAwake
	{
		[HarmonyPostfix]
		internal static void Postfix(WearNTear __instance)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsModEnabled && !Plugin.Instance.IsWoodAndBoneStacksTakeRainDamage && !((Object)(object)((Component)__instance).GetComponent<Piece>() == (Object)null))
			{
				string name = ((Object)((Component)__instance).gameObject).name;
				if (((int)__instance.m_materialType == 0 || (int)__instance.m_materialType == 3) && name.IndexOf("stack", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					__instance.m_noRoofWear = false;
				}
			}
		}
	}
}
namespace HexWaterproofBuilding.Components
{
	internal class PierComponent : MonoBehaviour
	{
		private const float MaxRaycastDistance = 100f;

		private const float GhostUpdateInterval = 0.1f;

		private const float SegmentLength = 4f;

		private const float SupportChainVerticalOffset = -4f;

		private const float InteractionColliderWidth = 0.6f;

		private const string VisualObjectName = "New";

		private const string GeneratedSupportsName = "GeneratedSupports";

		private const string InteractionColliderName = "PierInteractionCollider";

		private bool _isPlacementGhost;

		private bool? _lastGhostValidation;

		private int _terrainMask;

		private ZNetView _nview;

		private WearNTear _wear;

		private Transform _visual;

		private Vector3 _originalVisualLocalPosition;

		private void Awake()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			_isPlacementGhost = ZNetView.m_forceDisableInit;
			_terrainMask = LayerMask.GetMask(new string[1] { "terrain" });
			_nview = ((Component)this).GetComponent<ZNetView>();
			_wear = ((Component)this).GetComponent<WearNTear>();
			_visual = ((Component)this).transform.Find("New");
			if ((Object)(object)_visual != (Object)null)
			{
				_originalVisualLocalPosition = _visual.localPosition;
			}
			ApplyVisualOffset();
		}

		private void Start()
		{
			if (_isPlacementGhost)
			{
				((MonoBehaviour)this).InvokeRepeating("UpdatePlacementGhost", 0f, 0.1f);
			}
			else if (!((Object)(object)_nview == (Object)null) && _nview.GetZDO() != null)
			{
				CheckPlacedPiece();
			}
		}

		private void ApplyVisualOffset()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_wear == (Object)null))
			{
				Vector3 offset = Vector3.up * -4f;
				ApplyOffsetToVisual(_wear.m_new, offset);
				if ((Object)(object)_wear.m_worn != (Object)(object)_wear.m_new)
				{
					ApplyOffsetToVisual(_wear.m_worn, offset);
				}
				if ((Object)(object)_wear.m_broken != (Object)(object)_wear.m_new && (Object)(object)_wear.m_broken != (Object)(object)_wear.m_worn)
				{
					ApplyOffsetToVisual(_wear.m_broken, offset);
				}
			}
		}

		private void ApplyOffsetToVisual(GameObject visualObject, Vector3 offset)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)visualObject == (Object)null))
			{
				Transform transform = visualObject.transform;
				transform.localPosition += offset;
			}
		}

		private void UpdatePlacementGhost()
		{
			RaycastHit hit;
			bool flag = IsOverUnderwaterTerrain(out hit);
			if (!_lastGhostValidation.HasValue || _lastGhostValidation.Value != flag)
			{
				_lastGhostValidation = flag;
			}
		}

		private void CheckPlacedPiece()
		{
			if (IsOverUnderwaterTerrain(out var hit))
			{
				int num = Mathf.CeilToInt(((RaycastHit)(ref hit)).distance / 4f);
				int additionalSegments = Mathf.Max(0, num - 1);
				BuildSupports(additionalSegments);
				BuildInteractionCollider(num);
			}
		}

		private void BuildSupports(int additionalSegments)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_visual == (Object)null)
			{
				return;
			}
			Transform val = ((Component)this).transform.Find("GeneratedSupports");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			if (additionalSegments <= 0)
			{
				return;
			}
			GameObject val2 = new GameObject("GeneratedSupports");
			val2.transform.SetParent(((Component)this).transform, false);
			Vector3 val3 = _originalVisualLocalPosition + Vector3.up * -4f;
			for (int i = 1; i <= additionalSegments; i++)
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)_visual).gameObject, val2.transform);
				((Object)obj).name = $"Segment_{i}";
				obj.transform.localPosition = val3 + Vector3.down * 4f * (float)i;
				obj.transform.localRotation = _visual.localRotation;
				obj.transform.localScale = _visual.localScale;
				obj.SetActive(true);
				Collider[] componentsInChildren = obj.GetComponentsInChildren<Collider>();
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					componentsInChildren[j].enabled = false;
				}
			}
		}

		private void BuildInteractionCollider(int segmentCount)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (segmentCount > 0)
			{
				Transform val = ((Component)this).transform.Find("PierInteractionCollider");
				GameObject val2;
				if ((Object)(object)val == (Object)null)
				{
					val2 = new GameObject("PierInteractionCollider");
					val2.transform.SetParent(((Component)this).transform, false);
				}
				else
				{
					val2 = ((Component)val).gameObject;
				}
				val2.layer = ((Component)this).gameObject.layer;
				val2.transform.localRotation = Quaternion.identity;
				val2.transform.localScale = Vector3.one;
				float num = 4f * (float)segmentCount;
				float num2 = -2f - num;
				float num3 = (-2f + num2) * 0.5f;
				val2.transform.localPosition = new Vector3(0f, num3, 0f);
				BoxCollider val3 = val2.GetComponent<BoxCollider>();
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = val2.AddComponent<BoxCollider>();
				}
				val3.center = Vector3.zero;
				val3.size = new Vector3(0.6f, num, 0.6f);
				((Collider)val3).isTrigger = false;
				((Collider)val3).enabled = true;
			}
		}

		private bool IsOverUnderwaterTerrain(out RaycastHit hit)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			hit = default(RaycastHit);
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			if (!Physics.Raycast(((Component)this).transform.position, Vector3.down, ref hit, 100f, _terrainMask, (QueryTriggerInteraction)1))
			{
				return false;
			}
			return ((RaycastHit)(ref hit)).point.y < ZoneSystem.instance.m_waterLevel;
		}

		private void OnDestroy()
		{
			if (_isPlacementGhost)
			{
				((MonoBehaviour)this).CancelInvoke("UpdatePlacementGhost");
			}
		}
	}
}
namespace HexWaterproofBuilding.Core
{
	internal static class Constants
	{
		internal const string WaterproofCategory = "Waterproof Building";

		internal const string WaterProofPrefabPrefix = "Waterproof";

		internal const float ClosestRangeModifier = 2.5f;

		internal const float CharacterHitDataValue = 1E+10f;

		internal const float ExtendedHoverDistance = 100f;

		internal const float ExtendedPlacementDistance = 100f;

		internal const float ExtendedRemoveDistance = 100f;

		internal const float ExtendedCopyDistance = 100f;

		internal const string PierCategory = "Pier";

		internal const string PierPrefabPrefix = "hex_pier_";
	}
	internal static class ItemList
	{
		internal const string Resin = "Resin";

		internal const string RoundLog = "RoundLog";
	}
	internal static class WaterproofPieceRegistrar
	{
		private static bool _registered;

		internal static void RegisterPieces()
		{
			if (!_registered)
			{
				if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.Instance.IsModEnabled)
				{
					PrefabManager.OnVanillaPrefabsAvailable -= RegisterPieces;
					return;
				}
				int num = CreateWaterproofPieces(PrefabDiscovery.GetHammerPieceIndexes());
				CreatePierPieces();
				_registered = true;
				PrefabManager.OnVanillaPrefabsAvailable -= RegisterPieces;
				Logger.LogInfo((object)$"Waterproof pieces registered. Count: {num}");
			}
		}

		private static int CreatePierPieces()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			if ((Object)(object)Plugin.Instance == (Object)null)
			{
				return 0;
			}
			GameObject pierLog4Asset = Plugin.Instance.PierLog4Asset;
			if ((Object)(object)pierLog4Asset == (Object)null)
			{
				return 0;
			}
			if ((Object)(object)pierLog4Asset.GetComponent<PierComponent>() == (Object)null)
			{
				pierLog4Asset.AddComponent<PierComponent>();
			}
			PieceManager.Instance.AddPieceCategory("Pier");
			PieceConfig val = new PieceConfig();
			val.Name = "$piece_hex_pier_log_4_vertical";
			val.Description = "$piece_hex_pier_log_4_vertical_desc";
			val.PieceTable = PieceTables.Hammer;
			val.CraftingStation = null;
			val.Category = "Pier";
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("RoundLog", 2, 0, true),
				new RequirementConfig("Resin", 1, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece(pierLog4Asset, true, val2);
			PieceManager.Instance.AddPiece(val3);
			Logger.LogInfo((object)("Registered pier piece: " + ((Object)pierLog4Asset).name));
			return 1;
		}

		private static int CreateWaterproofPieces(Dictionary<string, int> hammerIndexes)
		{
			int num = 0;
			int value;
			foreach (GameObject item in (from prefab in PrefabDiscovery.GetPrefabs(WaterproofPrefabRules.IsValidPrefab)
				orderby (hammerIndexes != null && hammerIndexes.TryGetValue(((Object)prefab).name, out value)) ? value : int.MaxValue, ((Object)prefab).name
				select prefab).ToList())
			{
				if (CreateWaterproofPiece(item))
				{
					num++;
				}
			}
			return num;
		}

		private static bool CreateWaterproofPiece(GameObject vanillaPrefab)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if ((Object)(object)vanillaPrefab == (Object)null)
			{
				return false;
			}
			Piece component = vanillaPrefab.GetComponent<Piece>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.LogWarning((object)(((Object)vanillaPrefab).name + " has no Piece component. Skipping."));
				return false;
			}
			string text = "Waterproof_" + ((Object)vanillaPrefab).name;
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(text, ((Object)vanillaPrefab).name);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogWarning((object)("Failed to clone prefab: " + ((Object)vanillaPrefab).name));
				return false;
			}
			ApplyModifiersToCustomPrefab(val);
			PieceConfig val2 = BuildPieceConfig(text, component);
			CustomPiece val3 = new CustomPiece(val, true, val2);
			PieceManager.Instance.AddPiece(val3);
			Logger.LogInfo((object)("Registered waterproof building piece: " + text));
			return true;
		}

		private static void ApplyModifiersToCustomPrefab(GameObject customPrefab)
		{
			if (!((Object)(object)customPrefab == (Object)null))
			{
				WearNTear component = customPrefab.GetComponent<WearNTear>();
				if ((Object)(object)component == (Object)null)
				{
					Logger.LogWarning((object)(((Object)customPrefab).name + " has no WearNTear component."));
				}
				else
				{
					component.m_noRoofWear = false;
				}
			}
		}

		private static PieceConfig BuildPieceConfig(string customPrefabName, Piece vanillaPiece)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_004c: Expected O, but got Unknown
			return new PieceConfig
			{
				Name = customPrefabName,
				Description = "A waterproof building piece that resists water damage.",
				PieceTable = PieceTables.Hammer,
				Category = "Waterproof Building",
				Requirements = BuildRequirementConfigs(vanillaPiece, new Dictionary<string, int> { { "Resin", 1 } })
			};
		}

		private static RequirementConfig[] BuildRequirementConfigs(Piece vanillaPiece, Dictionary<string, int> customRequirements, bool keepVanillaRequirements = true)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			List<RequirementConfig> list = new List<RequirementConfig>();
			if (keepVanillaRequirements && (Object)(object)vanillaPiece != (Object)null && vanillaPiece.m_resources != null)
			{
				Requirement[] resources = vanillaPiece.m_resources;
				foreach (Requirement val in resources)
				{
					if (val != null && !((Object)(object)val.m_resItem == (Object)null))
					{
						list.Add(new RequirementConfig(((Object)val.m_resItem).name, val.m_amount, val.m_amountPerLevel, val.m_recover));
					}
				}
			}
			if (customRequirements != null)
			{
				foreach (KeyValuePair<string, int> customRequirement in customRequirements)
				{
					if (!list.Any((RequirementConfig requirement) => string.Equals(requirement.Item, customRequirement.Key, StringComparison.OrdinalIgnoreCase)))
					{
						list.Add(new RequirementConfig(customRequirement.Key, customRequirement.Value, 0, true));
					}
				}
			}
			return list.ToArray();
		}
	}
}