Decompiled source of HardheimShipEquipment v1.0.0

plugins/ShipEquipment.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ShipEquipment")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ShipEquipment")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1dfd2955-15aa-482e-ba47-30ef42456b96")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
public class SimpleFloat : MonoBehaviour
{
	private Vector3 _startPos;

	private void Start()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		_startPos = ((Component)this).transform.localPosition;
	}

	private void Update()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Sin(Time.time * 2f) * 0.05f;
		((Component)this).transform.localPosition = _startPos + new Vector3(0f, num, 0f);
	}
}
namespace HardheimShipEquipment;

[BepInPlugin("h4nz0.hardheimshipequipment", "HardheimShipEquipment", "1.0.0")]
[BepInDependency("com.jotunn.jotunn", "2.29.0")]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[SynchronizationMode(/*Could not decode attribute arguments.*/)]
public class HardheimShipEquipmentPlugin : BaseUnityPlugin
{
	private sealed class UnityAudioSpamFilterLogHandler : ILogHandler
	{
		private readonly ILogHandler _inner;

		public UnityAudioSpamFilterLogHandler(ILogHandler inner)
		{
			_inner = inner;
		}

		public void LogFormat(LogType logType, Object context, string format, params object[] args)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = ((args != null && args.Length != 0) ? string.Format(format, args) : format);
				if (text != null && text.Contains("Attempting to set `time` on an audio source"))
				{
					return;
				}
			}
			catch
			{
			}
			ILogHandler inner = _inner;
			if (inner != null)
			{
				inner.LogFormat(logType, context, format, args);
			}
		}

		public void LogException(Exception exception, Object context)
		{
			ILogHandler inner = _inner;
			if (inner != null)
			{
				inner.LogException(exception, context);
			}
		}
	}

	public const string ModGuid = "h4nz0.hardheimshipequipment";

	public const string ModName = "HardheimShipEquipment";

	public const string ModVersion = "1.0.0";

	public const string ShipTorchPrefabName = "HH_ShipTorch";

	public const string ShipTorchIronPrefabName = "HH_ShipTorchIron";

	public const string ShipTorchMistPrefabName = "HH_ShipTorchMist";

	public const string DrumHoopsItemName = "HH_DrumHoops";

	public const string ShipDrumPrefabName = "HH_ShipDrum";

	private const string RpcRegisterGender = "HH_RegisterGender";

	private const string RpcSyncGender = "HH_SyncGender";

	public const string ZdoSongIndex = "hh_song_index";

	public const string ZdoSongDrumActive = "hh_song_drum_active";

	public const string ZdoSongDrumStart = "hh_song_drum_start";

	public const string ZdoSongDrummerId = "hh_song_drummer_id";

	public const string ZdoSongDrummerHeartbeat = "hh_song_drummer_heartbeat";

	public const string ZdoSongVocalStart = "hh_song_vocal_start";

	public const string ZdoSongMaleVocalCount = "hh_song_male_vocal_count";

	public const string ZdoSongFemaleVocalCount = "hh_song_female_vocal_count";

	public const string ZdoSongMaleVocalPlayerId = "hh_song_male_vocal_player_id";

	public const string ZdoSongFemaleVocalPlayerId = "hh_song_female_vocal_player_id";

	public const string ZdoSongFinishedToken = "hh_song_finished_token";

	public const string ZdoSongFinishedIndex = "hh_song_finished_index";

	public const string SongBuffInternalName = "HardheimSongBuff";

	public static readonly int SongBuffHash = StringExtensionMethods.GetStableHashCode("HardheimSongBuff");

	public const string UnderworldBuffInternalName = "HardheimUnderworldBuff";

	public const float UnderworldArmorMultiplier = 1.1f;

	public const float UnderworldMaxStaminaMultiplier = 1.1f;

	internal static HardheimShipEquipmentPlugin Instance;

	internal static ManualLogSource Log;

	private Harmony _harmony;

	private bool _pieceRegistered;

	private string _modRootPath;

	private string _pluginsPath;

	private string _soundsPath;

	private string _genderYamlPath;

	private readonly Dictionary<string, string> _genderById = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

	private bool _localPlayerRegistered;

	private bool _genderRpcRegistered;

	private static ILogHandler _originalUnityLogHandler;

	private static bool _unityAudioSpamFilterInstalled;

	internal static ConfigEntry<bool> CfgEnableMod;

	internal static ConfigEntry<bool> CfgDebug;

	internal static ConfigEntry<float> CfgAttachSearchRadius;

	internal static ConfigEntry<float> CfgReattachInterval;

	internal static ConfigEntry<string> CfgPieceTable;

	internal static ConfigEntry<string> CfgCategory;

	internal static ConfigEntry<int> CfgWoodCost;

	internal static ConfigEntry<int> CfgResinCost;

	internal static ConfigEntry<bool> CfgDestroyIfNotOnShip;

	internal static ConfigEntry<bool> CfgNoRoofWear;

	internal static ConfigEntry<float> CfgGhostSnapSearchRadius;

	internal static ConfigEntry<float> CfgMarkerOffsetY;

	internal static ConfigEntry<float> CfgMarkerOffsetStep;

	internal static ConfigEntry<float> CfgFinalPlacementOffsetY;

	internal static ConfigEntry<KeyboardShortcut> CfgMarkerOffsetUpKey;

	internal static ConfigEntry<KeyboardShortcut> CfgMarkerOffsetDownKey;

	internal static ConfigEntry<KeyboardShortcut> CfgMarkerOffsetLogKey;

	internal static ConfigEntry<KeyboardShortcut> CfgDumpHHStateKey;

	internal static ConfigEntry<bool> CfgEnableMigrationFileLog;

	internal static ConfigEntry<int> CfgKeepMigrationLogs;

	internal static ConfigEntry<float> CfgMigrationPlayerProximityRadius;

	private static AssetBundle _iconBundle;

	private static Sprite _drumRingIcon;

	private static Sprite _drumIcon;

	private static AssetBundle _drumBundle;

	private static GameObject _drumPrefab;

	internal string SoundsPath => _soundsPath;

	private void EnsureModFolders()
	{
		try
		{
			_modRootPath = Path.Combine(Paths.ConfigPath, "HardheimShipEquipment");
			_pluginsPath = Path.Combine(_modRootPath, "plugins");
			_soundsPath = Path.Combine(_modRootPath, "sounds");
			Directory.CreateDirectory(_modRootPath);
			Directory.CreateDirectory(_pluginsPath);
			Directory.CreateDirectory(_soundsPath);
			_genderYamlPath = Path.Combine(_modRootPath, "player_genders.yml");
			EnsureGenderYamlExists();
			LoadGenderYaml();
			Log.LogInfo((object)"[HardheimShipEquipment] Mappák létrehozva:");
			Log.LogInfo((object)("Root: " + _modRootPath));
			Log.LogInfo((object)("Plugins: " + _pluginsPath));
			Log.LogInfo((object)("Sounds: " + _soundsPath));
			Log.LogInfo((object)("GenderYaml: " + _genderYamlPath));
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Hiba mappák létrehozásakor: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void EnsureGenderYamlExists()
	{
		try
		{
			if (!string.IsNullOrWhiteSpace(_genderYamlPath) && !File.Exists(_genderYamlPath))
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("# Hardheim Ship Equipment - player gender map");
				stringBuilder.AppendLine("# Kulcs: SteamID / fallback player profile ID");
				stringBuilder.AppendLine("# Érték: male vagy female");
				stringBuilder.AppendLine("players:");
				stringBuilder.AppendLine("  \"76561198000000000\": male");
				stringBuilder.AppendLine("  \"76561198000000001\": female");
				File.WriteAllText(_genderYamlPath, stringBuilder.ToString(), Encoding.UTF8);
				Log.LogInfo((object)("[HardheimShipEquipment] Létrehozva: " + _genderYamlPath));
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Gender YAML create error: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void LoadGenderYaml()
	{
		_genderById.Clear();
		try
		{
			if (string.IsNullOrWhiteSpace(_genderYamlPath) || !File.Exists(_genderYamlPath))
			{
				return;
			}
			string[] array = File.ReadAllLines(_genderYamlPath, Encoding.UTF8);
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (string.IsNullOrWhiteSpace(text))
				{
					continue;
				}
				string text2 = text.Trim();
				if (text2.StartsWith("#") || text2.Equals("players:", StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				int num = text2.IndexOf(':');
				if (num > 0)
				{
					string text3 = text2.Substring(0, num).Trim().Trim(new char[1] { '"' });
					string text4 = text2.Substring(num + 1).Trim().Trim(new char[1] { '"' })
						.ToLowerInvariant();
					if (!string.IsNullOrWhiteSpace(text3) && (!(text4 != "male") || !(text4 != "female")))
					{
						_genderById[text3] = text4;
					}
				}
			}
			Log.LogInfo((object)string.Format("[{0}] Gender YAML entries betöltve: {1}", "HardheimShipEquipment", _genderById.Count));
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Gender YAML load error: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void SaveGenderYaml()
	{
		try
		{
			if (string.IsNullOrWhiteSpace(_genderYamlPath))
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("# Hardheim Ship Equipment - player gender map");
			stringBuilder.AppendLine("# Kulcs: SteamID / fallback player profile ID");
			stringBuilder.AppendLine("# Érték: male vagy female");
			stringBuilder.AppendLine("players:");
			foreach (KeyValuePair<string, string> item in _genderById.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> k) => k.Key, StringComparer.OrdinalIgnoreCase))
			{
				stringBuilder.AppendLine("  \"" + item.Key + "\": " + item.Value);
			}
			File.WriteAllText(_genderYamlPath, stringBuilder.ToString(), Encoding.UTF8);
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Gender YAML save error: {1}", "HardheimShipEquipment", arg));
		}
	}

	internal string ResolveLocalPlayerIdentityKey(Player player)
	{
		try
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				MethodInfo method = typeof(ZNet).GetMethod("GetUID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method != null)
				{
					object obj = method.Invoke(ZNet.instance, null);
					if (obj != null)
					{
						string text = obj.ToString();
						if (!string.IsNullOrWhiteSpace(text) && text != "0")
						{
							return text;
						}
					}
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogDebug((object)string.Format("[{0}] ResolveLocalPlayerIdentityKey ZNet.GetUID error: {1}", "HardheimShipEquipment", arg));
		}
		try
		{
			if ((Object)(object)Game.instance != (Object)null)
			{
				PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
				if (playerProfile != null)
				{
					long playerID = playerProfile.GetPlayerID();
					if (playerID != 0)
					{
						return playerID.ToString();
					}
				}
			}
		}
		catch (Exception arg2)
		{
			Log.LogDebug((object)string.Format("[{0}] ResolveLocalPlayerIdentityKey profile error: {1}", "HardheimShipEquipment", arg2));
		}
		try
		{
			if ((Object)(object)player != (Object)null)
			{
				string playerName = player.GetPlayerName();
				if (!string.IsNullOrWhiteSpace(playerName))
				{
					return playerName;
				}
			}
		}
		catch
		{
		}
		return "unknown";
	}

	internal bool ResolveFemaleFromYaml(Player player)
	{
		string text = ResolveLocalPlayerIdentityKey(player);
		if (string.IsNullOrWhiteSpace(text))
		{
			text = "unknown";
		}
		if (_genderById.Count == 0)
		{
			LoadGenderYaml();
		}
		if (_genderById.TryGetValue(text, out var value))
		{
			bool result = string.Equals(value, "female", StringComparison.OrdinalIgnoreCase);
			Log.LogDebug((object)("[HardheimShipEquipment] Gender YAML hit: key=" + text + " gender=" + value));
			return result;
		}
		Log.LogWarning((object)("[HardheimShipEquipment] Gender YAML miss: key=" + text + ". Default=male"));
		return false;
	}

	internal void ReloadGenderYamlNow()
	{
		LoadGenderYaml();
	}

	internal void RegisterLocalPlayerGender(Player player)
	{
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Expected O, but got Unknown
		if (_localPlayerRegistered)
		{
			return;
		}
		if ((Object)(object)player == (Object)null)
		{
			Log.LogInfo((object)"[HardheimShipEquipment] RegisterLocalPlayerGender: player == null");
			return;
		}
		if (_genderById.Count == 0)
		{
			LoadGenderYaml();
		}
		string text = ResolveLocalPlayerIdentityKey(player);
		Log.LogInfo((object)("[HardheimShipEquipment] RegisterLocalPlayerGender: resolved key = " + text));
		if (string.IsNullOrWhiteSpace(text))
		{
			Log.LogWarning((object)"[HardheimShipEquipment] RegisterLocalPlayerGender: empty key");
			return;
		}
		if (!TryDetectGender(player, out var gender))
		{
			Log.LogInfo((object)"[HardheimShipEquipment] RegisterLocalPlayerGender: gender not ready yet, retry later");
			return;
		}
		string value;
		bool flag = !_genderById.TryGetValue(text, out value) || !string.Equals(value, gender, StringComparison.OrdinalIgnoreCase);
		_genderById[text] = gender;
		if (flag)
		{
			SaveGenderYaml();
			Log.LogInfo((object)("[HardheimShipEquipment] LOCAL gender saved/updated: key=" + text + " gender=" + gender));
		}
		else
		{
			Log.LogInfo((object)("[HardheimShipEquipment] LOCAL gender unchanged: key=" + text + " gender=" + gender));
		}
		if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
		{
			Log.LogInfo((object)"[HardheimShipEquipment] RegisterLocalPlayerGender running on server, no RPC needed");
		}
		else if (ZRoutedRpc.instance != null)
		{
			ZPackage val = new ZPackage();
			val.Write(text);
			val.Write(gender);
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "HH_RegisterGender", new object[1] { val });
			Log.LogInfo((object)("[HardheimShipEquipment] CLIENT gender sent to server: key=" + text + " gender=" + gender));
		}
		else
		{
			Log.LogWarning((object)"[HardheimShipEquipment] CLIENT could not send gender to server, ZRoutedRpc.instance == null");
		}
		_localPlayerRegistered = true;
	}

	private void RPC_RegisterGender(long sender, ZPackage pkg)
	{
		try
		{
			if (pkg == null)
			{
				return;
			}
			string text = pkg.ReadString();
			string text2 = pkg.ReadString();
			if (!string.IsNullOrWhiteSpace(text) && (!(text2 != "male") || !(text2 != "female")))
			{
				if (_genderById.Count == 0)
				{
					LoadGenderYaml();
				}
				string value;
				bool flag = !_genderById.TryGetValue(text, out value) || !string.Equals(value, text2, StringComparison.OrdinalIgnoreCase);
				_genderById[text] = text2;
				if (flag)
				{
					SaveGenderYaml();
					Log.LogInfo((object)string.Format("[{0}] SERVER gender saved/updated: key={1} gender={2} sender={3}", "HardheimShipEquipment", text, text2, sender));
				}
				else
				{
					Log.LogInfo((object)("[HardheimShipEquipment] SERVER gender unchanged: key=" + text + " gender=" + text2));
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] RPC_RegisterGender error: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void RPC_SyncGender(long sender, ZPackage pkg)
	{
		try
		{
			if (pkg == null)
			{
				return;
			}
			string text = pkg.ReadString();
			string text2 = pkg.ReadString();
			if (!string.IsNullOrWhiteSpace(text) && (!(text2 != "male") || !(text2 != "female")))
			{
				if (_genderById.Count == 0)
				{
					LoadGenderYaml();
				}
				_genderById[text] = text2;
				SaveGenderYaml();
				Log.LogInfo((object)string.Format("[{0}] CLIENT gender synced: key={1} gender={2} sender={3}", "HardheimShipEquipment", text, text2, sender));
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] RPC_SyncGender error: {1}", "HardheimShipEquipment", arg));
		}
	}

	private bool TryDetectGender(Player player, out string gender)
	{
		gender = null;
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		try
		{
			if (TryReadModelIndex(player, out var modelIndex))
			{
				Log.LogInfo((object)string.Format("[{0}] TryDetectGender: modelIndex={1}", "HardheimShipEquipment", modelIndex));
				switch (modelIndex)
				{
				case 0:
					gender = "male";
					return true;
				case 1:
					gender = "female";
					return true;
				}
			}
			Animator val = ((Component)player).GetComponentInChildren<Animator>(true) ?? ((Component)player).GetComponent<Animator>();
			if ((Object)(object)val != (Object)null && (Object)(object)val.avatar != (Object)null)
			{
				string text = ((Object)val.avatar).name ?? "";
				string text2 = text.ToLowerInvariant();
				Log.LogInfo((object)("[HardheimShipEquipment] TryDetectGender: avatar=" + text));
				if (text2.Contains("female"))
				{
					gender = "female";
					return true;
				}
				if (text2.Contains("male"))
				{
					gender = "male";
					return true;
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogWarning((object)string.Format("[{0}] TryDetectGender error: {1}", "HardheimShipEquipment", arg));
		}
		return false;
	}

	private bool TryReadModelIndex(Player player, out int modelIndex)
	{
		modelIndex = -1;
		BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
		try
		{
			if (TryReadIntMember(player, ((object)player).GetType(), bindingFlags, out modelIndex, "m_modelIndex", "modelIndex", "m_playerModel", "playerModel"))
			{
				return true;
			}
			VisEquipment val = ((Component)player).GetComponentInChildren<VisEquipment>(true) ?? ((Component)player).GetComponent<VisEquipment>();
			if ((Object)(object)val != (Object)null && TryReadIntMember(val, ((object)val).GetType(), bindingFlags, out modelIndex, "m_modelIndex", "modelIndex", "m_currentModel", "m_model", "m_modelType"))
			{
				return true;
			}
			if ((Object)(object)player == (Object)(object)Player.m_localPlayer && (Object)(object)Game.instance != (Object)null)
			{
				PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
				if (playerProfile != null)
				{
					MethodInfo method = ((object)playerProfile).GetType().GetMethod("GetPlayerModel", bindingFlags, null, Type.EmptyTypes, null);
					if (method != null && method.Invoke(playerProfile, null) is int num)
					{
						modelIndex = num;
						return true;
					}
					if (TryReadIntMember(playerProfile, ((object)playerProfile).GetType(), bindingFlags, out modelIndex, "m_playerModel", "m_modelIndex", "modelIndex"))
					{
						return true;
					}
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogWarning((object)string.Format("[{0}] TryReadModelIndex error: {1}", "HardheimShipEquipment", arg));
		}
		return false;
	}

	private bool TryReadIntMember(object instance, Type type, BindingFlags flags, out int value, params string[] memberNames)
	{
		value = -1;
		foreach (string text in memberNames)
		{
			FieldInfo field = type.GetField(text, flags);
			if (field != null && field.FieldType == typeof(int) && field.GetValue(instance) is int num)
			{
				value = num;
				Log.LogInfo((object)string.Format("[{0}] TryReadIntMember field {1}.{2} = {3}", "HardheimShipEquipment", type.Name, text, value));
				return true;
			}
			PropertyInfo property = type.GetProperty(text, flags);
			if (property != null && property.PropertyType == typeof(int) && property.CanRead && property.GetIndexParameters().Length == 0 && property.GetValue(instance, null) is int num2)
			{
				value = num2;
				Log.LogInfo((object)string.Format("[{0}] TryReadIntMember property {1}.{2} = {3}", "HardheimShipEquipment", type.Name, text, value));
				return true;
			}
		}
		return false;
	}

	private void LoadIconBundle()
	{
		try
		{
			string text = Path.Combine(Paths.ConfigPath, "HardheimShipEquipment", "plugins", "hardheim_icons");
			if (!File.Exists(text))
			{
				Log.LogWarning((object)("[HardheimShipEquipment] Ikon bundle nem található: " + text));
				return;
			}
			_iconBundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)_iconBundle == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem sikerült betölteni az ikon bundle-t.");
				return;
			}
			_drumRingIcon = _iconBundle.LoadAsset<Sprite>("drum_ring");
			if ((Object)(object)_drumRingIcon == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem található sprite: drum_ring");
				return;
			}
			_drumIcon = _iconBundle.LoadAsset<Sprite>("drum_icon");
			if ((Object)(object)_drumIcon == (Object)null)
			{
				Log.LogWarning((object)"[HardheimShipEquipment] Nem található sprite: drum_icon");
			}
			Log.LogInfo((object)"[HardheimShipEquipment] Drum icon betöltve!");
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Bundle load error: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void LoadDrumBundle()
	{
		try
		{
			string text = Path.Combine(Paths.ConfigPath, "HardheimShipEquipment", "plugins", "hardheimship");
			if (!File.Exists(text))
			{
				Log.LogWarning((object)("[HardheimShipEquipment] Drum bundle nem található: " + text));
				return;
			}
			_drumBundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)_drumBundle == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem sikerült betölteni a drum bundle-t.");
				return;
			}
			_drumPrefab = _drumBundle.LoadAsset<GameObject>("HH_ShipDrumVisual");
			if ((Object)(object)_drumPrefab == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] HH_ShipDrumVisual prefab nincs a bundle-ben.");
			}
			else
			{
				Log.LogInfo((object)"[HardheimShipEquipment] Drum prefab betöltve!");
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Drum bundle load error: {1}", "HardheimShipEquipment", arg));
		}
	}

	private static void InstallUnityAudioSpamFilter()
	{
		if (!_unityAudioSpamFilterInstalled)
		{
			_originalUnityLogHandler = Debug.unityLogger.logHandler;
			Debug.unityLogger.logHandler = (ILogHandler)(object)new UnityAudioSpamFilterLogHandler(_originalUnityLogHandler);
			_unityAudioSpamFilterInstalled = true;
		}
	}

	private void Awake()
	{
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Expected O, but got Unknown
		InstallUnityAudioSpamFilter();
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		EnsureModFolders();
		LoadIconBundle();
		LoadDrumBundle();
		((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
		BindConfigs();
		((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
		((BaseUnityPlugin)this).Config.Save();
		SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized;
		SynchronizationManager.OnAdminStatusChanged += OnAdminStatusChanged;
		if (!CfgEnableMod.Value)
		{
			Log.LogInfo((object)"[HardheimShipEquipment] Mod letiltva konfiguráció alapján.");
			return;
		}
		_harmony = new Harmony("h4nz0.hardheimshipequipment");
		_harmony.PatchAll();
		((Component)this).gameObject.AddComponent<ShipSongBuffOverlay>();
		if (ZRoutedRpc.instance != null)
		{
			EnsureGenderRpcRegistered();
		}
		else
		{
			Log.LogWarning((object)"[HardheimShipEquipment] ZRoutedRpc.instance == null az Awake-ben");
		}
		PrefabManager.OnVanillaPrefabsAvailable += RegisterPiece;
		Log.LogInfo((object)"[HardheimShipEquipment] Mod betöltve.");
		LogDebugConfigSnapshot("Awake");
	}

	private void EnsureGenderRpcRegistered()
	{
		if (!_genderRpcRegistered && ZRoutedRpc.instance != null)
		{
			ZRoutedRpc.instance.Register<ZPackage>("HH_RegisterGender", (Action<long, ZPackage>)RPC_RegisterGender);
			ZRoutedRpc.instance.Register<ZPackage>("HH_SyncGender", (Action<long, ZPackage>)RPC_SyncGender);
			_genderRpcRegistered = true;
			Log.LogInfo((object)"[HardheimShipEquipment] Gender RPC registered: HH_RegisterGender, HH_SyncGender");
		}
	}

	private void Update()
	{
		try
		{
			if (CfgEnableMod.Value)
			{
				EnsureGenderRpcRegistered();
				if (!_localPlayerRegistered && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					RegisterLocalPlayerGender(Player.m_localPlayer);
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Update RegisterLocalPlayerGender error: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= RegisterPiece;
		SynchronizationManager.OnConfigurationSynchronized -= OnConfigurationSynchronized;
		SynchronizationManager.OnAdminStatusChanged -= OnAdminStatusChanged;
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		PendingShipPlacement.Clear();
		LastShipRaycastHit.Clear();
		if (_unityAudioSpamFilterInstalled && _originalUnityLogHandler != null)
		{
			Debug.unityLogger.logHandler = _originalUnityLogHandler;
			_originalUnityLogHandler = null;
			_unityAudioSpamFilterInstalled = false;
		}
	}

	private void BindConfigs()
	{
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
		CfgEnableMod = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "1 - General", "Enabled", true, "Mod engedélyezése.", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgDebug = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "9 - Debug", "EnableDebug", false, "Debug logok engedélyezése.", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgAttachSearchRadius = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "1 - General", "AttachSearchRadius", 12f, "Mekkora sugarú körben keressen hajót a lerakott HH_ építmény.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgReattachInterval = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "1 - General", "ReattachInterval", 0.5f, "Milyen gyakran próbálja újrakeresni a hajó referenciát a lerakott HH_ építmény.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgDestroyIfNotOnShip = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "1 - General", "DestroyIfNotOnShip", true, "Ha lerakás után nem talál hajót, törölje magát.", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgNoRoofWear = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "1 - General", "NoRoofWear", true, "Ne sérüljön tető hiánya miatt.", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgPieceTable = ConfigFileExtensions.BindConfigInOrder<string>(((BaseUnityPlugin)this).Config, "2 - Build", "PieceTable", "_HammerPieceTable", "Melyik build menübe kerüljön a hajófáklya.", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgCategory = ConfigFileExtensions.BindConfigInOrder<string>(((BaseUnityPlugin)this).Config, "2 - Build", "Category", "Hajófelszerelés", "Kategória neve a kalapácsban. Példa: Hajófelszerelés", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgWoodCost = ConfigFileExtensions.BindConfigInOrder<int>(((BaseUnityPlugin)this).Config, "2 - Build", "WoodCost", 2, "Fa költség.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgResinCost = ConfigFileExtensions.BindConfigInOrder<int>(((BaseUnityPlugin)this).Config, "2 - Build", "ResinCost", 2, "Gyanta költség.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgGhostSnapSearchRadius = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "3 - Placement", "GhostSnapSearchRadius", 4f, "Mekkora sugarú körben számítson hajónak a HH_ lerakási pont környezete.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 12f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgMarkerOffsetY = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "3 - Placement", "MarkerOffsetY", 0.54f, "A sárga placement markerhez képesti függőleges offset a HH_ preview ghost számára.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgMarkerOffsetStep = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "3 - Placement", "MarkerOffsetStep", 0.01f, "Mennyit változzon a MarkerOffsetY a hotkeyek használatakor.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.5f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgMarkerOffsetUpKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("8 - Hotkeys", "MarkerOffsetUpKey", new KeyboardShortcut((KeyCode)280, Array.Empty<KeyCode>()), "MarkerOffsetY növelése.");
		CfgMarkerOffsetDownKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("8 - Hotkeys", "MarkerOffsetDownKey", new KeyboardShortcut((KeyCode)281, Array.Empty<KeyCode>()), "MarkerOffsetY csökkentése.");
		CfgMarkerOffsetLogKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("8 - Hotkeys", "MarkerOffsetLogKey", new KeyboardShortcut((KeyCode)279, Array.Empty<KeyCode>()), "Aktuális marker/ghost offset kilogolása és mentése.");
		CfgEnableMigrationFileLog = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "9 - Debug", "EnableMigrationFileLog", true, "Mentse a migration / restore / bind eseményeket napi txt fájlba.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgKeepMigrationLogs = ConfigFileExtensions.BindConfigInOrder<int>(((BaseUnityPlugin)this).Config, "9 - Debug", "KeepMigrationLogs", 5, "Hány napi migration txt log maradjon meg a mappában.", false, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgMigrationPlayerProximityRadius = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "9 - Debug", "MigrationPlayerProximityRadius", 64f, "Csak akkor próbáljon migrálni egy HH_ itemet, ha játékos van a közelében.", false, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgFinalPlacementOffsetY = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "3 - Placement", "FinalPlacementOffsetY", 0f, "A lerakott HH_ építmény végleges függőleges offsetje a marker/hit ponthoz képest.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		CfgDumpHHStateKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("9 - Debug", "DumpHHStateKey", new KeyboardShortcut((KeyCode)278, Array.Empty<KeyCode>()), "Kilistázza az összes HH_ item állapotát (migration debug).");
	}

	private void OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs args)
	{
		string arg = (args.InitialSynchronization ? "Initial" : "Runtime");
		Log.LogInfo((object)string.Format("[{0}] Konfig szinkron esemény: {1}. PlayerIsAdmin={2}", "HardheimShipEquipment", arg, SynchronizationManager.Instance.PlayerIsAdmin));
		LogDebugConfigSnapshot("OnConfigurationSynchronized");
	}

	private void OnAdminStatusChanged()
	{
		Log.LogInfo((object)string.Format("[{0}] Admin státusz szinkron frissült. PlayerIsAdmin={1}", "HardheimShipEquipment", SynchronizationManager.Instance.PlayerIsAdmin));
	}

	private void RegisterPiece()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Expected O, but got Unknown
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Expected O, but got Unknown
		//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Expected O, but got Unknown
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Expected O, but got Unknown
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Expected O, but got Unknown
		//IL_0336: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Expected O, but got Unknown
		//IL_0592: Unknown result type (might be due to invalid IL or missing references)
		//IL_0599: Expected O, but got Unknown
		//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f3: Expected O, but got Unknown
		//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0603: Expected O, but got Unknown
		//IL_060d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0613: Expected O, but got Unknown
		//IL_061d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0623: Expected O, but got Unknown
		//IL_0639: Unknown result type (might be due to invalid IL or missing references)
		//IL_0640: Expected O, but got Unknown
		//IL_0822: Unknown result type (might be due to invalid IL or missing references)
		if (_pieceRegistered)
		{
			return;
		}
		try
		{
			PieceConfig val = new PieceConfig();
			val.Name = "Hajófáklya";
			val.Description = "Csak hajóra építhető fáklya.";
			val.PieceTable = CfgPieceTable.Value;
			val.Category = "Hajófelszerelés";
			val.AllowedInDungeons = true;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("RoundLog", CfgWoodCost.Value, 0, true),
				new RequirementConfig("Resin", CfgResinCost.Value, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece("HH_ShipTorch", "piece_groundtorch_wood", val2);
			Piece piece = val3.Piece;
			if ((Object)(object)piece == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem sikerült létrehozni a custom piece-t: HH_ShipTorch");
				return;
			}
			DebugHoverSources(((Component)piece).gameObject, "HH_ShipTorch");
			piece.m_name = "Hajófáklya";
			piece.m_description = "Csak hajóra építhető fáklya.";
			piece.m_canBeRemoved = true;
			piece.m_groundPiece = false;
			piece.m_groundOnly = false;
			piece.m_cultivatedGroundOnly = false;
			piece.m_waterPiece = true;
			piece.m_noInWater = false;
			piece.m_notOnWood = false;
			piece.m_notOnTiltingSurface = false;
			piece.m_inCeilingOnly = false;
			piece.m_notOnFloor = false;
			piece.m_mustConnectTo = null;
			piece.m_mustBeAboveConnected = false;
			piece.m_clipGround = false;
			piece.m_clipEverything = false;
			piece.m_craftingStation = null;
			piece.m_onlyInTeleportArea = false;
			piece.m_allowedInDungeons = true;
			WearNTear component = ((Component)piece).GetComponent<WearNTear>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Rigidbody component2 = ((Component)piece).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.isKinematic = true;
				component2.useGravity = false;
			}
			Collider[] componentsInChildren = ((Component)piece).GetComponentsInChildren<Collider>(true);
			Collider[] array = componentsInChildren;
			foreach (Collider val4 in array)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					val4.isTrigger = true;
				}
			}
			((Component)piece).gameObject.layer = LayerMask.NameToLayer("piece_nonsolid");
			if ((Object)(object)((Component)piece).GetComponent<ShipTorchAttachment>() == (Object)null)
			{
				((Component)piece).gameObject.AddComponent<ShipTorchAttachment>();
			}
			StripVanillaTorchHoverSources(((Component)piece).gameObject);
			ShipTorchHover shipTorchHover = ((Component)piece).gameObject.GetComponent<ShipTorchHover>();
			if ((Object)(object)shipTorchHover == (Object)null)
			{
				shipTorchHover = ((Component)piece).gameObject.AddComponent<ShipTorchHover>();
			}
			shipTorchHover.HoverName = "Hajófáklya";
			shipTorchHover.HoverText = "Hajófáklya";
			PieceManager.Instance.AddPiece(val3);
			LogDebug("[HardheimShipEquipment] Hajófáklya piece regisztrálva: HH_ShipTorch");
			val = new PieceConfig();
			val.Name = "Vas hajófáklya";
			val.Description = "Erősebb fényt adó hajófáklya. Tartósabb és nagyobb fényt biztosít.";
			val.PieceTable = CfgPieceTable.Value;
			val.Category = "Hajófelszerelés";
			val.AllowedInDungeons = true;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("Iron", 2, 0, true),
				new RequirementConfig("RoundLog", 1, 0, true),
				new RequirementConfig("Resin", 2, 0, true)
			};
			PieceConfig val5 = val;
			CustomPiece val6 = new CustomPiece("HH_ShipTorchIron", "piece_groundtorch", val5);
			Piece piece2 = val6.Piece;
			piece2.m_name = "Vas hajófáklya";
			piece2.m_description = "Erősebb fényt adó hajófáklya. Tartósabb és nagyobb fényt biztosít.";
			if ((Object)(object)piece2 == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem sikerült létrehozni a custom piece-t: HH_ShipTorchIron");
				return;
			}
			DebugHoverSources(((Component)piece2).gameObject, "HH_ShipTorchIron");
			piece2.m_canBeRemoved = true;
			piece2.m_groundPiece = false;
			piece2.m_groundOnly = false;
			piece2.m_cultivatedGroundOnly = false;
			piece2.m_waterPiece = true;
			piece2.m_noInWater = false;
			piece2.m_notOnWood = false;
			piece2.m_notOnTiltingSurface = false;
			piece2.m_inCeilingOnly = false;
			piece2.m_notOnFloor = false;
			piece2.m_mustConnectTo = null;
			piece2.m_mustBeAboveConnected = false;
			piece2.m_clipGround = false;
			piece2.m_clipEverything = false;
			piece2.m_craftingStation = null;
			piece2.m_onlyInTeleportArea = false;
			piece2.m_allowedInDungeons = true;
			WearNTear component3 = ((Component)piece2).GetComponent<WearNTear>();
			if ((Object)(object)component3 != (Object)null)
			{
				Object.Destroy((Object)(object)component3);
			}
			Rigidbody component4 = ((Component)piece2).GetComponent<Rigidbody>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.isKinematic = true;
				component4.useGravity = false;
			}
			Collider[] componentsInChildren2 = ((Component)piece2).GetComponentsInChildren<Collider>(true);
			Collider[] array2 = componentsInChildren2;
			foreach (Collider val7 in array2)
			{
				if ((Object)(object)val7 != (Object)null)
				{
					val7.isTrigger = true;
				}
			}
			((Component)piece2).gameObject.layer = LayerMask.NameToLayer("piece_nonsolid");
			Light componentInChildren = ((Component)piece2).GetComponentInChildren<Light>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.range *= 1.8f;
				componentInChildren.intensity *= 1.5f;
			}
			if ((Object)(object)((Component)piece2).gameObject.GetComponent<ShipTorchAttachment>() == (Object)null)
			{
				((Component)piece2).gameObject.AddComponent<ShipTorchAttachment>();
			}
			StripVanillaTorchHoverSources(((Component)piece2).gameObject);
			ShipTorchHover shipTorchHover2 = ((Component)piece2).gameObject.GetComponent<ShipTorchHover>();
			if ((Object)(object)shipTorchHover2 == (Object)null)
			{
				shipTorchHover2 = ((Component)piece2).gameObject.AddComponent<ShipTorchHover>();
			}
			shipTorchHover2.HoverName = "Vas hajófáklya";
			shipTorchHover2.HoverText = "Vas hajófáklya";
			PieceManager.Instance.AddPiece(val6);
			LogDebug("[HardheimShipEquipment] Vas hajófáklya piece regisztrálva: HH_ShipTorchIron");
			val = new PieceConfig();
			val.Name = "Ködtörő hajófáklya";
			val.Description = "Ködtörő hajófáklya. Tündér energiával működik, és áttöri a ködvidék sűrű ködét.";
			val.PieceTable = CfgPieceTable.Value;
			val.Category = "Hajófelszerelés";
			val.AllowedInDungeons = true;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[4]
			{
				new RequirementConfig("BlackMetal", 4, 0, true),
				new RequirementConfig("Silver", 2, 0, true),
				new RequirementConfig("FineWood", 5, 0, true),
				new RequirementConfig("Wisp", 1, 0, true)
			};
			PieceConfig val8 = val;
			CustomPiece val9 = new CustomPiece("HH_ShipTorchMist", "piece_groundtorch_blue", val8);
			DebugPrefabComponents("piece_groundtorch_blue");
			Piece piece3 = val9.Piece;
			piece3.m_name = "Ködtörő hajófáklya";
			piece3.m_description = "Ködtörő hajófáklya. Tündér energiával működik, és áttöri a ködvidék sűrű ködét.";
			if ((Object)(object)piece3 == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem sikerült létrehozni a custom piece-t: HH_ShipTorchMist");
				return;
			}
			DebugHoverSources(((Component)piece3).gameObject, "HH_ShipTorchMist");
			piece3.m_canBeRemoved = true;
			piece3.m_groundPiece = false;
			piece3.m_groundOnly = false;
			piece3.m_cultivatedGroundOnly = false;
			piece3.m_waterPiece = true;
			piece3.m_noInWater = false;
			piece3.m_notOnWood = false;
			piece3.m_notOnTiltingSurface = false;
			piece3.m_inCeilingOnly = false;
			piece3.m_notOnFloor = false;
			piece3.m_mustConnectTo = null;
			piece3.m_mustBeAboveConnected = false;
			piece3.m_clipGround = false;
			piece3.m_clipEverything = false;
			piece3.m_craftingStation = null;
			piece3.m_onlyInTeleportArea = false;
			piece3.m_allowedInDungeons = true;
			WearNTear component5 = ((Component)piece3).GetComponent<WearNTear>();
			if ((Object)(object)component5 != (Object)null)
			{
				Object.Destroy((Object)(object)component5);
			}
			Rigidbody component6 = ((Component)piece3).GetComponent<Rigidbody>();
			if ((Object)(object)component6 != (Object)null)
			{
				component6.isKinematic = true;
				component6.useGravity = false;
			}
			Collider[] componentsInChildren3 = ((Component)piece3).GetComponentsInChildren<Collider>(true);
			Collider[] array3 = componentsInChildren3;
			foreach (Collider val10 in array3)
			{
				if ((Object)(object)val10 != (Object)null)
				{
					val10.isTrigger = true;
				}
			}
			((Component)piece3).gameObject.layer = LayerMask.NameToLayer("piece_nonsolid");
			Light componentInChildren2 = ((Component)piece3).GetComponentInChildren<Light>();
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				componentInChildren2.range *= 1.8f;
				componentInChildren2.intensity *= 1.5f;
				componentInChildren2.color = new Color(0.7f, 0.85f, 1f);
			}
			if ((Object)(object)((Component)piece3).gameObject.GetComponent<ShipTorchAttachment>() == (Object)null)
			{
				((Component)piece3).gameObject.AddComponent<ShipTorchAttachment>();
			}
			StripVanillaTorchHoverSources(((Component)piece3).gameObject);
			ShipTorchHover shipTorchHover3 = ((Component)piece3).gameObject.GetComponent<ShipTorchHover>();
			if ((Object)(object)shipTorchHover3 == (Object)null)
			{
				shipTorchHover3 = ((Component)piece3).gameObject.AddComponent<ShipTorchHover>();
			}
			shipTorchHover3.HoverName = "Ködtörő hajófáklya";
			shipTorchHover3.HoverText = "Ködtörő hajófáklya";
			PieceManager.Instance.AddPiece(val9);
			LogDebug("[HardheimShipEquipment] Ködtörő hajófáklya piece regisztrálva: HH_ShipTorchMist");
			RegisterDrumItem();
			RegisterDrumPiece();
			if (CfgDebug != null && CfgDebug.Value)
			{
				DebugObjectDBItemPrefabs("Demister");
				DebugObjectDBItemPrefabs("Wisp");
			}
			_pieceRegistered = true;
			LogDebugConfigSnapshot("RegisterPiece");
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Hiba a piece regisztráció közben: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void RegisterDrumItem()
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Expected O, but got Unknown
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Expected O, but got Unknown
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Expected O, but got Unknown
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Expected O, but got Unknown
		try
		{
			ItemConfig val = new ItemConfig();
			val.Name = "Dobgyűrű";
			val.Description = "Átalakított hordógyűrűk hajódob készítéséhez.";
			CustomItem val2 = new CustomItem("HH_DrumHoops", "BarrelRings", val);
			ItemDrop itemDrop = val2.ItemDrop;
			if ((Object)(object)itemDrop == (Object)null || itemDrop.m_itemData == null || itemDrop.m_itemData.m_shared == null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem sikerült létrehozni a custom itemet: HH_DrumHoops");
				return;
			}
			itemDrop.m_itemData.m_shared.m_name = "Dobgyűrű";
			itemDrop.m_itemData.m_shared.m_description = "Átalakított hordógyűrűk hajódob készítéséhez.";
			itemDrop.m_itemData.m_shared.m_maxStackSize = 50;
			itemDrop.m_itemData.m_shared.m_weight = 1f;
			itemDrop.m_itemData.m_shared.m_value = 0;
			if ((Object)(object)_drumRingIcon != (Object)null)
			{
				itemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { _drumRingIcon };
			}
			ItemManager.Instance.AddItem(val2);
			RecipeConfig val3 = new RecipeConfig();
			val3.Name = "Recipe_HH_DrumHoops";
			val3.Item = "HH_DrumHoops";
			val3.Amount = 1;
			val3.CraftingStation = "forge";
			val3.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("BarrelRings", 1, 0, true),
				new RequirementConfig("Bronze", 2, 0, true)
			};
			ItemManager.Instance.AddRecipe(new CustomRecipe(val3));
			LogDebug("[HardheimShipEquipment] Dobgyűrű item + recipe regisztrálva: HH_DrumHoops");
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Hiba a dobgyűrű item regisztráció közben: {1}", "HardheimShipEquipment", arg));
		}
	}

	private void RegisterDrumPiece()
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Expected O, but got Unknown
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Expected O, but got Unknown
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Expected O, but got Unknown
		//IL_033e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Expected O, but got Unknown
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_053a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0556: Unknown result type (might be due to invalid IL or missing references)
		//IL_05df: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			PieceConfig val = new PieceConfig();
			val.Name = "Hajódob";
			val.Description = "Hajóra építhető dob. A dobgyűrű birtokában készíthető el.";
			val.PieceTable = CfgPieceTable.Value;
			val.Category = "Hajófelszerelés";
			val.AllowedInDungeons = true;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("HH_DrumHoops", 1, 0, true),
				new RequirementConfig("DeerHide", 2, 0, true),
				new RequirementConfig("Wood", 4, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece("HH_ShipDrum", "piece_chest_barrel", val2);
			Piece piece = val3.Piece;
			if ((Object)(object)piece == (Object)null)
			{
				Log.LogError((object)"[HardheimShipEquipment] Nem sikerült létrehozni a custom piece-t: HH_ShipDrum");
				return;
			}
			piece.m_name = "Dob";
			piece.m_description = "Hajóra építhető dob. A dobgyűrű birtokában készíthető el.";
			if ((Object)(object)_drumIcon != (Object)null)
			{
				piece.m_icon = _drumIcon;
			}
			piece.m_canBeRemoved = true;
			piece.m_groundPiece = false;
			piece.m_groundOnly = false;
			piece.m_cultivatedGroundOnly = false;
			piece.m_waterPiece = true;
			piece.m_noInWater = false;
			piece.m_notOnWood = false;
			piece.m_notOnTiltingSurface = false;
			piece.m_inCeilingOnly = false;
			piece.m_notOnFloor = false;
			piece.m_mustConnectTo = null;
			piece.m_mustBeAboveConnected = false;
			piece.m_clipGround = false;
			piece.m_clipEverything = false;
			piece.m_craftingStation = null;
			piece.m_onlyInTeleportArea = false;
			piece.m_allowedInDungeons = true;
			GameObject gameObject = ((Component)piece).gameObject;
			Container component = gameObject.GetComponent<Container>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			WearNTear component2 = gameObject.GetComponent<WearNTear>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.Destroy((Object)(object)component2);
			}
			Rigidbody component3 = gameObject.GetComponent<Rigidbody>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.isKinematic = true;
				component3.useGravity = false;
			}
			Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(true);
			Collider[] array = componentsInChildren;
			foreach (Collider val4 in array)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					val4.isTrigger = true;
				}
			}
			gameObject.layer = LayerMask.NameToLayer("piece_nonsolid");
			if ((Object)(object)_drumIcon != (Object)null)
			{
				piece.m_icon = _drumIcon;
			}
			if ((Object)(object)_drumPrefab != (Object)null)
			{
				Renderer[] componentsInChildren2 = gameObject.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val5 in componentsInChildren2)
				{
					if ((Object)(object)val5 != (Object)null)
					{
						val5.enabled = false;
					}
				}
				List<GameObject> list = new List<GameObject>();
				foreach (Transform item in gameObject.transform)
				{
					Transform val6 = item;
					list.Add(((Component)val6).gameObject);
				}
				foreach (GameObject item2 in list)
				{
					Object.Destroy((Object)(object)item2);
				}
				GameObject val7 = new GameObject("HH_DrumVisualRoot");
				val7.transform.SetParent(gameObject.transform, false);
				val7.transform.localPosition = new Vector3(0f, -0.8f, 0f);
				val7.transform.localRotation = Quaternion.identity;
				val7.transform.localScale = new Vector3(1.2f, 1.2f, 1.2f);
				GameObject val8 = Object.Instantiate<GameObject>(_drumPrefab, val7.transform, false);
				((Object)val8).name = "HH_DrumVisual";
				val8.transform.localPosition = Vector3.zero;
				val8.transform.localRotation = Quaternion.identity;
				val8.transform.localScale = Vector3.one;
				Piece[] componentsInChildren3 = val8.GetComponentsInChildren<Piece>(true);
				foreach (Piece val9 in componentsInChildren3)
				{
					Object.Destroy((Object)(object)val9);
				}
				WearNTear[] componentsInChildren4 = val8.GetComponentsInChildren<WearNTear>(true);
				foreach (WearNTear val10 in componentsInChildren4)
				{
					Object.Destroy((Object)(object)val10);
				}
				ZNetView[] componentsInChildren5 = val8.GetComponentsInChildren<ZNetView>(true);
				foreach (ZNetView val11 in componentsInChildren5)
				{
					Object.Destroy((Object)(object)val11);
				}
				Renderer[] componentsInChildren6 = val8.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val12 in componentsInChildren6)
				{
					if ((Object)(object)val12 != (Object)null)
					{
						val12.enabled = true;
						val12.forceRenderingOff = false;
					}
				}
				Collider[] componentsInChildren7 = val8.GetComponentsInChildren<Collider>(true);
				foreach (Collider val13 in componentsInChildren7)
				{
					Object.Destroy((Object)(object)val13);
				}
				BoxCollider val14 = gameObject.GetComponent<BoxCollider>();
				if ((Object)(object)val14 == (Object)null)
				{
					val14 = gameObject.AddComponent<BoxCollider>();
				}
				val14.center = new Vector3(0f, 0.1f, 0f);
				val14.size = new Vector3(0.85f, 0.42f, 0.85f);
				((Collider)val14).isTrigger = true;
				Transform[] componentsInChildren8 = val7.GetComponentsInChildren<Transform>(true);
				foreach (Transform val15 in componentsInChildren8)
				{
					((Component)val15).gameObject.layer = LayerMask.NameToLayer("piece");
				}
				int num3 = val7.GetComponentsInChildren<Renderer>(true).Length;
				Log.LogInfo((object)string.Format("[{0}] Drum visual berakva. renderers={1}, localPos={2}, localScale={3}", "HardheimShipEquipment", num3, val7.transform.localPosition, val7.transform.localScale));
			}
			else
			{
				Log.LogWarning((object)"[HardheimShipEquipment] Drum prefab nincs betöltve, marad a vanilla barrel vizuál.");
			}
			if ((Object)(object)gameObject.GetComponent<ShipTorchAttachment>() == (Object)null)
			{
				gameObject.AddComponent<ShipTorchAttachment>();
			}
			if ((Object)(object)gameObject.GetComponent<ShipDrumInteraction>() == (Object)null)
			{
				gameObject.AddComponent<ShipDrumInteraction>();
			}
			PieceManager.Instance.AddPiece(val3);
			LogDebug("[HardheimShipEquipment] Hajódob piece regisztrálva: HH_ShipDrum");
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] Hiba a hajódob piece regisztráció közben: {1}", "HardheimShipEquipment", arg));
		}
	}

	internal static void LogDebug(string msg)
	{
		if (CfgDebug != null && CfgDebug.Value)
		{
			Log.LogInfo((object)msg);
		}
	}

	internal static void LogDebugConfigSnapshot(string source)
	{
		if (CfgDebug != null && CfgDebug.Value)
		{
			Log.LogInfo((object)("[HardheimShipEquipment] [" + source + "] Config snapshot => " + $"Enabled={CfgEnableMod?.Value}, " + $"AttachSearchRadius={CfgAttachSearchRadius?.Value}, " + $"ReattachInterval={CfgReattachInterval?.Value}, " + $"DestroyIfNotOnShip={CfgDestroyIfNotOnShip?.Value}, " + $"NoRoofWear={CfgNoRoofWear?.Value}, " + "PieceTable=" + CfgPieceTable?.Value + ", Category=" + CfgCategory?.Value + ", " + $"WoodCost={CfgWoodCost?.Value}, " + $"ResinCost={CfgResinCost?.Value}, " + $"GhostSnapSearchRadius={CfgGhostSnapSearchRadius?.Value}, " + $"MarkerOffsetY={CfgMarkerOffsetY?.Value}, " + $"MarkerOffsetStep={CfgMarkerOffsetStep?.Value}"));
		}
	}

	private static void DebugHoverSources(GameObject root, string tag)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Log.LogInfo((object)("[HardheimShipEquipment] [HOVER DEBUG] ===== " + tag + " ====="));
		MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
		foreach (MonoBehaviour val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null))
			{
				bool flag = val is Hoverable;
				bool flag2 = val is Interactable;
				if (flag || flag2)
				{
					Log.LogInfo((object)("[HardheimShipEquipment] [HOVER DEBUG] obj=" + ((Object)((Component)val).gameObject).name + " comp=" + ((object)val).GetType().FullName + " " + $"hoverable={flag} interactable={flag2}"));
				}
			}
		}
	}

	private static void DebugFindWispPrefabs()
	{
		if ((Object)(object)ZNetScene.instance == (Object)null)
		{
			Log.LogWarning((object)"[HardheimShipEquipment] [WISP DEBUG] ZNetScene.instance == null");
			return;
		}
		foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
		{
			if (!((Object)(object)prefab == (Object)null))
			{
				string text = ((Object)prefab).name ?? "";
				if (text.IndexOf("wisp", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					Log.LogWarning((object)("[HardheimShipEquipment] [WISP DEBUG] prefab = " + text));
				}
			}
		}
	}

	private static void DebugPrefabComponents(string prefabName)
	{
		try
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				Log.LogWarning((object)"[HardheimShipEquipment] [PREFAB DEBUG] ZNetScene.instance == null");
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				Log.LogWarning((object)("[HardheimShipEquipment] [PREFAB DEBUG] Prefab nem található: " + prefabName));
				return;
			}
			Log.LogWarning((object)("[HardheimShipEquipment] [PREFAB DEBUG] ===== " + prefabName + " ====="));
			Component[] componentsInChildren = prefab.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string transformPath = GetTransformPath(val.transform, prefab.transform);
					Log.LogWarning((object)("[HardheimShipEquipment] [PREFAB DEBUG] path=" + transformPath + " type=" + ((object)val).GetType().FullName));
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] [PREFAB DEBUG] Hiba: {1}", "HardheimShipEquipment", arg));
		}
	}

	internal static void DebugLiveObjectComponents(GameObject obj, string tag)
	{
		if (CfgDebug == null || !CfgDebug.Value)
		{
			return;
		}
		try
		{
			if ((Object)(object)obj == (Object)null)
			{
				LogDebug("[HardheimShipEquipment] [LIVE DEBUG] " + tag + ": obj == null");
				return;
			}
			LogDebug("[HardheimShipEquipment] [LIVE DEBUG] ===== " + tag + " / " + ((Object)obj).name + " =====");
			Component[] componentsInChildren = obj.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string transformPath = GetTransformPath(val.transform, obj.transform);
					LogDebug("[HardheimShipEquipment] [LIVE DEBUG] path=" + transformPath + " type=" + ((object)val).GetType().FullName);
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] [LIVE DEBUG] Hiba: {1}", "HardheimShipEquipment", arg));
		}
	}

	internal static void DebugObjectDBItemPrefabs(string containsFilter)
	{
		try
		{
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				Log.LogWarning((object)"[HardheimShipEquipment] [ITEM DEBUG] ObjectDB.instance == null");
				return;
			}
			Log.LogWarning((object)("[HardheimShipEquipment] [ITEM DEBUG] ===== filter=" + containsFilter + " ====="));
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				string text = ((Object)item).name ?? string.Empty;
				if (text.IndexOf(containsFilter, StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				Log.LogWarning((object)("[HardheimShipEquipment] [ITEM DEBUG] ITEM PREFAB = " + text));
				Component[] componentsInChildren = item.GetComponentsInChildren<Component>(true);
				foreach (Component val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null))
					{
						string transformPath = GetTransformPath(val.transform, item.transform);
						Log.LogWarning((object)("[HardheimShipEquipment] [ITEM DEBUG] path=" + transformPath + " type=" + ((object)val).GetType().FullName));
					}
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] [ITEM DEBUG] Hiba: {1}", "HardheimShipEquipment", arg));
		}
	}

	internal static void DebugZNetScenePrefabComponents(string prefabName)
	{
		try
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				Log.LogWarning((object)"[HardheimShipEquipment] [ZNET PREFAB DEBUG] ZNetScene.instance == null");
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				Log.LogWarning((object)("[HardheimShipEquipment] [ZNET PREFAB DEBUG] Prefab nem található: " + prefabName));
				return;
			}
			Log.LogWarning((object)("[HardheimShipEquipment] [ZNET PREFAB DEBUG] ===== " + prefabName + " ====="));
			Component[] componentsInChildren = prefab.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string transformPath = GetTransformPath(val.transform, prefab.transform);
					Log.LogWarning((object)("[HardheimShipEquipment] [ZNET PREFAB DEBUG] path=" + transformPath + " type=" + ((object)val).GetType().FullName));
				}
			}
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] [ZNET PREFAB DEBUG] Hiba: {1}", "HardheimShipEquipment", arg));
		}
	}

	private static string GetTransformPath(Transform current, Transform root)
	{
		if ((Object)(object)current == (Object)null)
		{
			return "<null>";
		}
		if ((Object)(object)current == (Object)(object)root)
		{
			return ((Object)current).name;
		}
		List<string> list = new List<string>();
		Transform val = current;
		while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
		{
			list.Add(((Object)val).name);
			val = val.parent;
		}
		if ((Object)(object)root != (Object)null)
		{
			list.Add(((Object)root).name);
		}
		list.Reverse();
		return string.Join("/", list);
	}

	private static void StripVanillaTorchHoverSources(GameObject root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
		foreach (MonoBehaviour val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && !(val is ShipTorchHover) && !(val is ShipTorchAttachment) && !(val is Fireplace) && (val is Hoverable || val is Interactable))
			{
				Object.Destroy((Object)(object)val);
			}
		}
	}

	private static void AttachSafeMistVisual(GameObject root)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Expected O, but got Unknown
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Transform val = root.transform.Find("HH_SafeMistVisual");
		if (!((Object)(object)val != (Object)null))
		{
			GameObject val2 = new GameObject("HH_SafeMistVisual");
			val2.transform.SetParent(root.transform, false);
			val2.transform.localPosition = new Vector3(0f, 1f, 0f);
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			val2.AddComponent<SimpleFloat>();
			GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val3).name = "HH_SafeMistOrb";
			val3.transform.SetParent(val2.transform, false);
			val3.transform.localPosition = Vector3.zero;
			val3.transform.localRotation = Quaternion.identity;
			val3.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
			Collider component = val3.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			MeshRenderer component2 = val3.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)component2).receiveShadows = false;
				Material val4 = new Material(Shader.Find("Sprites/Default"));
				val4.color = new Color(0.45f, 0.8f, 1f, 0.75f);
				((Renderer)component2).sharedMaterial = val4;
			}
			Light val5 = val2.AddComponent<Light>();
			val5.type = (LightType)2;
			val5.color = new Color(0.45f, 0.8f, 1f);
			val5.range = 8f;
			val5.intensity = 4.5f;
			val5.shadows = (LightShadows)0;
			LogDebug("[MIST VISUAL] Safe mist visual attached.");
		}
	}

	internal static void AttachDemisterEffect(GameObject root)
	{
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Expected O, but got Unknown
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Transform val = root.transform.Find("HH_DemisterBall");
			if ((Object)(object)val != (Object)null)
			{
				return;
			}
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				Log.LogWarning((object)"[HardheimShipEquipment] [DEMISTER ATTACH] ZNetScene.instance == null");
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab("demister_ball");
			if ((Object)(object)prefab == (Object)null)
			{
				Log.LogWarning((object)"[HardheimShipEquipment] [DEMISTER ATTACH] demister_ball prefab nem található");
				return;
			}
			Transform val2 = prefab.transform.Find("effects/Particle System Force Field");
			if ((Object)(object)val2 == (Object)null)
			{
				Log.LogWarning((object)"[HardheimShipEquipment] [DEMISTER ATTACH] Nem található: demister_ball/effects/Particle System Force Field");
				return;
			}
			GameObject val3 = new GameObject("HH_DemisterBall");
			val3.transform.SetParent(root.transform, false);
			val3.transform.localPosition = new Vector3(0f, 1f, 0f);
			val3.transform.localRotation = Quaternion.identity;
			val3.transform.localScale = Vector3.one;
			GameObject val4 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val3.transform, false);
			((Object)val4).name = "Particle System Force Field";
			val4.transform.localPosition = Vector3.zero;
			val4.transform.localRotation = Quaternion.identity;
			val4.transform.localScale = Vector3.one;
			ZNetView[] componentsInChildren = val4.GetComponentsInChildren<ZNetView>(true);
			foreach (ZNetView val5 in componentsInChildren)
			{
				if ((Object)(object)val5 != (Object)null)
				{
					Object.Destroy((Object)(object)val5);
				}
			}
			ZSyncTransform[] componentsInChildren2 = val4.GetComponentsInChildren<ZSyncTransform>(true);
			foreach (ZSyncTransform val6 in componentsInChildren2)
			{
				if ((Object)(object)val6 != (Object)null)
				{
					Object.Destroy((Object)(object)val6);
				}
			}
			Renderer[] componentsInChildren3 = val4.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val7 in componentsInChildren3)
			{
				if ((Object)(object)val7 != (Object)null)
				{
					val7.enabled = false;
				}
			}
			ParticleSystem[] componentsInChildren4 = val4.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val8 in componentsInChildren4)
			{
				if ((Object)(object)val8 != (Object)null)
				{
					val8.Stop(true, (ParticleSystemStopBehavior)0);
				}
			}
			AudioSource[] componentsInChildren5 = val4.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val9 in componentsInChildren5)
			{
				if ((Object)(object)val9 != (Object)null)
				{
					((Behaviour)val9).enabled = false;
				}
			}
			LogDebug("[HardheimShipEquipment] [DEMISTER ATTACH] ForceField demister attach OK");
		}
		catch (Exception arg)
		{
			Log.LogError((object)string.Format("[{0}] [DEMISTER ATTACH] Hiba: {1}", "HardheimShipEquipment", arg));
		}
	}
}
[HarmonyPatch(typeof(ZNet), "Start")]
public static class ZNet_Start_SessionLog_Patch
{
	private static void Postfix()
	{
		try
		{
			if (!((Object)(object)ZNet.instance == (Object)null))
			{
				string text = ZNet.instance.GetWorldName();
				if (string.IsNullOrWhiteSpace(text))
				{
					text = "unknown_world";
				}
				MigrationFileLogger.WriteLine("SESSION", "world_loaded world=" + text + " modVersion=1.0.0");
			}
		}
		catch (Exception ex)
		{
			HardheimShipEquipmentPlugin.LogDebug("[SESSION LOG ERROR] " + ex);
		}
	}
}
[HarmonyPatch(typeof(Fireplace), "GetHoverText")]
public static class Fireplace_GetHoverText_Hardheim_Patch
{
	private static void Postfix(Fireplace __instance, ref string __result)
	{
		if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).gameObject == (Object)null)
		{
			return;
		}
		string text = ((Object)((Component)__instance).gameObject).name ?? string.Empty;
		float num = 0f;
		float maxFuel = __instance.m_maxFuel;
		try
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null)
			{
				num = component.GetZDO().GetFloat("fuel", 0f);
			}
		}
		catch
		{
		}
		int num2 = Mathf.RoundToInt(num);
		int num3 = Mathf.RoundToInt(maxFuel);
		if (text.StartsWith("HH_ShipTorchMist", StringComparison.OrdinalIgnoreCase))
		{
			__result = "Ködtörő hajófáklya\n" + $"(Üzemanyag {num2}/{num3})\n" + "<color=yellow>[E]</color> Használ: Tündér\n[1-8] Tárgyat használ";
		}
		else if (text.StartsWith("HH_ShipTorchIron", StringComparison.OrdinalIgnoreCase))
		{
			__result = "Vas hajófáklya\n" + $"(Üzemanyag {num2}/{num3})\n" + "<color=yellow>[E]</color> Használ: Gyanta\n[1-8] Tárgyat használ";
		}
		else if (text.StartsWith("HH_ShipTorch", StringComparison.OrdinalIgnoreCase))
		{
			__result = "Hajófáklya\n" + $"(Üzemanyag {num2}/{num3})\n" + "<color=yellow>[E]</color> Használ: Gyanta\n[1-8] Tárgyat használ";
		}
	}
}
internal static class ReflectionCache
{
	internal static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

