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!");
}
}
}