Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HexWaterproofBuilding v1.5.0
plugins/HexWaterproofBuilding.dll
Decompiled 2 weeks agousing 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(); } } }