	internal static readonly FieldInfo PlacementStatusField = AccessTools.Field(typeof(Player), "m_placementStatus");

	internal static readonly FieldInfo PlacementMarkerField = AccessTools.Field(typeof(Player), "m_placementMarkerInstance");

	internal static readonly MethodInfo SetPlacementGhostValidMethod = AccessTools.Method(typeof(Player), "SetPlacementGhostValid", (Type[])null, (Type[])null);

	internal static readonly FieldInfo ZanimField = AccessTools.Field(typeof(Character), "m_zanim");

	internal static Animator GetZanim(Character c)
	{
		object? obj = ZanimField?.GetValue(c);
		return (Animator)((obj is Animator) ? obj : null);
	}

	internal static GameObject GetPlacementGhost(Player player)
	{
		object? obj = PlacementGhostField?.GetValue(player);
		return (GameObject)((obj is GameObject) ? obj : null);
	}

	internal static GameObject GetPlacementMarker(Player player)
	{
		object? obj = PlacementMarkerField?.GetValue(player);
		return (GameObject)((obj is GameObject) ? obj : null);
	}

	internal static void CallSetPlacementGhostValid(Player player, bool valid)
	{
		try
		{
			if (!((Object)(object)player == (Object)null) && !(SetPlacementGhostValidMethod == null))
			{
				SetPlacementGhostValidMethod.Invoke(player, new object[1] { valid });
			}
		}
		catch
		{
		}
	}

