Decompiled source of ShipwrightsTouch v1.0.1

ShipwrightsTouch.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("ShipwrightsTouch")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Extra features for Valheim boats: naming and sail coloring.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+29eda9ec79a0f6912332cd03b4d0b2767af66609")]
[assembly: AssemblyProduct("ShipwrightsTouch")]
[assembly: AssemblyTitle("ShipwrightsTouch")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ValheimBoatCustomizer
{
	[HarmonyPatch]
	public static class ColoringPatches
	{
		private const string ZdoStyleKey = "custom_sail_style";

		private static int m_selectedStyle = 0;

		private const int MaxStyles = 6;

		private static readonly Color[] SailColors = (Color[])(object)new Color[6]
		{
			Color.white,
			Color.red,
			Color.blue,
			Color.green,
			Color.yellow,
			new Color(0.2f, 0.2f, 0.2f)
		};

		private static readonly string[] ColorNames = new string[6] { "White", "Red", "Blue", "Green", "Yellow", "Black" };

		private static bool m_isPlacing = false;

		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		[HarmonyPrefix]
		private static void Prefix_UpdatePlacement(Player __instance, bool takeInput, float dt, GameObject ___m_placementGhost)
		{
			if ((Object)(object)___m_placementGhost == (Object)null)
			{
				return;
			}
			Ship component = ___m_placementGhost.GetComponent<Ship>();
			if (!((Object)(object)component == (Object)null))
			{
				ApplyStyle(component, m_selectedStyle);
				if (takeInput && Input.GetKeyDown((KeyCode)103))
				{
					m_selectedStyle = (m_selectedStyle + 1) % 6;
					MessageHud.instance.ShowMessage((MessageType)2, "Sail Color: <color=yellow>" + ColorNames[m_selectedStyle] + "</color>", 0, (Sprite)null, false);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		[HarmonyPrefix]
		private static void Prefix_PlacePiece(Player __instance, Piece piece)
		{
			if ((Object)(object)piece != (Object)null && (Object)(object)((Component)piece).GetComponent<Ship>() != (Object)null)
			{
				m_isPlacing = true;
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		[HarmonyPostfix]
		private static void Postfix_PlacePiece()
		{
			if (m_isPlacing)
			{
				m_isPlacing = false;
			}
		}

		[HarmonyPatch(typeof(Ship), "Awake")]
		[HarmonyPostfix]
		private static void Postfix_ShipAwake(Ship __instance)
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				if (m_isPlacing && component.IsOwner())
				{
					ZLog.LogWarning((object)$"[ValheimBoatMod] Setting initial sail style {m_selectedStyle} for new ship: {((Object)((Component)__instance).gameObject).name}");
					component.GetZDO().Set("custom_sail_style", m_selectedStyle);
				}
				UpdateSailAppearance(__instance);
			}
		}

		[HarmonyPatch(typeof(Ship), "Start")]
		[HarmonyPostfix]
		private static void Postfix_ShipStart(Ship __instance)
		{
			UpdateSailAppearance(__instance);
		}

		private static void UpdateSailAppearance(Ship ship)
		{
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				int @int = component.GetZDO().GetInt("custom_sail_style", 0);
				ApplyStyle(ship, @int);
			}
		}

		private static void ApplyStyle(Ship ship, int style)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (style < 0 || style >= SailColors.Length)
			{
				return;
			}
			Color val = SailColors[style];
			Renderer[] componentsInChildren = ((Component)ship).GetComponentsInChildren<Renderer>(true);
			int num = 0;
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				string text = ((Object)((Component)val2).gameObject).name.ToLower();
				if (text.Contains("sail") || text.Contains("cloth") || text.Contains("flag"))
				{
					num++;
					MaterialPropertyBlock val3 = new MaterialPropertyBlock();
					val2.GetPropertyBlock(val3);
					val3.SetColor("_Color", val);
					val2.SetPropertyBlock(val3);
				}
			}
			if (num <= 0)
			{
			}
		}

		[HarmonyPatch(typeof(Ship), "UpdateSail")]
		[HarmonyPostfix]
		private static void Postfix_UpdateSail(Ship __instance)
		{
			UpdateSailAppearance(__instance);
		}

		[HarmonyPatch(typeof(Ship), "UpdateSailSize")]
		[HarmonyPostfix]
		private static void Postfix_UpdateSailSize(Ship __instance)
		{
			UpdateSailAppearance(__instance);
		}
	}
	[HarmonyPatch]
	public static class DeconstructionPatches
	{
		[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
		[HarmonyPrefix]
		private static void Prefix_CheckCanRemovePiece(ref Piece piece)
		{
			if ((Object)(object)piece == (Object)null || !Plugin.AllowShipDeconstruction.Value)
			{
				return;
			}
			Ship componentInParent = ((Component)piece).GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				if (piece.m_name.Contains("karve") || piece.m_name.Contains("longship") || piece.m_name.Contains("raft"))
				{
					ZLog.LogWarning((object)("[ValheimBoatMod] Found ship piece " + piece.m_name + " but no Ship component in parent."));
				}
			}
			else if (!piece.m_canBeRemoved)
			{
				piece.m_canBeRemoved = true;
				ZLog.LogWarning((object)("[ValheimBoatMod] Force-allowing deconstruction of ship piece: " + piece.m_name));
			}
		}

		[HarmonyPatch(typeof(Player), "RemovePiece")]
		[HarmonyPrefix]
		private static bool Prefix_RemovePiece(Player __instance)
		{
			if (!Plugin.AllowShipDeconstruction.Value)
			{
				return true;
			}
			GameObject hoverObject = ((Humanoid)__instance).GetHoverObject();
			if ((Object)(object)hoverObject == (Object)null)
			{
				return true;
			}
			Ship componentInParent = hoverObject.GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return true;
			}
			ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon();
			if (currentWeapon == null || (Object)(object)currentWeapon.m_shared.m_buildPieces == (Object)null)
			{
				return true;
			}
			Piece component = ((Component)componentInParent).GetComponent<Piece>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!component.m_canBeRemoved)
			{
				component.m_canBeRemoved = true;
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class NamingPatches
	{
		private class ShipNameTextReceiver : TextReceiver
		{
			private readonly Ship m_ship;

			public ShipNameTextReceiver(Ship ship)
			{
				m_ship = ship;
			}

			public string GetText()
			{
				ZNetView component = ((Component)m_ship).GetComponent<ZNetView>();
				return ((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO().GetString("custom_ship_name", "") : "";
			}

			public void SetText(string text)
			{
				ZNetView component = ((Component)m_ship).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.GetZDO().Set("custom_ship_name", text);
				}
			}
		}

		private const string ZdoNameKey = "custom_ship_name";

		private static Ship GetParentShip(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			Ship val = (Ship)(object)((component is Ship) ? component : null);
			if (val != null)
			{
				return val;
			}
			Ship componentInParent = component.GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			Transform root = component.transform.root;
			if ((Object)(object)root != (Object)null)
			{
				return ((Component)root).GetComponentInChildren<Ship>();
			}
			return null;
		}

		private static string GetRenameTitle()
		{
			try
			{
				string text = Localization.instance.Localize("$text_rename");
				if (string.IsNullOrEmpty(text) || text.StartsWith("$") || text.ToLower().Contains("text_rename"))
				{
					return "Rename Ship";
				}
				return text;
			}
			catch
			{
				return "Rename Ship";
			}
		}

		[HarmonyPatch(typeof(HoverText), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_HoverText(HoverText __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		[HarmonyPatch(typeof(ShipControlls), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_RudderHoverText(ShipControlls __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		[HarmonyPatch(typeof(Container), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_ContainerHoverText(Container __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		[HarmonyPatch(typeof(Chair), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_ChairHoverText(Chair __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		private static void ApplyNamingHover(Component instance, ref string result)
		{
			Ship parentShip = GetParentShip(instance);
			if ((Object)(object)parentShip == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)parentShip).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			string @string = component.GetZDO().GetString("custom_ship_name", "");
			if (!string.IsNullOrEmpty(@string))
			{
				string text = "<color=yellow>" + @string + "</color>";
				if (result == null || !result.StartsWith(text))
				{
					result = (string.IsNullOrEmpty(result) ? text : (text + "\n" + result));
				}
			}
			if (!(instance is Container))
			{
				string text2 = "[<color=yellow><b>Shift + E</b></color>] " + GetRenameTitle();
				if (result != null && !result.Contains("Shift + E"))
				{
					result = result + "\n" + text2;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Interact")]
		[HarmonyPrefix]
		private static bool Prefix_PlayerInteract(Player __instance, GameObject go, bool hold, bool alt)
		{
			if (hold || (Object)(object)go == (Object)null)
			{
				return true;
			}
			if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303))
			{
				if ((Object)(object)go.GetComponentInParent<Container>() != (Object)null)
				{
					return true;
				}
				Ship parentShip = GetParentShip(go.GetComponent<Component>());
				if ((Object)(object)parentShip != (Object)null)
				{
					TextInput.instance.RequestText((TextReceiver)(object)new ShipNameTextReceiver(parentShip), GetRenameTitle(), 20);
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Player), "Update")]
		[HarmonyPostfix]
		private static void Postfix_PlayerUpdate(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || TextInput.IsVisible() || !Input.GetKeyDown((KeyCode)101) || (!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)))
			{
				return;
			}
			GameObject hoverObject = ((Humanoid)__instance).GetHoverObject();
			if (!((Object)(object)hoverObject == (Object)null) && !((Object)(object)hoverObject.GetComponentInParent<Container>() != (Object)null) && hoverObject.GetComponentInParent<Interactable>() == null)
			{
				Ship parentShip = GetParentShip(hoverObject.GetComponent<Component>());
				if ((Object)(object)parentShip != (Object)null)
				{
					TextInput.instance.RequestText((TextReceiver)(object)new ShipNameTextReceiver(parentShip), GetRenameTitle(), 20);
				}
			}
		}
	}
	[BepInPlugin("com.malafein.shipwrightstouch", "Shipwright's Touch", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "com.malafein.shipwrightstouch";

		public const string ModName = "Shipwright's Touch";

		public const string ModVersion = "1.0.1";

		public static ConfigEntry<bool> AllowShipDeconstruction;

		private readonly Harmony harmony = new Harmony("com.malafein.shipwrightstouch");

		private void Awake()
		{
			AllowShipDeconstruction = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowShipDeconstruction", false, "Allow deconstructing ships with the hammer (middle-mouse button).");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Shipwright's Touch 1.0.1 is loading...");
			try
			{
				harmony.PatchAll();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Shipwright's Touch patches applied successfully.");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("{0} failed to apply some patches: {1}", "Shipwright's Touch", arg));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Shipwright's Touch loaded!");
		}
	}
}