	internal static void SetPlacementStatusValid(Player player)
	{
		if (!((Object)(object)player == (Object)null) && !(PlacementStatusField == null))
		{
			object value = Enum.ToObject(PlacementStatusField.FieldType, 0);
			PlacementStatusField.SetValue(player, value);
		}
	}
}
internal static class PendingShipPlacement
{
	internal struct Snapshot
	{
		public bool IsValid;

		public Vector3 WorldPosition;

		public Quaternion WorldRotation;

		public ZDOID ShipId;

		public float TimeStamp;
	}

	private static Snapshot _last;

	internal static void Set(Vector3 worldPosition, Quaternion worldRotation, Ship ship)
	{
		//IL_0050: 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_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: 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)
		if (!((Object)(object)ship == (Object)null))
		{
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && component.GetZDO() != null)
			{
				Snapshot last = default(Snapshot);
				last.IsValid = true;
				last.WorldPosition = worldPosition;
				last.WorldRotation = worldRotation;
				last.ShipId = component.GetZDO().m_uid;
				last.TimeStamp = Time.time;
				_last = last;
				HardheimShipEquipmentPlugin.LogDebug($"[HH_BIND_TRACE] PENDING SET worldPos={worldPosition} worldRot={((Quaternion)(ref worldRotation)).eulerAngles} ship={((Object)ship).name} shipId={_last.ShipId}");
			}
		}
	}

	internal static bool TryConsume(out Snapshot snapshot)
	{
		snapshot = _last;
		if (!_last.IsValid)
		{
			return false;
		}
		if (Time.time - _last.TimeStamp > 10f)
		{
			Clear();
			return false;
		}
		Clear();
		return true;
	}

	internal static void Clear()
	{
		_last = default(Snapshot);
	}
}
internal static class MigrationFileLogger
{
	private static readonly object FileLock = new object();

	private static string GetLogDirectory()
	{
		string text = Path.Combine(Paths.ConfigPath, "HardheimShipEquipment");
		Directory.CreateDirectory(text);
		return text;
	}

	private static string GetCurrentLogPath()
	{
		string path = $"migration_{DateTime.Now:yyyy-MM-dd}.txt";
		return Path.Combine(GetLogDirectory(), path);
	}

	private static void CleanupOldLogs()
	{
		try
		{
			int num = ((HardheimShipEquipmentPlugin.CfgKeepMigrationLogs != null) ? HardheimShipEquipmentPlugin.CfgKeepMigrationLogs.Value : 5);
			string logDirectory = GetLogDirectory();
			List<FileInfo> list = (from f in new DirectoryInfo(logDirectory).GetFiles("migration_*.txt", SearchOption.TopDirectoryOnly)
				orderby f.Name descending
				select f).ToList();
			for (int i = num; i < list.Count; i++)
			{
				try
				{
					list[i].Delete();
				}
				catch
				{
				}
			}
		}
		catch
		{
		}
	}

	private static string SafeVec(Vector3 v)
	{
		//IL_0006: 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_001c: Unknown result type (might be due to invalid IL or missing references)
		return $"({v.x:0.000},{v.y:0.000},{v.z:0.000})";
	}

	private static string SafeQuat(Quaternion q)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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_0024: Unknown result type (might be due to invalid IL or missing references)
		Vector3 eulerAngles = ((Quaternion)(ref q)).eulerAngles;
		return $"({eulerAngles.x:0.000},{eulerAngles.y:0.000},{eulerAngles.z:0.000})";
	}

	private static string SafeShipId(ZDOID id)
	{
		return $"{((ZDOID)(ref id)).UserID}:{((ZDOID)(ref id)).ID}";
	}

	private static string GetWorldNameSafe()
	{
		try
		{
			return ((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldName() : "unknown_world";
		}
		catch
		{
			return "unknown_world";
		}
	}

	internal static void WriteLine(string eventType, string message)
	{
		try
		{
			if (HardheimShipEquipmentPlugin.CfgEnableMigrationFileLog != null && !HardheimShipEquipmentPlugin.CfgEnableMigrationFileLog.Value)
			{
				return;
			}
			lock (FileLock)
			{
				CleanupOldLogs();
				string currentLogPath = GetCurrentLogPath();
				bool flag = !File.Exists(currentLogPath);
				using StreamWriter streamWriter = new StreamWriter(currentLogPath, append: true, Encoding.UTF8);
				if (flag)
				{
					streamWriter.WriteLine("============================================================");
					streamWriter.WriteLine("HardheimShipEquipment migration log");
					streamWriter.WriteLine($"Date: {DateTime.Now:yyyy-MM-dd}");
					streamWriter.WriteLine("ModVersion: 1.0.0");
					streamWriter.WriteLine("World: " + GetWorldNameSafe());
					streamWriter.WriteLine("============================================================");
					streamWriter.WriteLine();
				}
				streamWriter.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{eventType}] {message}");
			}
		}
		catch
		{
		}
	}

	internal static void WriteItemState(string eventType, GameObject item, ZDO zdo, Ship resolvedShip, bool bound, int schema, bool hasShipId, bool hasLocalAnchor, bool hasShipRef, string result, string reason = null, Vector3? localPos = null, Quaternion? localRot = null)
	{
		//IL_002f: 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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			string text = (((Object)(object)item != (Object)null) ? ((Object)item).name : "<null>");
			Vector3 v = (((Object)(object)item != (Object)null) ? item.transform.position : Vector3.zero);
			Quaternion q = (((Object)(object)item != (Object)null) ? item.transform.rotation : Quaternion.identity);
			string text2 = (((Object)(object)resolvedShip != (Object)null) ? ((Object)resolvedShip).name : "NULL");
			string text3 = "NULL";
			if (zdo != null)
			{
				uint num = (uint)zdo.GetLong("hh_ship_uid_user", 0L);
				uint num2 = (uint)zdo.GetLong("hh_ship_uid_id", 0L);
				if (num != 0 || num2 != 0)
				{
					text3 = $"{num}:{num2}";
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("result=" + result);
			stringBuilder.AppendLine("itemName=" + text);
			stringBuilder.AppendLine("worldPos=" + SafeVec(v));
			stringBuilder.AppendLine("worldRot=" + SafeQuat(q));
			stringBuilder.AppendLine($"bound={bound}");
			stringBuilder.AppendLine($"schema={schema}");
			stringBuilder.AppendLine($"hasShipId={hasShipId}");
			stringBuilder.AppendLine("resolvedShip=" + text2);
			stringBuilder.AppendLine("shipId=" + text3);
			stringBuilder.AppendLine($"hasLocalAnchor={hasLocalAnchor}");
			stringBuilder.AppendLine($"hasShipRef={hasShipRef}");
			if (localPos.HasValue)
			{
				stringBuilder.AppendLine("localPos=" + SafeVec(localPos.Value));
			}
			if (localRot.HasValue)
			{
				stringBuilder.AppendLine("localRot=" + SafeQuat(localRot.Value));
			}
			if (!string.IsNullOrEmpty(reason))
			{
				stringBuilder.AppendLine("reason=" + reason);
			}
			WriteLine(eventType, Environment.NewLine + stringBuilder.ToString().TrimEnd(Array.Empty<char>()));
		}
		catch
		{
		}
	}
}
internal static class LastShipRaycastHit
{
	internal struct Snapshot
	{
		public bool IsValid;

		public Vector3 Point;

		public Vector3 Normal;

		public ZDOID ShipId;

		public float TimeStamp;
	}

	private static Snapshot _last;

	internal static void Set(Vector3 point, Vector3 normal, Ship ship)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: 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)
		if (!((Object)(object)ship == (Object)null))
		{
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && component.GetZDO() != null)
			{
				Snapshot last = default(Snapshot);
				last.IsValid = true;
				last.Point = point;
				last.Normal = normal;
				last.ShipId = component.GetZDO().m_uid;
				last.TimeStamp = Time.time;
				_last = last;
				HardheimShipEquipmentPlugin.LogDebug($"[LAST RAY HIT] point={point} normal={normal} shipId={_last.ShipId}");
			}
		}
	}

	internal static bool TryGet(out Snapshot snapshot)
	{
		snapshot = _last;
		if (!_last.IsValid)
		{
			return false;
		}
		if (Time.time - _last.TimeStamp > 1f)
		{
			Clear();
			return false;
		}
		return true;
	}

	internal static void Clear()
	{
		_last = default(Snapshot);
	}
}
public static class ShipTorchPlacementHelper
{
	internal static class HardheimShipCleanupHelper
	{
		internal static void DestroyAllBoundHHItemsForShip(Ship ship)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ship == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || component.GetZDO() == null)
			{
				return;
			}
			ZDOID uid = component.GetZDO().m_uid;
			ShipTorchAttachment[] array = Object.FindObjectsByType<ShipTorchAttachment>((FindObjectsSortMode)0);
			if (array == null || array.Length == 0)
			{
				return;
			}
			ShipTorchAttachment[] array2 = array;
			foreach (ShipTorchAttachment shipTorchAttachment in array2)
			{
				if (!((Object)(object)shipTorchAttachment == (Object)null) && IsHardheimPieceName(((Object)shipTorchAttachment).name) && shipTorchAttachment.IsBoundToShip(uid))
				{
					shipTorchAttachment.DestroyBecauseShipWasDestroyed();
				}
			}
		}
	}

	public static bool IsHardheimPieceName(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return false;
		}
		return value.StartsWith("hh_", StringComparison.OrdinalIgnoreCase);
	}

	public static bool IsShipChest(GameObject obj)
	{
		return false;
	}

	public static bool IsHardheimGhost(GameObject ghost)
	{
		if ((Object)(object)ghost == (Object)null)
		{
			return false;
		}
		string value = ((Object)ghost).name ?? string.Empty;
		if (IsHardheimPieceName(value))
		{
			return true;
		}
		Piece component = ghost.GetComponent<Piece>();
		if ((Object)(object)component != (Object)null && IsHardheimPieceName(((Object)component).name))
		{
			return true;
		}
		return false;
	}

	public static bool IsPreviewGhostObject(GameObject obj)
	{
		if ((Object)(object)obj == (Object)null)
		{
			return false;
		}
		if (!IsHardheimPieceName(((Object)obj).name))
		{
			return false;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return false;
		}
		GameObject placementGhost = ReflectionCache.GetPlacementGhost(localPlayer);
		if ((Object)(object)placementGhost == (Object)null)
		{
			return false;
		}
		return (Object)(object)placementGhost == (Object)(object)obj;
	}

	public static void EnsureGhostVisible(GameObject ghost)
	{
		if ((Object)(object)ghost == (Object)null)
		{
			return;
		}
		if (!ghost.activeSelf)
		{
			ghost.SetActive(true);
		}
		Transform[] componentsInChildren = ghost.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null && !((Component)val).gameObject.activeSelf)
			{
				((Component)val).gameObject.SetActive(true);
			}
		}
		Renderer[] componentsInChildren2 = ghost.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val2 in componentsInChildren2)
		{
			if (!((Object)(object)val2 == (Object)null))
			{
				val2.enabled = true;
				val2.forceRenderingOff = false;
			}
		}
	}

	public static void HandleMarkerOffsetHotkeys(GameObject ghost, GameObject marker)
	{
		//IL_004e: 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_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ghost == (Object)null || (Object)(object)marker == (Object)null || HardheimShipEquipmentPlugin.CfgMarkerOffsetY == null)
		{
			return;
		}
		bool flag = false;
		float num = ((HardheimShipEquipmentPlugin.CfgMarkerOffsetStep != null) ? HardheimShipEquipmentPlugin.CfgMarkerOffsetStep.Value : 0.01f);
		KeyboardShortcut value;
		if (HardheimShipEquipmentPlugin.CfgMarkerOffsetUpKey != null)
		{
			value = HardheimShipEquipmentPlugin.CfgMarkerOffsetUpKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				ConfigEntry<float> cfgMarkerOffsetY = HardheimShipEquipmentPlugin.CfgMarkerOffsetY;
				cfgMarkerOffsetY.Value += num;
				flag = true;
			}
		}
		if (HardheimShipEquipmentPlugin.CfgMarkerOffsetDownKey != null)
		{
			value = HardheimShipEquipmentPlugin.CfgMarkerOffsetDownKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				ConfigEntry<float> cfgMarkerOffsetY2 = HardheimShipEquipmentPlugin.CfgMarkerOffsetY;
				cfgMarkerOffsetY2.Value -= num;
				flag = true;
			}
		}
		if (flag)
		{
			HardheimShipEquipmentPlugin instance = HardheimShipEquipmentPlugin.Instance;
			if (instance != null)
			{
				ConfigFile config = ((BaseUnityPlugin)instance).Config;
				if (config != null)
				{
					config.Save();
				}
			}
			HardheimShipEquipmentPlugin.LogDebug($"[MARKER OFFSET] savedOffsetY={HardheimShipEquipmentPlugin.CfgMarkerOffsetY.Value:0.000}");
		}
		if (HardheimShipEquipmentPlugin.CfgMarkerOffsetLogKey == null)
		{
			return;
		}
		value = HardheimShipEquipmentPlugin.CfgMarkerOffsetLogKey.Value;
		if (!((KeyboardShortcut)(ref value)).IsDown())
		{
			return;
		}
		Vector3 position = marker.transform.position;
		Vector3 position2 = ghost.transform.position;
		Vector3 val = position2 - position;
		HardheimShipEquipmentPlugin.CfgMarkerOffsetY.Value = val.y;
		HardheimShipEquipmentPlugin instance2 = HardheimShipEquipmentPlugin.Instance;
		if (instance2 != null)
		{
			ConfigFile config2 = ((BaseUnityPlugin)instance2).Config;
			if (config2 != null)
			{
				config2.Save();
			}
		}
		HardheimShipEquipmentPlugin.LogDebug($"[MARKER OFFSET LOG] markerPos={position} ghostPos={position2} savedOffset=(0.00, {val.y:0.00}, 0.00)");
	}

	public static void ForceGhostToMarkerOffset(GameObject ghost, GameObject marker)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)ghost == (Object)null) && !((Object)(object)marker == (Object)null) && HardheimShipEquipmentPlugin.CfgMarkerOffsetY != null)
		{
			float value = HardheimShipEquipmentPlugin.CfgMarkerOffsetY.Value;
			Vector3 position = marker.transform.position;
			ghost.transform.position = new Vector3(position.x, position.y + value, position.z);
		}
	}

	public static Ship FindShipByZdoId(ZDOID id)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		if (id == ZDOID.None)
		{
			return null;
		}
		Ship[] array = Object.FindObjectsByType<Ship>((FindObjectsSortMode)0);
		HardheimShipEquipmentPlugin.LogDebug($"[FIND SHIP] wanted={((ZDOID)(ref id)).UserID}:{((ZDOID)(ref id)).ID} activeShips={array.Length}");
		Ship[] array2 = array;
		foreach (Ship val in array2)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				ZDO zDO = component.GetZDO();
				HardheimShipEquipmentPlugin.LogDebug("[FIND SHIP CANDIDATE] ship=" + ((Object)val).name + " uid=" + ((zDO != null) ? $"{((ZDOID)(ref zDO.m_uid)).UserID}:{((ZDOID)(ref zDO.m_uid)).ID}" : "null"));
				if (zDO != null && zDO.m_uid == id)
				{
					return val;
				}
			}
		}
		return null;
	}

	public static Ship FindNearestShip(Vector3 position, float radius)
	{
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: 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)
		Ship[] array = Object.FindObjectsByType<Ship>((FindObjectsSortMode)0);
		Ship result = null;
		float num = float.MaxValue;
		Ship[] array2 = array;
		foreach (Ship val in array2)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				continue;
			}
			Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true);
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				continue;
			}
			Collider[] array3 = componentsInChildren;
			foreach (Collider val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger)
				{
					Vector3 val3 = val2.ClosestPoint(position);
					float num2 = Vector3.Distance(position, val3);
					if (num2 <= radius && num2 < num)
					{
						result = val;
						num = num2;
					}
				}
			}
		}
		return result;
	}
}
public sealed class ShipTorchHover : MonoBehaviour, Hoverable, Interactable
{
	public string HoverName = "";

	public string HoverText = "";

	public string GetHoverName()
	{
		return string.IsNullOrWhiteSpace(HoverName) ? "Hajófáklya" : HoverName;
	}

	public string GetHoverText()
	{
		return HoverName + "\n<color=yellow>[E]</color> Használ\n[1-8] Tárgyat használ";
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		Fireplace componentInChildren = ((Component)this).GetComponentInChildren<Fireplace>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			return componentInChildren.Interact(user, hold, alt);
		}
		return false;
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		Fireplace componentInChildren = ((Component)this).GetComponentInChildren<Fireplace>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			return componentInChildren.UseItem(user, item);
		}
		return false;
	}
}
public sealed class ShipDrumInteraction : MonoBehaviour, Interactable, Hoverable
{
	[CompilerGenerated]
	private sealed class <DelayedVocalJoinSync>d__74 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public bool female;

		public ShipDrumInteraction <>4__this;

		private int <i>5__1;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<i>5__1 = 0;
				break;
			case 1:
				<>1__state = -1;
				if (female && !<>4__this._localJoinedFemaleVocal)
				{
					return false;
				}
				if (!female && !<>4__this._localJoinedMaleVocal)
				{
					return false;
				}
				<>4__this.ForceVocalJoinState(female);
				<>4__this.SyncSongPlayback(allowDuringInitialBlock: true);
				<i>5__1++;
				break;
			}
			if (<i>5__1 < 10)
			{
				<>2__current = (object)new WaitForSeconds(0.25f);
				<>1__state = 1;
				return true;
			}
			if (female)
			{
				<>4__this._pendingFemaleJoinUntil = 0f;
			}
			else
			{
				<>4__this._pendingMaleJoinUntil = 0f;
			}
			return false;
		}

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

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

	private AudioSource _drumSource;

	private float _nextDrumInteractTime;

	private AudioSource _maleVocalSource;

	private AudioSource _femaleVocalSource;

	private bool _localJoinedMaleVocal;

	private bool _localJoinedFemaleVocal;

	private float _nextDrummerHeartbeatTime;

	private ZNetView _nview;

	private bool _songWasPlaying = false;

	private bool _drumWasPlayingLocally;

	private bool _localDrumStartedByThisClient;

	private bool _suppressSongEndReward;

	private bool _initialSongStateSanitized;

	private float _blockAutoSongPlaybackUntil;

	private bool _localSongActionThisSession;

	private float _suppressMaleVocalUntil;

	private float _suppressFemaleVocalUntil;

	private float _pendingMaleJoinUntil;

	private float _pendingFemaleJoinUntil;

	private static Sprite _songBuffIcon;

	private long _localDrummerPlayerId;

	private float _nextDrummerDistanceCheck;

	private float _nextLocalVocalShipCheckTime;

	private const float MaxDrumDistance = 2.2f;

	private static readonly string[] SongIds = new string[2] { "song1", "song2" };

	private static readonly string[] SongDisplayNames = new string[2] { "Valhalla", "Túlpart" };

	private readonly Dictionary<AudioSource, float> _savedVanillaMusicVolumes = new Dictionary<AudioSource, float>();

	private readonly Dictionary<string, AudioClip> _clipCache = new Dictionary<string, AudioClip>();

	private float _nextSongSyncTime;

	private int _lastProcessedSongFinishedToken;

	public string GetHoverName()
	{
		return "Dob";
	}

	public string GetHoverText()
	{
		if ((Object)(object)_nview == (Object)null)
		{
			_nview = ((Component)this).GetComponent<ZNetView>();
		}
		if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
		{
			return "Harci szellem";
		}
		ZDO zDO = _nview.GetZDO();
		if (zDO == null)
		{
			return "Harci szellem";
		}
		bool @bool = zDO.GetBool("hh_song_drum_active", false);
		int num = Mathf.Clamp(zDO.GetInt("hh_song_index", 0), 0, SongIds.Length - 1);
		if (!@bool)
		{
			return "Harci szellem\n<color=yellow>[E]</color> Rituálé indítása\n<color=yellow>[Shift+E]</color> Dal váltása\nAktuális dal: " + SongDisplayNames[num];
		}
		return "Harci szellem\n<color=yellow>[E]</color> Rituálé megszakítása\nAktív dal: " + SongDisplayNames[num];
	}

	private void Start()
	{
		_blockAutoSongPlaybackUntil = Time.time + 8f;
		EnsureAudioSources();
		StopAndClearSource(_drumSource);
		StopAndClearSource(_maleVocalSource);
		StopAndClearSource(_femaleVocalSource);
		SetVanillaMusicMuted(muted: false);
		HardheimShipEquipmentPlugin.LogDebug("[SHIP SONG] Initial auto playback blocked for 8 sec.");
	}

	public bool IsDrumSongActive()
	{
		EnsureNView();
		if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
		{
			return false;
		}
		ZDO zDO = _nview.GetZDO();
		if (zDO == null)
		{
			return false;
		}
		return zDO.GetBool("hh_song_drum_active", false);
	}

	public bool CanPlayerJoinVocal(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		EnsureNView();
		if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
		{
			return false;
		}
		ZDO zDO = _nview.GetZDO();
		if (zDO == null)
		{
			return false;
		}
		if (!zDO.GetBool("hh_song_drum_active", false))
		{
			return false;
		}
		if (IsFemale(player))
		{
			return zDO.GetInt("hh_song_female_vocal_count", 0) <= 0;
		}
		return z