Decompiled source of HardheimWeaponReinforcement v1.0.0

plugins/WeaponReinforcement.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
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("WeaponReinforcement")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WeaponReinforcement")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3cd12e7c-3247-4e1b-a85c-7bed4c338b17")]
[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")]
namespace HardheimWeaponReinforcement;

[BepInPlugin("h4nz0.hardheimweaponreinforcement", "Hardheim Weapon Reinforcement", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[SynchronizationMode(/*Could not decode attribute arguments.*/)]
public class HardheimWeaponReinforcementPlugin : BaseUnityPlugin
{
	public enum BonusStationType
	{
		None,
		Reinforcement,
		Forge,
		Blessing
	}

	[CompilerGenerated]
	private sealed class <EnsureCustomBlessingClipLoaded>d__161 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		private string <filePath>5__1;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (_customBlessingClipLoadAttempted)
				{
					return false;
				}
				_customBlessingClipLoadAttempted = true;
				if (!RuntimeUseCustomBlessingAudioFile)
				{
					return false;
				}
				<filePath>5__1 = GetCustomBlessingAudioPath();
				if (string.IsNullOrEmpty(<filePath>5__1) || !File.Exists(<filePath>5__1))
				{
					LogDebug("Custom blessing audio file not found: " + <filePath>5__1);
					return false;
				}
				<>2__current = LoadClipCoroutine(<filePath>5__1, delegate(AudioClip clip)
				{
					_customBlessingClip = clip;
					if ((Object)(object)clip != (Object)null)
					{
						((Object)clip).name = "HardheimWeaponReinforcementBlessingAudio";
					}
				});
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				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();
		}
	}

	[CompilerGenerated]
	private sealed class <EnsureCustomForgeClipLoaded>d__160 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		private string <filePath>5__1;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (_customForgeClipLoadAttempted)
				{
					return false;
				}
				_customForgeClipLoadAttempted = true;
				if (!RuntimeUseCustomForgeAudioFile)
				{
					return false;
				}
				<filePath>5__1 = GetCustomForgeAudioPath();
				if (string.IsNullOrEmpty(<filePath>5__1) || !File.Exists(<filePath>5__1))
				{
					LogDebug("Custom forge audio file not found: " + <filePath>5__1);
					return false;
				}
				<>2__current = LoadClipCoroutine(<filePath>5__1, delegate(AudioClip clip)
				{
					_customForgeClip = clip;
					if ((Object)(object)clip != (Object)null)
					{
						((Object)clip).name = "HardheimWeaponReinforcementForgeAudio";
					}
				});
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				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();
		}
	}

	[CompilerGenerated]
	private sealed class <EnsureCustomReinforcementClipLoaded>d__159 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		private string <filePath>5__1;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (_customReinforcementClipLoadAttempted)
				{
					return false;
				}
				_customReinforcementClipLoadAttempted = true;
				if (!RuntimeUseCustomReinforcementAudioFile)
				{
					return false;
				}
				<filePath>5__1 = GetCustomReinforcementAudioPath();
				if (string.IsNullOrEmpty(<filePath>5__1) || !File.Exists(<filePath>5__1))
				{
					LogDebug("Custom reinforcement audio file not found: " + <filePath>5__1);
					return false;
				}
				<>2__current = LoadClipCoroutine(<filePath>5__1, delegate(AudioClip clip)
				{
					_customReinforcementClip = clip;
					if ((Object)(object)clip != (Object)null)
					{
						((Object)clip).name = "HardheimWeaponReinforcementGrindingAudio";
					}
				});
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				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();
		}
	}

	[CompilerGenerated]
	private sealed class <LoadClipCoroutine>d__162 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string filePath;

		public Action<AudioClip> onLoaded;

		private string <url>5__1;

		private AudioType <audioType>5__2;

		private UnityWebRequest <req>5__3;

		private AudioClip <clip>5__4;

		private Exception <ex>5__5;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			int num = <>1__state;
			if (num == -3 || num == 1)
			{
				try
				{
				}
				finally
				{
					<>m__Finally1();
				}
			}
			<url>5__1 = null;
			<req>5__3 = null;
			<clip>5__4 = null;
			<ex>5__5 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0054: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			bool result;
			try
			{
				switch (<>1__state)
				{
				default:
					result = false;
					break;
				case 0:
					<>1__state = -1;
					<url>5__1 = "file://" + filePath.Replace("\\", "/");
					<audioType>5__2 = DetectAudioTypeFromPath(filePath);
					<req>5__3 = UnityWebRequestMultimedia.GetAudioClip(<url>5__1, <audioType>5__2);
					<>1__state = -3;
					<>2__current = <req>5__3.SendWebRequest();
					<>1__state = 1;
					result = true;
					break;
				case 1:
					<>1__state = -3;
					if ((int)<req>5__3.result != 1)
					{
						LogDebug("Failed to load audio: " + <req>5__3.error);
						result = false;
						<>m__Finally1();
						break;
					}
					<clip>5__4 = null;
					try
					{
						<clip>5__4 = DownloadHandlerAudioClip.GetContent(<req>5__3);
					}
					catch (Exception ex)
					{
						<ex>5__5 = ex;
						LogDebug("Exception while reading audio: " + <ex>5__5.Message);
					}
					onLoaded?.Invoke(<clip>5__4);
					<clip>5__4 = null;
					<>m__Finally1();
					<req>5__3 = null;
					result = false;
					break;
				}
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
			return result;
		}

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

		private void <>m__Finally1()
		{
			<>1__state = -1;
			if (<req>5__3 != null)
			{
				((IDisposable)<req>5__3).Dispose();
			}
		}

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

	[CompilerGenerated]
	private sealed class <LocalAnimatorStateLoggerCoroutine>d__191 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player player;

		public string tag;

		public float seconds;

		private float <endTime>5__1;

		private Animator <animator>5__2;

		private AnimatorStateInfo <current>5__3;

		private AnimatorStateInfo <next>5__4;

		private AnimatorClipInfo[] <clips>5__5;

		private int <i>5__6;

		private Exception <ex>5__7;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<animator>5__2 = null;
			<clips>5__5 = null;
			<ex>5__7 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<endTime>5__1 = Time.time + seconds;
				break;
			case 1:
				<>1__state = -1;
				<animator>5__2 = null;
				break;
			}
			if (Time.time < <endTime>5__1)
			{
				if ((Object)(object)player == (Object)null)
				{
					return false;
				}
				<animator>5__2 = ((Component)player).GetComponentInChildren<Animator>();
				if ((Object)(object)<animator>5__2 != (Object)null)
				{
					try
					{
						<current>5__3 = <animator>5__2.GetCurrentAnimatorStateInfo(0);
						<next>5__4 = <animator>5__2.GetNextAnimatorStateInfo(0);
						LogDebug($"[{tag}] current.fullPathHash={((AnimatorStateInfo)(ref <current>5__3)).fullPathHash} current.shortNameHash={((AnimatorStateInfo)(ref <current>5__3)).shortNameHash} current.normalizedTime={((AnimatorStateInfo)(ref <current>5__3)).normalizedTime:0.00}");
						LogDebug($"[{tag}] next.fullPathHash={((AnimatorStateInfo)(ref <next>5__4)).fullPathHash} next.shortNameHash={((AnimatorStateInfo)(ref <next>5__4)).shortNameHash} next.normalizedTime={((AnimatorStateInfo)(ref <next>5__4)).normalizedTime:0.00}");
						LogDebug(string.Format("[{0}] crafting={1} moving={2} forward_speed={3:0.00} sideway_speed={4:0.00}", tag, <animator>5__2.GetInteger("crafting"), <animator>5__2.GetBool("moving"), <animator>5__2.GetFloat("forward_speed"), <animator>5__2.GetFloat("sideway_speed")));
						<clips>5__5 = <animator>5__2.GetCurrentAnimatorClipInfo(0);
						if (<clips>5__5 != null)
						{
							<i>5__6 = 0;
							while (<i>5__6 < <clips>5__5.Length)
							{
								if ((Object)(object)((AnimatorClipInfo)(ref <clips>5__5[<i>5__6])).clip != (Object)null)
								{
									LogDebug($"[{tag}] clip={((Object)((AnimatorClipInfo)(ref <clips>5__5[<i>5__6])).clip).name} weight={((AnimatorClipInfo)(ref <clips>5__5[<i>5__6])).weight:0.00}");
								}
								int num = <i>5__6 + 1;
								<i>5__6 = num;
							}
						}
						<clips>5__5 = null;
					}
					catch (Exception ex)
					{
						<ex>5__7 = ex;
						LogDebug("[" + tag + "] logger failed: " + <ex>5__7.Message);
					}
				}
				<>2__current = (object)new WaitForSeconds(0.1f);
				<>1__state = 1;
				return true;
			}
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <ProcessRoutine>d__185 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player player;

		public ItemData weapon;

		public Transform stationTransform;

		public BonusStationType type;

		private float <duration>5__1;

		private float <elapsed>5__2;

		private float <nextFxAt>5__3;

		private string <message>5__4;

		private bool <success>5__5;

		private float <maxDistance>5__6;

		private float <distance>5__7;

		private ItemData <currentWeapon>5__8;

		private Vector3 <fxPos>5__9;

		private string <blessingFx>5__10;

		private Animator <animator>5__11;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			int num = <>1__state;
			if (num == -3 || (uint)(num - 1) <= 1u)
			{
				try
				{
				}
				finally
				{
					<>m__Finally1();
				}
			}
			<message>5__4 = null;
			<currentWeapon>5__8 = null;
			<blessingFx>5__10 = null;
			<animator>5__11 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			bool result;
			try
			{
				switch (<>1__state)
				{
				default:
					result = false;
					goto end_IL_0000;
				case 0:
					<>1__state = -1;
					<duration>5__1 = RuntimeProcessAnimationSeconds;
					<elapsed>5__2 = 0f;
					<nextFxAt>5__3 = 0f;
					<>1__state = -3;
					if (CfgShowCenterMessages != null && CfgShowCenterMessages.Value)
					{
						((Character)player).Message((MessageType)2, GetProgressTextForType(type), 0, (Sprite)null);
					}
					<>2__current = StartProcessSound(player, stationTransform, type);
					<>1__state = 1;
					result = true;
					goto end_IL_0000;
				case 1:
					<>1__state = -3;
					break;
				case 2:
					<>1__state = -3;
					<currentWeapon>5__8 = null;
					break;
				}
				if (<elapsed>5__2 < <duration>5__1)
				{
					if ((Object)(object)player == (Object)null || (Object)(object)stationTransform == (Object)null)
					{
						result = false;
						goto IL_046d;
					}
					<maxDistance>5__6 = 2.6f;
					<distance>5__7 = Vector3.Distance(((Component)player).transform.position, stationTransform.position);
					if (<distance>5__7 > <maxDistance>5__6)
					{
						if (CfgShowCenterMessages != null && CfgShowCenterMessages.Value)
						{
							((Character)player).Message((MessageType)2, GetInterruptedTextForType(type), 0, (Sprite)null);
						}
						result = false;
						goto IL_046d;
					}
					if (!CanProcessCurrentWeapon(player, type, out <currentWeapon>5__8))
					{
						if (CfgShowCenterMessages != null && CfgShowCenterMessages.Value)
						{
							((Character)player).Message((MessageType)2, GetInterruptedTextForType(type), 0, (Sprite)null);
						}
						result = false;
						goto IL_046d;
					}
					if (<currentWeapon>5__8 != weapon)
					{
						if (CfgShowCenterMessages != null && CfgShowCenterMessages.Value)
						{
							((Character)player).Message((MessageType)2, GetInterruptedTextForType(type), 0, (Sprite)null);
						}
						result = false;
						goto IL_046d;
					}
					FaceTarget(player, stationTransform.position);
					StopPlayerMovement(player);
					TryPlayStationAnimation(player, type);
					if (type == BonusStationType.Blessing)
					{
						SuppressBlessingCameraShakeFor(0.35f);
						TryLockBlessingPose(player);
					}
					UpdateCustomAudioLoopPosition(GetProcessEffectPosition(player, stationTransform));
					if (<elapsed>5__2 >= <nextFxAt>5__3 && RuntimeEnableProcessVfx)
					{
						<fxPos>5__9 = GetProcessEffectPosition(player, stationTransform);
						if (type == BonusStationType.Forge)
						{
							SpawnForgeProcessEffects(<fxPos>5__9, stationTransform.rotation);
							<nextFxAt>5__3 += 0.5f;
						}
						else if (type == BonusStationType.Blessing)
						{
							<blessingFx>5__10 = ResolveBlessingVfxPrefab();
							LogDebug("[PROCESS] Spawning BLESSING VFX. Prefab=" + <blessingFx>5__10 + " (visual only)");
							TrySpawnEffectVisualOnly(<blessingFx>5__10, <fxPos>5__9, stationTransform.rotation);
							<nextFxAt>5__3 += 0.75f;
							<blessingFx>5__10 = null;
						}
						else
						{
							SpawnReinforcementProcessEffects(<fxPos>5__9, stationTransform.rotation);
							<nextFxAt>5__3 += RuntimeReinforcementSparkInterval;
						}
					}
					<elapsed>5__2 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 2;
					result = true;
				}
				else
				{
					<success>5__5 = TryApplyBonusToWeapon(player, weapon, type, out <message>5__4);
					if (<success>5__5 && CfgShowCenterMessages != null && CfgShowCenterMessages.Value)
					{
						((Character)player).Message((MessageType)2, <message>5__4, 0, (Sprite)null);
					}
					<message>5__4 = null;
					<>m__Finally1();
					result = false;
				}
				goto end_IL_0000;
				IL_046d:
				<>m__Finally1();
				end_IL_0000:;
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
			return result;
		}

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

		private void <>m__Finally1()
		{
			<>1__state = -1;
			try
			{
				if ((Object)(object)player != (Object)null)
				{
					TryStopPlayerEmote(player);
					<animator>5__11 = ((Component)player).GetComponentInChildren<Animator>();
					if ((Object)(object)<animator>5__11 != (Object)null)
					{
						if (_blessingAnimatorDisabledThisProcess)
						{
							((Behaviour)<animator>5__11).enabled = true;
						}
						<animator>5__11.speed = 1f;
						<animator>5__11.ResetTrigger("interact");
						<animator>5__11.ResetTrigger("attack");
						<animator>5__11.ResetTrigger("attack_abort");
						<animator>5__11.ResetTrigger("swing_hammer");
						<animator>5__11.ResetTrigger("emote_wave");
						<animator>5__11.ResetTrigger("emote_bow");
						<animator>5__11.ResetTrigger("emote_point");
						<animator>5__11.ResetTrigger("emote_cheer");
						<animator>5__11.ResetTrigger("emote_stop");
						<animator>5__11.ResetTrigger("emote_toast");
						<animator>5__11.ResetTrigger("emote_relax");
						<animator>5__11.ResetTrigger("emote_vibe");
						<animator>5__11.SetBool("moving", false);
						<animator>5__11.SetBool("emote_sit", false);
						<animator>5__11.SetBool("emote_sitchair", false);
						<animator>5__11.SetBool("attach_chair", false);
						<animator>5__11.SetBool("attach_throne", false);
						<animator>5__11.SetBool("attach_divan", false);
						<animator>5__11.SetBool("attach_sitship", false);
						<animator>5__11.SetFloat("forward_speed", 0f);
						<animator>5__11.SetFloat("sideway_speed", 0f);
						<animator>5__11.SetInteger("crafting", 0);
						<animator>5__11.Update(0f);
					}
					<animator>5__11 = null;
				}
			}
			catch
			{
			}
			StopCustomAudioLoop();
			BroadcastStationProcess(player, stationTransform, type, active: false);
			_isProcessInProgress = false;
			_activePlayerId = 0L;
			_activeRoutine = null;
			_activeProcessType = BonusStationType.None;
			_blessingPoseLockedThisProcess = false;
			_blessingAnimatorDisabledThisProcess = false;
		}

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

	[CompilerGenerated]
	private sealed class <RemoteStationProcessCoroutine>d__207 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public long playerId;

		public Transform stationTransform;

		public BonusStationType type;

		private bool <reinforcementStarted>5__1;

		private bool <blessingStarted>5__2;

		private float <duration>5__3;

		private float <elapsed>5__4;

		private float <nextFxAt>5__5;

		private Player <player>5__6;

		private Vector3 <fxPos>5__7;

		private string <blessingFx>5__8;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<player>5__6 = null;
			<blessingFx>5__8 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<reinforcementStarted>5__1 = false;
				<blessingStarted>5__2 = false;
				<duration>5__3 = RuntimeProcessAnimationSeconds;
				<elapsed>5__4 = 0f;
				<nextFxAt>5__5 = 0f;
				<player>5__6 = FindPlayerById(playerId);
				if ((Object)(object)<player>5__6 == (Object)null)
				{
					return false;
				}
				if ((Object)(object)Player.m_localPlayer != (Object)null && <player>5__6 == Player.m_localPlayer)
				{
					return false;
				}
				<>2__current = StartRemoteProcessSound(playerId, <player>5__6, stationTransform, type);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				break;
			case 2:
				<>1__state = -1;
				break;
			}
			if (<elapsed>5__4 < <duration>5__3)
			{
				<player>5__6 = FindPlayerById(playerId);
				if (!((Object)(object)<player>5__6 == (Object)null) && !((Object)(object)stationTransform == (Object)null))
				{
					FaceTarget(<player>5__6, stationTransform.position);
					TryPlayRemoteStationAnimation(<player>5__6, type, ref <reinforcementStarted>5__1, ref <blessingStarted>5__2);
					if (type == BonusStationType.Blessing)
					{
						SuppressBlessingCameraShakeFor(0.35f);
						TryLockBlessingPose(<player>5__6);
					}
					UpdateRemoteAudioLoopPosition(playerId, GetProcessEffectPosition(<player>5__6, stationTransform));
					if (<elapsed>5__4 >= <nextFxAt>5__5 && RuntimeEnableProcessVfx)
					{
						<fxPos>5__7 = GetProcessEffectPosition(<player>5__6, stationTransform);
						if (type == BonusStationType.Forge)
						{
							SpawnForgeProcessEffects(<fxPos>5__7, stationTransform.rotation);
							<nextFxAt>5__5 += 0.5f;
						}
						else if (type == BonusStationType.Blessing)
						{
							<blessingFx>5__8 = ResolveBlessingVfxPrefab();
							LogDebug("[NET PROCESS] Remote BLESSING VFX. Prefab=" + <blessingFx>5__8 + " (stable visual only)");
							TrySpawnEffectVisualOnly(<blessingFx>5__8, <fxPos>5__7, stationTransform.rotation);
							<nextFxAt>5__5 += 0.75f;
							<blessingFx>5__8 = null;
						}
						else
						{
							SpawnReinforcementProcessEffects(<fxPos>5__7, stationTransform.rotation);
							<nextFxAt>5__5 += RuntimeReinforcementSparkInterval;
						}
					}
					<elapsed>5__4 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
			}
			StopRemoteStationProcess(playerId, resetAnimator: true);
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <StartProcessSound>d__166 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player player;

		public Transform stationTransform;

		public BonusStationType type;

		private Vector3 <pos>5__1;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (!RuntimeEnableProcessSfx)
				{
					return false;
				}
				<pos>5__1 = GetProcessEffectPosition(player, stationTransform);
				if (type == BonusStationType.Reinforcement)
				{
					if (RuntimeUseCustomReinforcementAudioFile)
					{
						if (!_customReinforcementClipLoadAttempted)
						{
							<>2__current = EnsureCustomReinforcementClipLoaded();
							<>1__state = 1;
							return true;
						}
						goto IL_00a3;
					}
					goto IL_00d3;
				}
				if (type == BonusStationType.Forge)
				{
					if (RuntimeUseCustomForgeAudioFile)
					{
						if (!_customForgeClipLoadAttempted)
						{
							<>2__current = EnsureCustomForgeClipLoaded();
							<>1__state = 2;
							return true;
						}
						goto IL_013b;
					}
					goto IL_016b;
				}
				if (type != BonusStationType.Blessing)
				{
					break;
				}
				if (RuntimeUseCustomBlessingAudioFile)
				{
					if (!_customBlessingClipLoadAttempted)
					{
						<>2__current = EnsureCustomBlessingClipLoaded();
						<>1__state = 3;
						return true;
					}
					goto IL_01d0;
				}
				goto IL_0200;
			case 1:
				<>1__state = -1;
				goto IL_00a3;
			case 2:
				<>1__state = -1;
				goto IL_013b;
			case 3:
				{
					<>1__state = -1;
					goto IL_01d0;
				}
				IL_00d3:
				TrySpawnEffect(RuntimeReinforcementSfxPrefab, <pos>5__1, stationTransform.rotation);
				return false;
				IL_016b:
				TrySpawnEffect(ResolveForgeSfxPrefab(), <pos>5__1, stationTransform.rotation);
				return false;
				IL_0200:
				LogDebug("[BLESSING] Custom blessing audio missing; fallback SFX skipped to avoid vanilla boom/shake.");
				break;
				IL_01d0:
				if ((Object)(object)_customBlessingClip != (Object)null)
				{
					StartCustomAudioLoop(_customBlessingClip, <pos>5__1, RuntimeCustomBlessingAudioVolume, "HardheimWeaponReinforcementBlessingAudio");
					return false;
				}
				goto IL_0200;
				IL_013b:
				if ((Object)(object)_customForgeClip != (Object)null)
				{
					StartCustomAudioLoop(_customForgeClip, <pos>5__1, RuntimeCustomForgeAudioVolume, "HardheimWeaponReinforcementForgeAudio");
					return false;
				}
				goto IL_016b;
				IL_00a3:
				if ((Object)(object)_customReinforcementClip != (Object)null)
				{
					StartCustomAudioLoop(_customReinforcementClip, <pos>5__1, RuntimeCustomReinforcementAudioVolume, "HardheimWeaponReinforcementGrindingAudio");
					return false;
				}
				goto IL_00d3;
			}
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <StartRemoteProcessSound>d__211 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public long playerId;

		public Player player;

		public Transform stationTransform;

		public BonusStationType type;

		private Vector3 <pos>5__1;

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

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

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

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

		private bool MoveNext()
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (!RuntimeEnableProcessSfx || (Object)(object)player == (Object)null || (Object)(object)stationTransform == (Object)null)
				{
					return false;
				}
				<pos>5__1 = GetProcessEffectPosition(player, stationTransform);
				if (type == BonusStationType.Reinforcement)
				{
					if (RuntimeUseCustomReinforcementAudioFile)
					{
						if (!_customReinforcementClipLoadAttempted)
						{
							<>2__current = EnsureCustomReinforcementClipLoaded();
							<>1__state = 1;
							return true;
						}
						goto IL_00c2;
					}
					goto IL_00f8;
				}
				if (type == BonusStationType.Forge)
				{
					if (RuntimeUseCustomForgeAudioFile)
					{
						if (!_customForgeClipLoadAttempted)
						{
							<>2__current = EnsureCustomForgeClipLoaded();
							<>1__state = 2;
							return true;
						}
						goto IL_0160;
					}
					goto IL_0196;
				}
				if (type == BonusStationType.Blessing)
				{
					if (RuntimeUseCustomBlessingAudioFile)
					{
						if (!_customBlessingClipLoadAttempted)
						{
							<>2__current = EnsureCustomBlessingClipLoaded();
							<>1__state = 3;
							return true;
						}
						goto IL_01fb;
					}
					goto IL_0231;
				}
				return false;
			case 1:
				<>1__state = -1;
				goto IL_00c2;
			case 2:
				<>1__state = -1;
				goto IL_0160;
			case 3:
				{
					<>1__state = -1;
					goto IL_01fb;
				}
				IL_00f8:
				TrySpawnEffect(RuntimeReinforcementSfxPrefab, <pos>5__1, stationTransform.rotation);
				return false;
				IL_0196:
				TrySpawnEffect(ResolveForgeSfxPrefab(), <pos>5__1, stationTransform.rotation);
				return false;
				IL_0231:
				LogDebug("[NET PROCESS] Remote blessing custom audio missing; fallback SFX skipped to avoid boom/shake.");
				return false;
				IL_0160:
				if ((Object)(object)_customForgeClip != (Object)null)
				{
					StartRemoteCustomAudioLoop(playerId, _customForgeClip, <pos>5__1, RuntimeCustomForgeAudioVolume, "HH_WR_RemoteForgeAudio");
					return false;
				}
				goto IL_0196;
				IL_01fb:
				if ((Object)(object)_customBlessingClip != (Object)null)
				{
					StartRemoteCustomAudioLoop(playerId, _customBlessingClip, <pos>5__1, RuntimeCustomBlessingAudioVolume, "HH_WR_RemoteBlessingAudio");
					return false;
				}
				goto IL_0231;
				IL_00c2:
				if ((Object)(object)_customReinforcementClip != (Object)null)
				{
					StartRemoteCustomAudioLoop(playerId, _customReinforcementClip, <pos>5__1, RuntimeCustomReinforcementAudioVolume, "HH_WR_RemoteGrindingAudio");
					return false;
				}
				goto IL_00f8;
			}
		}

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

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

	[CompilerGenerated]
	private sealed class <VanillaGaldrStateLoggerCoroutine>d__193 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player player;

		public CraftingStation station;

		private float <endTime>5__1;

		private Animator <animator>5__2;

		private AnimatorStateInfo <current>5__3;

		private AnimatorStateInfo <next>5__4;

		private AnimatorClipInfo[] <clips>5__5;

		private int <i>5__6;

		private Exception <ex>5__7;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<animator>5__2 = null;
			<clips>5__5 = null;
			<ex>5__7 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<endTime>5__1 = Time.time + 2f;
				LogDebug("[VANILLA GALDR] ---- state logging started ---- station=" + (((Object)(object)station != (Object)null && (Object)(object)((Component)station).gameObject != (Object)null) ? ((Object)((Component)station).gameObject).name : "null"));
				break;
			case 1:
				<>1__state = -1;
				<animator>5__2 = null;
				break;
			}
			if (Time.time < <endTime>5__1 && !((Object)(object)player == (Object)null))
			{
				<animator>5__2 = ((Component)player).GetComponentInChildren<Animator>();
				if ((Object)(object)<animator>5__2 != (Object)null)
				{
					try
					{
						<current>5__3 = <animator>5__2.GetCurrentAnimatorStateInfo(0);
						<next>5__4 = <animator>5__2.GetNextAnimatorStateInfo(0);
						LogDebug($"[VANILLA GALDR] current.fullPathHash={((AnimatorStateInfo)(ref <current>5__3)).fullPathHash} current.shortNameHash={((AnimatorStateInfo)(ref <current>5__3)).shortNameHash} current.normalizedTime={((AnimatorStateInfo)(ref <current>5__3)).normalizedTime:0.00}");
						LogDebug($"[VANILLA GALDR] next.fullPathHash={((AnimatorStateInfo)(ref <next>5__4)).fullPathHash} next.shortNameHash={((AnimatorStateInfo)(ref <next>5__4)).shortNameHash} next.normalizedTime={((AnimatorStateInfo)(ref <next>5__4)).normalizedTime:0.00}");
						LogDebug(string.Format("[VANILLA GALDR] crafting={0} moving={1} forward_speed={2:0.00} sideway_speed={3:0.00}", <animator>5__2.GetInteger("crafting"), <animator>5__2.GetBool("moving"), <animator>5__2.GetFloat("forward_speed"), <animator>5__2.GetFloat("sideway_speed")));
						<clips>5__5 = <animator>5__2.GetCurrentAnimatorClipInfo(0);
						if (<clips>5__5 != null)
						{
							<i>5__6 = 0;
							while (<i>5__6 < <clips>5__5.Length)
							{
								if ((Object)(object)((AnimatorClipInfo)(ref <clips>5__5[<i>5__6])).clip != (Object)null)
								{
									LogDebug($"[VANILLA GALDR] clip={((Object)((AnimatorClipInfo)(ref <clips>5__5[<i>5__6])).clip).name} weight={((AnimatorClipInfo)(ref <clips>5__5[<i>5__6])).weight:0.00}");
								}
								int num = <i>5__6 + 1;
								<i>5__6 = num;
							}
						}
						<clips>5__5 = null;
					}
					catch (Exception ex)
					{
						<ex>5__7 = ex;
						LogDebug("[VANILLA GALDR] logger failed: " + <ex>5__7.Message);
					}
				}
				<>2__current = (object)new WaitForSeconds(0.1f);
				<>1__state = 1;
				return true;
			}
			LogDebug("[VANILLA GALDR] ---- state logging finished ----");
			_vanillaGaldrStateLoggerRoutine = null;
			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();
		}
	}

	public const string PluginGuid = "h4nz0.hardheimweaponreinforcement";

	public const string PluginName = "Hardheim Weapon Reinforcement";

	public const string PluginVersion = "1.0.0";

	internal const string GrindingWheelPrefabName = "forge_ext3";

	internal const string AnvilPrefabName = "forge_ext4";

	internal const string RuneTablePrefabName = "piece_magetable_ext";

	internal const string GaldrTablePrefabName = "piece_magetable";

	internal const string ReinforcementCustomDataKeyUntil = "hh_reinforcement_until_utc";

	internal const string ForgeCustomDataKeyUntil = "hh_forge_until_utc";

	internal const string BlessingCustomDataKeyUntil = "hh_blessing_until_utc";

	internal const string ReinforcementStatusEffectName = "HardheimWeaponReinforcementReinforcedSE";

	internal const string ForgeStatusEffectName = "HardheimWeaponReinforcementForgedSE";

	internal const string BlessingStatusEffectName = "HardheimWeaponReinforcementBlessedSE";

	internal const string StationProcessRpcName = "HH_WR_StationProcess";

	internal static HardheimWeaponReinforcementPlugin Instance;

	internal static Harmony HarmonyInstance;

	internal static ConfigEntry<bool> CfgEnabled;

	internal static ConfigEntry<float> CfgMaxBonusPercent;

	internal static ConfigEntry<int> CfgDurationMinutes;

	internal static ConfigEntry<float> CfgMinDurabilityPercent;

	internal static ConfigEntry<bool> CfgShowCenterMessages;

	internal static ConfigEntry<bool> CfgDebugLogging;

	internal static ConfigEntry<float> CfgProcessAnimationSeconds;

	internal static ConfigEntry<bool> CfgEnableProcessVfx;

	internal static ConfigEntry<bool> CfgEnableProcessSfx;

	internal static ConfigEntry<float> CfgReinforcementSparkInterval;

	internal static ConfigEntry<string> CfgReinforcementVfxPrefab;

	internal static ConfigEntry<string> CfgForgeVfxPrefab;

	internal static ConfigEntry<string> CfgBlessingVfxPrefab;

	internal static ConfigEntry<string> CfgReinforcementSfxPrefab;

	internal static ConfigEntry<string> CfgForgeSfxPrefab;

	internal static ConfigEntry<string> CfgBlessingSfxPrefab;

	internal static ConfigEntry<bool> CfgUseCustomReinforcementAudioFile;

	internal static ConfigEntry<string> CfgCustomReinforcementAudioFolderName;

	internal static ConfigEntry<string> CfgCustomReinforcementAudioFileName;

	internal static ConfigEntry<float> CfgCustomReinforcementAudioVolume;

	internal static ConfigEntry<bool> CfgUseCustomForgeAudioFile;

	internal static ConfigEntry<string> CfgCustomForgeAudioFolderName;

	internal static ConfigEntry<string> CfgCustomForgeAudioFileName;

	internal static ConfigEntry<float> CfgCustomForgeAudioVolume;

	internal static ConfigEntry<bool> CfgUseCustomBlessingAudioFile;

	internal static ConfigEntry<string> CfgCustomBlessingAudioFolderName;

	internal static ConfigEntry<string> CfgCustomBlessingAudioFileName;

	internal static ConfigEntry<float> CfgCustomBlessingAudioVolume;

	internal static float RuntimeMaxBonusPercent;

	internal static int RuntimeDurationMinutes;

	internal static float RuntimeMinDurabilityPercent;

	internal static float RuntimeProcessAnimationSeconds;

	internal static bool RuntimeEnableProcessVfx;

	internal static bool RuntimeEnableProcessSfx;

	internal static float RuntimeReinforcementSparkInterval;

	internal static string RuntimeReinforcementVfxPrefab;

	internal static string RuntimeForgeVfxPrefab;

	internal static string RuntimeBlessingVfxPrefab;

	internal static string RuntimeReinforcementSfxPrefab;

	internal static string RuntimeForgeSfxPrefab;

	internal static string RuntimeBlessingSfxPrefab;

	internal static bool RuntimeUseCustomReinforcementAudioFile;

	internal static string RuntimeCustomReinforcementAudioFolderName;

	internal static string RuntimeCustomReinforcementAudioFileName;

	internal static float RuntimeCustomReinforcementAudioVolume;

	internal static bool RuntimeUseCustomForgeAudioFile;

	internal static string RuntimeCustomForgeAudioFolderName;

	internal static string RuntimeCustomForgeAudioFileName;

	internal static float RuntimeCustomForgeAudioVolume;

	internal static bool RuntimeUseCustomBlessingAudioFile;

	internal static string RuntimeCustomBlessingAudioFolderName;

	internal static string RuntimeCustomBlessingAudioFileName;

	internal static float RuntimeCustomBlessingAudioVolume;

	private static float _nextStatusRefreshTime;

	private static SE_HardheimTimedBonus _activeVisibleStatus;

	private static ItemData _activeVisibleWeapon;

	private static BonusStationType _activeVisibleStatusType = BonusStationType.None;

	private static Coroutine _activeRoutine;

	private static long _activePlayerId;

	private static bool _isProcessInProgress;

	private static BonusStationType _activeProcessType = BonusStationType.None;

	private static AudioClip _customReinforcementClip;

	private static bool _customReinforcementClipLoadAttempted;

	private static AudioClip _customForgeClip;

	private static bool _customForgeClipLoadAttempted;

	private static AudioClip _customBlessingClip;

	private static bool _customBlessingClipLoadAttempted;

	private static GameObject _activeAudioObject;

	private static AudioSource _activeAudioSource;

	private static readonly HashSet<int> _registeredStationRpcObjects = new HashSet<int>();

	private static readonly Dictionary<long, Coroutine> _remoteProcessRoutines = new Dictionary<long, Coroutine>();

	private static readonly Dictionary<long, GameObject> _remoteAudioObjects = new Dictionary<long, GameObject>();

	private static bool _reinforcementAnimStartedThisProcess;

	private static bool _blessingAnimStartedThisProcess;

	private static bool _loggedForgeAnimatorParamsThisProcess;

	private static bool _loggedBlessingAnimatorParamsThisProcess;

	private static bool _emoteLoggingEnabled = false;

	private static string _resolvedForgeSfxPrefab;

	private static string _resolvedForgeVfxPrefab;

	private static string _resolvedBlessingSfxPrefab;

	private static string _resolvedBlessingVfxPrefab;

	internal static float _suppressBlessingCameraShakeUntil;

	private static Coroutine _vanillaGaldrStateLoggerRoutine;

	private static bool _blessingPoseLockedThisProcess;

	private static float _blessingPoseLockNormalizedTime = 0.35f;

	private static bool _blessingAnimatorDisabledThisProcess;

	private void Awake()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		Instance = this;
		CreateConfigs();
		ApplySyncedConfigToRuntime();
		EnsureCustomAudioFoldersExist();
		HarmonyInstance = new Harmony("h4nz0.hardheimweaponreinforcement");
		HarmonyInstance.PatchAll();
		SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized;
		LogAlways("Hardheim Weapon Reinforcement loaded.");
	}

	private void OnDestroy()
	{
		SynchronizationManager.OnConfigurationSynchronized -= OnConfigurationSynchronized;
		StopCustomAudioLoop();
		if (HarmonyInstance != null)
		{
			HarmonyInstance.UnpatchSelf();
		}
	}

	private void OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs args)
	{
		ApplySyncedConfigToRuntime();
		EnsureCustomAudioFoldersExist();
		if (args != null && args.InitialSynchronization)
		{
			LogAlways(string.Format("{0}: config sync complete. MaxBonusPercent={1}, DurationMinutes={2}, AnimationSeconds={3}", "Hardheim Weapon Reinforcement", RuntimeMaxBonusPercent.ToString("0.##", CultureInfo.InvariantCulture), RuntimeDurationMinutes, RuntimeProcessAnimationSeconds.ToString("0.##", CultureInfo.InvariantCulture)));
		}
		if (IsDebugLoggingEnabled())
		{
			LogDebug($"[CFGSYNC] InitialSynchronization={args != null && args.InitialSynchronization}");
			LogDebug($"[CFGSYNC] Enabled={IsModEnabled()}");
			LogDebug("[CFGSYNC] MaxBonusPercent=" + RuntimeMaxBonusPercent.ToString("0.##", CultureInfo.InvariantCulture));
			LogDebug($"[CFGSYNC] DurationMinutes={RuntimeDurationMinutes}");
			LogDebug("[CFGSYNC] MinDurabilityPercent=" + RuntimeMinDurabilityPercent.ToString("0.##", CultureInfo.InvariantCulture));
			LogDebug("[CFGSYNC] ProcessAnimationSeconds=" + RuntimeProcessAnimationSeconds.ToString("0.##", CultureInfo.InvariantCulture));
			LogDebug($"[CFGSYNC] EnableProcessVfx={RuntimeEnableProcessVfx}");
			LogDebug($"[CFGSYNC] EnableProcessSfx={RuntimeEnableProcessSfx}");
			LogDebug("[CFGSYNC] ReinforcementSparkInterval=" + RuntimeReinforcementSparkInterval.ToString("0.##", CultureInfo.InvariantCulture));
		}
	}

	private ConfigEntry<T> BindSyncedConfig<T>(string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues = null)
	{
		return ConfigFileExtensions.BindConfig<T>(((BaseUnityPlugin)this).Config, section, key, defaultValue, description, true, (int?)null, acceptableValues, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
	}

	private void CreateConfigs()
	{
		CfgEnabled = BindSyncedConfig("General", "Enabled", defaultValue: true, "A mod be- vagy kikapcsolása.");
		CfgMaxBonusPercent = BindSyncedConfig("Balance", "MaxBonusPercent", 5f, "Maximális sebzésbónusz százalékban teljesen ép fegyvernél.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f));
		CfgDurationMinutes = BindSyncedConfig("Balance", "DurationMinutes", 60, "A folyamat időtartama percben.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1440));
		CfgMinDurabilityPercent = BindSyncedConfig("Balance", "MinDurabilityPercent", 1f, "Ez alatt már nem jár bónusz.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f));
		CfgShowCenterMessages = BindSyncedConfig("UI", "ShowCenterMessages", defaultValue: true, "Mutasson-e középső üzenetet a folyamat elején és végén.");
		CfgDebugLogging = BindSyncedConfig("Debug", "DebugLogging", defaultValue: false, "Részletes debug logok.");
		CfgProcessAnimationSeconds = BindSyncedConfig("Animation", "ProcessAnimationSeconds", 10f, "A folyamat hossza másodpercben.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f));
		CfgEnableProcessVfx = BindSyncedConfig("Animation", "EnableProcessVfx", defaultValue: true, "Jelenjenek-e meg effektek.");
		CfgEnableProcessSfx = BindSyncedConfig("Animation", "EnableProcessSfx", defaultValue: true, "Szóljon-e hang a folyamat közben.");
		CfgReinforcementSparkInterval = BindSyncedConfig("Animation", "ReinforcementSparkInterval", 0.45f, "Milyen gyakran jelenjen meg effekt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f));
		CfgReinforcementVfxPrefab = BindSyncedConfig("Animation", "ReinforcementVfxPrefab", "vfx_HitSparks", "A köszörűkőnél használandó VFX prefab neve.");
		CfgForgeVfxPrefab = BindSyncedConfig("Animation", "ForgeVfxPrefab", "vfx_HitSparks", "A kovácsoláskor használandó fő VFX prefab neve.");
		CfgBlessingVfxPrefab = BindSyncedConfig("Animation", "BlessingVfxPrefab", "fx_DvergerMage_Support_start", "Az áldáskor használandó VFX prefab neve.");
		CfgReinforcementSfxPrefab = BindSyncedConfig("Animation", "ReinforcementSfxPrefab", "sfx_gui_craftitem", "A köszörűkőnél használandó SFX prefab fallbackként.");
		CfgForgeSfxPrefab = BindSyncedConfig("Animation", "ForgeSfxPrefab", "sfx_gui_repairitem_forge", "A kovácsoláskor használandó SFX prefab fallbackként.");
		CfgBlessingSfxPrefab = BindSyncedConfig("Animation", "BlessingSfxPrefab", "sfx_gui_craftitem", "Az áldáskor használandó SFX prefab fallbackként.");
		CfgUseCustomReinforcementAudioFile = BindSyncedConfig("Animation", "UseCustomReinforcementAudioFile", defaultValue: true, "Egyedi hangfájl használata a WeaponReinforcement mappából a köszörűkőhöz.");
		CfgCustomReinforcementAudioFolderName = BindSyncedConfig("Animation", "CustomReinforcementAudioFolderName", "WeaponReinforcement", "A plugin melletti mappa neve a köszörűkő hangjához.");
		CfgCustomReinforcementAudioFileName = BindSyncedConfig("Animation", "CustomReinforcementAudioFileName", "grinding.ogg", "A köszörűkő egyedi hangfájlja.");
		CfgCustomReinforcementAudioVolume = BindSyncedConfig("Animation", "CustomReinforcementAudioVolume", 0.9f, "A köszörűkő egyedi hang hangereje.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f));
		CfgUseCustomForgeAudioFile = BindSyncedConfig("Animation", "UseCustomForgeAudioFile", defaultValue: true, "Egyedi hangfájl használata a WeaponReinforcement mappából az üllőhöz.");
		CfgCustomForgeAudioFolderName = BindSyncedConfig("Animation", "CustomForgeAudioFolderName", "WeaponReinforcement", "A plugin melletti mappa neve az üllő hangjához.");
		CfgCustomForgeAudioFileName = BindSyncedConfig("Animation", "CustomForgeAudioFileName", "forge.ogg", "Az üllő egyedi hangfájlja.");
		CfgCustomForgeAudioVolume = BindSyncedConfig("Animation", "CustomForgeAudioVolume", 0.9f, "Az üllő egyedi hang hangereje.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f));
		CfgUseCustomBlessingAudioFile = BindSyncedConfig("Animation", "UseCustomBlessingAudioFile", defaultValue: true, "Egyedi hangfájl használata a WeaponReinforcement mappából az áldáshoz.");
		CfgCustomBlessingAudioFolderName = BindSyncedConfig("Animation", "CustomBlessingAudioFolderName", "WeaponReinforcement", "A plugin melletti mappa neve az áldás hangjához.");
		CfgCustomBlessingAudioFileName = BindSyncedConfig("Animation", "CustomBlessingAudioFileName", "wand.ogg", "Az áldás egyedi hangfájlja.");
		CfgCustomBlessingAudioVolume = BindSyncedConfig("Animation", "CustomBlessingAudioVolume", 0.9f, "Az áldás egyedi hang hangereje.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f));
	}

	internal static void ApplySyncedConfigToRuntime()
	{
		_emoteLoggingEnabled = IsDebugLoggingEnabled();
		RuntimeMaxBonusPercent = ((CfgMaxBonusPercent != null) ? CfgMaxBonusPercent.Value : 5f);
		RuntimeDurationMinutes = ((CfgDurationMinutes != null) ? CfgDurationMinutes.Value : 60);
		RuntimeMinDurabilityPercent = ((CfgMinDurabilityPercent != null) ? CfgMinDurabilityPercent.Value : 1f);
		RuntimeProcessAnimationSeconds = ((CfgProcessAnimationSeconds != null) ? Mathf.Clamp(CfgProcessAnimationSeconds.Value, 0.5f, 30f) : 10f);
		RuntimeEnableProcessVfx = CfgEnableProcessVfx != null && CfgEnableProcessVfx.Value;
		RuntimeEnableProcessSfx = CfgEnableProcessSfx != null && CfgEnableProcessSfx.Value;
		RuntimeReinforcementSparkInterval = ((CfgReinforcementSparkInterval != null) ? Mathf.Clamp(CfgReinforcementSparkInterval.Value, 0.05f, 2f) : 0.45f);
		RuntimeReinforcementVfxPrefab = ((CfgReinforcementVfxPrefab != null) ? CfgReinforcementVfxPrefab.Value : "vfx_HitSparks");
		RuntimeForgeVfxPrefab = ((CfgForgeVfxPrefab != null) ? CfgForgeVfxPrefab.Value : "vfx_HitSparks");
		RuntimeBlessingVfxPrefab = ((CfgBlessingVfxPrefab != null) ? CfgBlessingVfxPrefab.Value : "fx_DvergerMage_Support_start");
		RuntimeReinforcementSfxPrefab = ((CfgReinforcementSfxPrefab != null) ? CfgReinforcementSfxPrefab.Value : "sfx_gui_craftitem");
		RuntimeForgeSfxPrefab = ((CfgForgeSfxPrefab != null) ? CfgForgeSfxPrefab.Value : "sfx_gui_repairitem_forge");
		RuntimeBlessingSfxPrefab = ((CfgBlessingSfxPrefab != null) ? CfgBlessingSfxPrefab.Value : "sfx_gui_craftitem");
		RuntimeUseCustomReinforcementAudioFile = CfgUseCustomReinforcementAudioFile != null && CfgUseCustomReinforcementAudioFile.Value;
		RuntimeCustomReinforcementAudioFolderName = ((CfgCustomReinforcementAudioFolderName != null) ? CfgCustomReinforcementAudioFolderName.Value : "WeaponReinforcement");
		RuntimeCustomReinforcementAudioFileName = ((CfgCustomReinforcementAudioFileName != null) ? CfgCustomReinforcementAudioFileName.Value : "grinding.ogg");
		RuntimeCustomReinforcementAudioVolume = ((CfgCustomReinforcementAudioVolume != null) ? Mathf.Clamp01(CfgCustomReinforcementAudioVolume.Value) : 0.9f);
		RuntimeUseCustomForgeAudioFile = CfgUseCustomForgeAudioFile != null && CfgUseCustomForgeAudioFile.Value;
		RuntimeCustomForgeAudioFolderName = ((CfgCustomForgeAudioFolderName != null) ? CfgCustomForgeAudioFolderName.Value : "WeaponReinforcement");
		RuntimeCustomForgeAudioFileName = ((CfgCustomForgeAudioFileName != null) ? CfgCustomForgeAudioFileName.Value : "forge.ogg");
		RuntimeCustomForgeAudioVolume = ((CfgCustomForgeAudioVolume != null) ? Mathf.Clamp01(CfgCustomForgeAudioVolume.Value) : 0.9f);
		RuntimeUseCustomBlessingAudioFile = CfgUseCustomBlessingAudioFile != null && CfgUseCustomBlessingAudioFile.Value;
		RuntimeCustomBlessingAudioFolderName = ((CfgCustomBlessingAudioFolderName != null) ? CfgCustomBlessingAudioFolderName.Value : "WeaponReinforcement");
		RuntimeCustomBlessingAudioFileName = ((CfgCustomBlessingAudioFileName != null) ? CfgCustomBlessingAudioFileName.Value : "wand.ogg");
		RuntimeCustomBlessingAudioVolume = ((CfgCustomBlessingAudioVolume != null) ? Mathf.Clamp01(CfgCustomBlessingAudioVolume.Value) : 0.9f);
		_customReinforcementClip = null;
		_customReinforcementClipLoadAttempted = false;
		_customForgeClip = null;
		_customForgeClipLoadAttempted = false;
		_customBlessingClip = null;
		_customBlessingClipLoadAttempted = false;
		_resolvedForgeSfxPrefab = null;
		_resolvedForgeVfxPrefab = null;
		_resolvedBlessingSfxPrefab = null;
		_resolvedBlessingVfxPrefab = null;
		_suppressBlessingCameraShakeUntil = 0f;
	}

	internal static bool IsModEnabled()
	{
		return CfgEnabled != null && CfgEnabled.Value;
	}

	internal static void LogAlways(string msg)
	{
		if ((Object)(object)Instance != (Object)null)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)msg);
		}
	}

	internal static bool IsDebugLoggingEnabled()
	{
		return CfgDebugLogging != null && CfgDebugLogging.Value;
	}

	internal static void LogDebug(string msg)
	{
		if ((Object)(object)Instance != (Object)null && IsDebugLoggingEnabled())
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[DEBUG] " + msg));
		}
	}

	internal static bool IsUnarmedItem(ItemData item)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Invalid comparison between Unknown and I4
		if (item == null || item.m_shared == null)
		{
			return true;
		}
		try
		{
			if ((int)item.m_shared.m_skillType == 11)
			{
				return true;
			}
		}
		catch
		{
		}
		string text = string.Empty;
		try
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				text = (((Object)item.m_dropPrefab).name ?? string.Empty).ToLowerInvariant();
			}
		}
		catch
		{
		}
		if (text == "unarmed")
		{
			return true;
		}
		string a = string.Empty;
		try
		{
			if (!string.IsNullOrEmpty(item.m_shared.m_name))
			{
				a = item.m_shared.m_name.Trim();
			}
		}
		catch
		{
		}
		return string.Equals(a, "Unarmed", StringComparison.OrdinalIgnoreCase);
	}

	internal static bool IsStaffWeapon(ItemData item)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Invalid comparison between Unknown and I4
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Invalid comparison between Unknown and I4
		if (item == null || item.m_shared == null)
		{
			return false;
		}
		try
		{
			SkillType skillType = item.m_shared.m_skillType;
			if ((int)skillType == 9 || (int)skillType == 10)
			{
				return true;
			}
		}
		catch
		{
		}
		string text = string.Empty;
		try
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				text = (((Object)item.m_dropPrefab).name ?? string.Empty).ToLowerInvariant();
			}
		}
		catch
		{
		}
		if (text.Contains("staff"))
		{
			return true;
		}
		string text2 = string.Empty;
		try
		{
			text2 = (item.m_shared.m_name ?? string.Empty).ToLowerInvariant();
		}
		catch
		{
		}
		return text2.Contains("staff");
	}

	internal static bool IsElementalStaffWeapon(ItemData item)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Invalid comparison between Unknown and I4
		if (item == null || item.m_shared == null || IsUnarmedItem(item))
		{
			return false;
		}
		try
		{
			if ((int)item.m_shared.m_skillType == 9)
			{
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	internal static bool IsReinforcementWeapon(ItemData item)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Invalid comparison between Unknown and I4
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Invalid comparison between Unknown and I4
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Invalid comparison between Unknown and I4
		if (item == null || item.m_shared == null || IsUnarmedItem(item) || IsStaffWeapon(item))
		{
			return false;
		}
		SkillType skillType = item.m_shared.m_skillType;
		if ((int)skillType != 1 && (int)skillType != 2 && (int)skillType != 7)
		{
			return false;
		}
		string text = string.Empty;
		try
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				text = (((Object)item.m_dropPrefab).name ?? string.Empty).ToLowerInvariant();
			}
		}
		catch
		{
		}
		switch (text)
		{
		default:
			if (!(text == "knifeflint"))
			{
				return true;
			}
			goto case "swordwood";
		case "swordwood":
		case "club":
		case "axestone":
			return false;
		}
	}

	internal static bool IsBluntWeapon(ItemData item)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Invalid comparison between Unknown and I4
		if (item == null || item.m_shared == null || IsUnarmedItem(item) || IsStaffWeapon(item))
		{
			return false;
		}
		try
		{
			if ((int)item.m_shared.m_skillType != 3)
			{
				return false;
			}
		}
		catch
		{
			return false;
		}
		string text = string.Empty;
		try
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				text = (((Object)item.m_dropPrefab).name ?? string.Empty).ToLowerInvariant();
			}
		}
		catch
		{
		}
		if (text == "club" || text == "macewood")
		{
			return false;
		}
		return true;
	}

	internal static bool IsAnySupportedWeapon(ItemData item)
	{
		return IsReinforcementWeapon(item) || IsBluntWeapon(item) || IsElementalStaffWeapon(item);
	}

	internal static bool PrefabExists(string prefabName)
	{
		if (string.IsNullOrEmpty(prefabName) || (Object)(object)ZNetScene.instance == (Object)null)
		{
			return false;
		}
		try
		{
			return (Object)(object)ZNetScene.instance.GetPrefab(prefabName) != (Object)null;
		}
		catch
		{
			return false;
		}
	}

	internal static string ResolveForgeSfxPrefab()
	{
		if (!string.IsNullOrEmpty(_resolvedForgeSfxPrefab) && PrefabExists(_resolvedForgeSfxPrefab))
		{
			return _resolvedForgeSfxPrefab;
		}
		if (PrefabExists(RuntimeForgeSfxPrefab))
		{
			_resolvedForgeSfxPrefab = RuntimeForgeSfxPrefab;
			return _resolvedForgeSfxPrefab;
		}
		string[] array = new string[8] { "sfx_gui_repairitem_forge", "sfx_fist_metal_blocked", "sfx_craft", "sfx_hammer", "sfx_build_hammer", "sfx_anvil", "sfx_forge", "sfx_smelter_add" };
		for (int i = 0; i < array.Length; i++)
		{
			if (PrefabExists(array[i]))
			{
				_resolvedForgeSfxPrefab = array[i];
				return _resolvedForgeSfxPrefab;
			}
		}
		_resolvedForgeSfxPrefab = RuntimeReinforcementSfxPrefab;
		return _resolvedForgeSfxPrefab;
	}

	internal static string ResolveForgeVfxPrefab()
	{
		if (!string.IsNullOrEmpty(_resolvedForgeVfxPrefab) && PrefabExists(_resolvedForgeVfxPrefab))
		{
			return _resolvedForgeVfxPrefab;
		}
		if (PrefabExists(RuntimeForgeVfxPrefab))
		{
			_resolvedForgeVfxPrefab = RuntimeForgeVfxPrefab;
			return _resolvedForgeVfxPrefab;
		}
		string[] array = new string[7] { "vfx_HitSparks", "vfx_FireAddFuel", "vfx_kiln_addore", "vfx_torch_hit", "fx_fire", "vfx_smelter", "vfx_smelter_add" };
		for (int i = 0; i < array.Length; i++)
		{
			if (PrefabExists(array[i]))
			{
				_resolvedForgeVfxPrefab = array[i];
				return _resolvedForgeVfxPrefab;
			}
		}
		_resolvedForgeVfxPrefab = "vfx_HitSparks";
		return _resolvedForgeVfxPrefab;
	}

	internal static string ResolveBlessingSfxPrefab()
	{
		if (!string.IsNullOrEmpty(_resolvedBlessingSfxPrefab) && PrefabExists(_resolvedBlessingSfxPrefab))
		{
			return _resolvedBlessingSfxPrefab;
		}
		if (PrefabExists(RuntimeBlessingSfxPrefab))
		{
			_resolvedBlessingSfxPrefab = RuntimeBlessingSfxPrefab;
			return _resolvedBlessingSfxPrefab;
		}
		string[] array = new string[5] { "sfx_gui_craftitem", "sfx_magic_attack", "sfx_magic_staff_charge", "sfx_magic_staff_fireball_start", "sfx_magic_staff_charge_loop" };
		for (int i = 0; i < array.Length; i++)
		{
			if (PrefabExists(array[i]))
			{
				_resolvedBlessingSfxPrefab = array[i];
				return _resolvedBlessingSfxPrefab;
			}
		}
		_resolvedBlessingSfxPrefab = RuntimeForgeSfxPrefab;
		return _resolvedBlessingSfxPrefab;
	}

	internal static string ResolveBlessingVfxPrefab()
	{
		if (!string.IsNullOrEmpty(_resolvedBlessingVfxPrefab) && PrefabExists(_resolvedBlessingVfxPrefab))
		{
			return _resolvedBlessingVfxPrefab;
		}
		if (PrefabExists(RuntimeBlessingVfxPrefab))
		{
			_resolvedBlessingVfxPrefab = RuntimeBlessingVfxPrefab;
			return _resolvedBlessingVfxPrefab;
		}
		string[] array = new string[4] { "fx_DvergerMage_Support_start", "fx_DvergerMage_MistileSpawn", "fx_DvergerMage_Nova_ring", "fx_GP_Player" };
		for (int i = 0; i < array.Length; i++)
		{
			if (PrefabExists(array[i]))
			{
				_resolvedBlessingVfxPrefab = array[i];
				return _resolvedBlessingVfxPrefab;
			}
		}
		_resolvedBlessingVfxPrefab = "fx_GP_Player";
		return _resolvedBlessingVfxPrefab;
	}

	internal static void DumpAnimatorParameters(Animator animator)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)animator == (Object)null)
		{
			return;
		}
		try
		{
			AnimatorControllerParameter[] parameters = animator.parameters;
			if (parameters == null || parameters.Length == 0)
			{
				LogDebug("[ANIM] Animator has no parameters");
				return;
			}
			foreach (AnimatorControllerParameter val in parameters)
			{
				string name = val.name;
				AnimatorControllerParameterType type = val.type;
				LogDebug("[ANIM] Param: " + name + " | Type=" + ((object)(AnimatorControllerParameterType)(ref type)).ToString());
			}
		}
		catch (Exception ex)
		{
			LogDebug("[ANIM] DumpAnimatorParameters failed: " + ex.Message);
		}
	}

	internal static void LogBlessingEmoteParameters(Animator animator)
	{
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Invalid comparison between Unknown and I4
		if ((Object)(object)animator == (Object)null)
		{
			return;
		}
		string[] array = new string[28]
		{
			"emote_stop", "emote_wave", "emote_sit", "emote_sitchair", "emote_drink", "emote_challenge", "emote_cheer", "emote_nonono", "emote_thumbsup", "emote_point",
			"emote_blowkiss", "emote_bow", "emote_cower", "emote_cry", "emote_despair", "emote_flex", "emote_comehere", "emote_kneel", "emote_laugh", "emote_roar",
			"emote_shrug", "emote_headbang", "emote_dance", "emote_toast", "emote_rest", "emote_relax", "emote_vibe", "emote_loveyou"
		};
		foreach (string text in array)
		{
			try
			{
				AnimatorControllerParameter[] parameters = animator.parameters;
				bool flag = false;
				AnimatorControllerParameterType val = (AnimatorControllerParameterType)9;
				for (int j = 0; j < parameters.Length; j++)
				{
					if (parameters[j].name == text)
					{
						flag = true;
						val = parameters[j].type;
						break;
					}
				}
				if (flag)
				{
					if ((int)val == 4)
					{
						LogDebug("[BLESSING EMOTE] BOOL param: " + text + " value=" + animator.GetBool(text));
					}
					else
					{
						LogDebug("[BLESSING EMOTE] Trigger param: " + text);
					}
				}
			}
			catch (Exception ex)
			{
				LogDebug("[BLESSING EMOTE] Failed reading param " + text + ": " + ex.Message);
			}
		}
	}

	internal static string GetDataKeyForType(BonusStationType type)
	{
		return type switch
		{
			BonusStationType.Reinforcement => "hh_reinforcement_until_utc", 
			BonusStationType.Forge => "hh_forge_until_utc", 
			BonusStationType.Blessing => "hh_blessing_until_utc", 
			_ => string.Empty, 
		};
	}

	internal static string GetStatusNameForType(BonusStationType type)
	{
		return type switch
		{
			BonusStationType.Reinforcement => "Megélezve", 
			BonusStationType.Forge => "Megkovácsolva", 
			BonusStationType.Blessing => "Megáldva", 
			_ => string.Empty, 
		};
	}

	internal static string GetActionTextForType(BonusStationType type)
	{
		return type switch
		{
			BonusStationType.Reinforcement => "Élezés", 
			BonusStationType.Forge => "Kovácsolás", 
			BonusStationType.Blessing => "Áldás", 
			_ => string.Empty, 
		};
	}

	internal static string GetProgressTextForType(BonusStationType type)
	{
		return type switch
		{
			BonusStationType.Reinforcement => "Fegyver élezése...", 
			BonusStationType.Forge => "Fegyver kovácsolása...", 
			BonusStationType.Blessing => "Fegyver megáldása...", 
			_ => "Folyamat...", 
		};
	}

	internal static string GetInterruptedTextForType(BonusStationType type)
	{
		return type switch
		{
			BonusStationType.Reinforcement => "Az élezés megszakadt.", 
			BonusStationType.Forge => "A kovácsolás megszakadt.", 
			BonusStationType.Blessing => "Az áldás megszakadt.", 
			_ => "A folyamat megszakadt.", 
		};
	}

	internal static string GetInvalidWeaponTextForType(BonusStationType type)
	{
		return type switch
		{
			BonusStationType.Reinforcement => "Ezt nem élezheted meg.", 
			BonusStationType.Forge => "Ezt nem kovácsolhatod meg.", 
			BonusStationType.Blessing => "Ezt itt nem áldhatod meg.", 
			_ => "Ez a tárgy nem használható itt.", 
		};
	}

	internal static float GetCurrentBonusPercent(ItemData weapon, BonusStationType type)
	{
		if (!IsModEnabled() || weapon == null || type == BonusStationType.None)
		{
			return 0f;
		}
		if (type == BonusStationType.Reinforcement && !IsReinforcementWeapon(weapon))
		{
			return 0f;
		}
		if (type == BonusStationType.Forge && !IsBluntWeapon(weapon))
		{
			return 0f;
		}
		if (type == BonusStationType.Blessing && !IsElementalStaffWeapon(weapon))
		{
			return 0f;
		}
		string dataKeyForType = GetDataKeyForType(type);
		if (string.IsNullOrEmpty(dataKeyForType))
		{
			return 0f;
		}
		if (!TryGetUtcCustomData(weapon, dataKeyForType, out var utc))
		{
			return 0f;
		}
		if (DateTime.UtcNow >= utc)
		{
			ClearBonusData(weapon, type);
			return 0f;
		}
		float maxDurabilitySafe = GetMaxDurabilitySafe(weapon);
		if (maxDurabilitySafe <= 0f)
		{
			return 0f;
		}
		float num = Mathf.Clamp01(weapon.m_durability / maxDurabilitySafe);
		float num2 = Mathf.Clamp01(RuntimeMinDurabilityPercent / 100f);
		if (num < num2)
		{
			return 0f;
		}
		return Mathf.Max(0f, RuntimeMaxBonusPercent * num);
	}

	internal static float GetCurrentBonusMultiplier(ItemData weapon, BonusStationType type)
	{
		return 1f + GetCurrentBonusPercent(weapon, type) / 100f;
	}

	internal static float GetMaxDurabilitySafe(ItemData weapon)
	{
		if (weapon == null)
		{
			return 0f;
		}
		try
		{
			return weapon.GetMaxDurability();
		}
		catch
		{
			return (weapon.m_shared != null) ? weapon.m_shared.m_maxDurability : 0f;
		}
	}

	internal static void SetUtcCustomData(ItemData item, string key, DateTime utc)
	{
		if (item != null)
		{
			if (item.m_customData == null)
			{
				item.m_customData = new Dictionary<string, string>();
			}
			item.m_customData[key] = utc.Ticks.ToString(CultureInfo.InvariantCulture);
		}
	}

	internal static bool TryGetUtcCustomData(ItemData item, string key, out DateTime utc)
	{
		utc = DateTime.MinValue;
		if (item == null || item.m_customData == null)
		{
			return false;
		}
		if (!item.m_customData.TryGetValue(key, out var value))
		{
			return false;
		}
		if (!long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
		{
			return false;
		}
		try
		{
			utc = new DateTime(result, DateTimeKind.Utc);
			return true;
		}
		catch
		{
			return false;
		}
	}

	internal static void ClearBonusData(ItemData item, BonusStationType type)
	{
		if (item != null && item.m_customData != null)
		{
			string dataKeyForType = GetDataKeyForType(type);
			if (!string.IsNullOrEmpty(dataKeyForType))
			{
				item.m_customData.Remove(dataKeyForType);
			}
		}
	}

	internal static void CleanupExpiredBonusData(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return;
		}
		List<ItemData> allItems = inventory.GetAllItems();
		if (allItems == null)
		{
			return;
		}
		DateTime utcNow = DateTime.UtcNow;
		for (int i = 0; i < allItems.Count; i++)
		{
			ItemData val = allItems[i];
			if (val != null)
			{
				CleanupExpiredBonusDataOnItem(val, BonusStationType.Reinforcement, utcNow);
				CleanupExpiredBonusDataOnItem(val, BonusStationType.Forge, utcNow);
				CleanupExpiredBonusDataOnItem(val, BonusStationType.Blessing, utcNow);
			}
		}
	}

	internal static void CleanupExpiredBonusDataOnItem(ItemData item, BonusStationType type, DateTime nowUtc)
	{
		string dataKeyForType = GetDataKeyForType(type);
		if (!string.IsNullOrEmpty(dataKeyForType) && TryGetUtcCustomData(item, dataKeyForType, out var utc) && nowUtc >= utc)
		{
			ClearBonusData(item, type);
		}
	}

	internal static bool TryApplyBonusToWeapon(Player player, ItemData weapon, BonusStationType type, out string message)
	{
		message = string.Empty;
		if (!IsModEnabled())
		{
			message = "A funkció ki van kapcsolva.";
			return false;
		}
		if ((Object)(object)player == (Object)null || weapon == null)
		{
			message = "Nincs megfelelő fegyver a kezedben.";
			return false;
		}
		if (type == BonusStationType.Reinforcement && !IsReinforcementWeapon(weapon))
		{
			message = GetInvalidWeaponTextForType(type);
			return false;
		}
		if (type == BonusStationType.Forge && !IsBluntWeapon(weapon))
		{
			message = GetInvalidWeaponTextForType(type);
			return false;
		}
		if (type == BonusStationType.Blessing && !IsElementalStaffWeapon(weapon))
		{
			message = GetInvalidWeaponTextForType(type);
			return false;
		}
		float maxDurabilitySafe = GetMaxDurabilitySafe(weapon);
		if (maxDurabilitySafe <= 0f)
		{
			message = "Ennél a tárgynál nincs használható tartósság.";
			return false;
		}
		if (weapon.m_durability <= 0f)
		{
			message = "A fegyvert előbb javítsd meg.";
			return false;
		}
		DateTime utc = DateTime.UtcNow.AddMinutes(Math.Max(1, RuntimeDurationMinutes));
		SetUtcCustomData(weapon, GetDataKeyForType(type), utc);
		float currentBonusPercent = GetCurrentBonusPercent(weapon, type);
		message = string.Format(CultureInfo.InvariantCulture, "{0}. Jelenlegi bónusz: +{1:0.##}%", type switch
		{
			BonusStationType.Forge => "Fegyver megkovácsolva", 
			BonusStationType.Reinforcement => "Fegyver megélezve", 
			_ => "Fegyver megáldva", 
		}, currentBonusPercent);
		RefreshVisibleBonusStatus(player, forceImmediate: true);
		return true;
	}

	internal static string FormatTimeRemainingHMS(TimeSpan remaining)
	{
		if (remaining.TotalSeconds <= 0.0)
		{
			return "0:00:00";
		}
		int num = Mathf.Max(0, Mathf.FloorToInt((float)remaining.TotalHours));
		return string.Format(CultureInfo.InvariantCulture, "{0}:{1:00}:{2:00}", num, remaining.Minutes, remaining.Seconds);
	}

	internal static string GetTimeRemainingText(ItemData item, BonusStationType type)
	{
		if (item == null)
		{
			return string.Empty;
		}
		string dataKeyForType = GetDataKeyForType(type);
		if (string.IsNullOrEmpty(dataKeyForType))
		{
			return string.Empty;
		}
		if (!TryGetUtcCustomData(item, dataKeyForType, out var utc))
		{
			return string.Empty;
		}
		TimeSpan remaining = utc - DateTime.UtcNow;
		if (remaining.TotalSeconds <= 0.0)
		{
			ClearBonusData(item, type);
			return "0:00:00";
		}
		return FormatTimeRemainingHMS(remaining);
	}

	internal static string GetItemName(ItemData item)
	{
		if (item == null)
		{
			return "unknown";
		}
		if (item.m_shared != null && !string.IsNullOrEmpty(item.m_shared.m_name))
		{
			return item.m_shared.m_name;
		}
		return "unknown";
	}

	internal static string FormatDamageValue(float value)
	{
		if (Math.Abs(value - Mathf.Round(value)) < 0.01f)
		{
			return Mathf.RoundToInt(value).ToString(CultureInfo.InvariantCulture);
		}
		return value.ToString("0.#", CultureInfo.InvariantCulture);
	}

	internal static string[] GetTooltipLabelCandidates(string labelToken)
	{
		return labelToken switch
		{
			"$inventory_blunt" => new string[3] { "$inventory_blunt", "Blunt", "Zúzó" }, 
			"$inventory_slash" => new string[3] { "$inventory_slash", "Slash", "Vágó" }, 
			"$inventory_pierce" => new string[3] { "$inventory_pierce", "Pierce", "Szúró" }, 
			"$inventory_chop" => new string[3] { "$inventory_chop", "Chop", "Vágás" }, 
			"$inventory_pickaxe" => new string[3] { "$inventory_pickaxe", "Pickaxe", "Csákány" }, 
			"$inventory_fire" => new string[3] { "$inventory_fire", "Fire", "Tűz" }, 
			"$inventory_frost" => new string[3] { "$inventory_frost", "Frost", "Fagy" }, 
			"$inventory_lightning" => new string[3] { "$inventory_lightning", "Lightning", "Villám" }, 
			"$inventory_spirit" => new string[3] { "$inventory_spirit", "Spirit", "Szellem" }, 
			"$inventory_poison" => new string[3] { "$inventory_poison", "Poison", "Mérgezés" }, 
			_ => new string[1] { labelToken }, 
		};
	}

	internal static bool TryReplaceTooltipDamageLine(ref string tooltip, string labelToken, float baseDamage, float multiplier)
	{
		if (string.IsNullOrEmpty(tooltip) || string.IsNullOrEmpty(labelToken) || baseDamage <= 0f || multiplier <= 1f)
		{
			return false;
		}
		string text = "<color=green>" + FormatDamageValue(baseDamage * multiplier) + "</color>";
		string[] tooltipLabelCandidates = GetTooltipLabelCandidates(labelToken);
		foreach (string text2 in tooltipLabelCandidates)
		{
			if (!string.IsNullOrEmpty(text2))
			{
				string pattern = "(?m)^(?<prefix>\\s*" + Regex.Escape(text2) + ":\\s*)(?<value>(?:<color=[^>]+>)?\\d+(?:[.,]\\d+)?(?:</color>)?)";
				Match match = Regex.Match(tooltip, pattern, RegexOptions.CultureInvariant);
				if (match.Success)
				{
					tooltip = Regex.Replace(tooltip, pattern, "${prefix}" + text, RegexOptions.CultureInvariant);
					return true;
				}
			}
		}
		return false;
	}

	internal static string ApplyBonusDamageTooltip(string tooltip, ItemData item)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(tooltip) || item == null)
		{
			return tooltip;
		}
		DamageTypes damage = item.GetDamage();
		bool flag = false;
		float currentBonusMultiplier = GetCurrentBonusMultiplier(item, BonusStationType.Reinforcement);
		float currentBonusMultiplier2 = GetCurrentBonusMultiplier(item, BonusStationType.Forge);
		float currentBonusMultiplier3 = GetCurrentBonusMultiplier(item, BonusStationType.Blessing);
		if (currentBonusMultiplier > 1f)
		{
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_slash", damage.m_slash, currentBonusMultiplier);
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_pierce", damage.m_pierce, currentBonusMultiplier);
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_chop", damage.m_chop, currentBonusMultiplier);
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_pickaxe", damage.m_pickaxe, currentBonusMultiplier);
		}
		if (currentBonusMultiplier2 > 1f)
		{
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_blunt", damage.m_blunt, currentBonusMultiplier2);
		}
		if (currentBonusMultiplier3 > 1f)
		{
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_fire", damage.m_fire, currentBonusMultiplier3);
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_frost", damage.m_frost, currentBonusMultiplier3);
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_lightning", damage.m_lightning, currentBonusMultiplier3);
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_spirit", damage.m_spirit, currentBonusMultiplier3);
			TryReplaceTooltipDamageLine(ref tooltip, "$inventory_poison", damage.m_poison, currentBonusMultiplier3);
		}
		return tooltip;
	}

	internal static void AppendBonusTooltipInfo(ref string tooltip, ItemData item)
	{
		float currentBonusPercent = GetCurrentBonusPercent(item, BonusStationType.Reinforcement);
		float currentBonusPercent2 = GetCurrentBonusPercent(item, BonusStationType.Forge);
		float currentBonusPercent3 = GetCurrentBonusPercent(item, BonusStationType.Blessing);
		if (currentBonusPercent > 0f)
		{
			tooltip += string.Format(CultureInfo.InvariantCulture, "\n<color=green>Megélezve</color>\nSebzésbónusz: <color=green>+{0:0.##}%</color>\nHátralévő idő: <color=yellow>{1}</color>", currentBonusPercent, GetTimeRemainingText(item, BonusStationType.Reinforcement));
		}
		if (currentBonusPercent2 > 0f)
		{
			tooltip += string.Format(CultureInfo.InvariantCulture, "\n<color=green>Megkovácsolva</color>\nSebzésbónusz: <color=green>+{0:0.##}%</color>\nHátralévő idő: <color=yellow>{1}</color>", currentBonusPercent2, GetTimeRemainingText(item, BonusStationType.Forge));
		}
		if (currentBonusPercent3 > 0f)
		{
			tooltip += string.Format(CultureInfo.InvariantCulture, "\n<color=green>Megáldva</color>\nSebzésbónusz: <color=green>+{0:0.##}%</color>\nHátralévő idő: <color=yellow>{1}</color>", currentBonusPercent3, GetTimeRemainingText(item, BonusStationType.Blessing));
		}
	}

	internal static void EnsureCustomAudioFoldersExist()
	{
		EnsureFolderExists(GetCustomReinforcementAudioFolderPath());
		EnsureFolderExists(GetCustomForgeAudioFolderPath());
		EnsureFolderExists(GetCustomBlessingAudioFolderPath());
	}

	private static void EnsureFolderExists(string folder)
	{
		try
		{
			if (!string.IsNullOrEmpty(folder) && !Directory.Exists(folder))
			{
				Directory.CreateDirectory(folder);
			}
		}
		catch (Exception ex)
		{
			LogDebug("EnsureFolderExists failed: " + ex.Message);
		}
	}

	internal static string GetPluginFolderPath()
	{
		try
		{
			return Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location);
		}
		catch
		{
			return string.Empty;
		}
	}

	internal static string GetCustomReinforcementAudioFolderPath()
	{
		string pluginFolderPath = GetPluginFolderPath();
		if (string.IsNullOrEmpty(pluginFolderPath))
		{
			return string.Empty;
		}
		string path = ((!string.IsNullOrEmpty(RuntimeCustomReinforcementAudioFolderName)) ? RuntimeCustomReinforcementAudioFolderName : "WeaponReinforcement");
		return Path.Combine(pluginFolderPath, path);
	}

	internal static string GetCustomForgeAudioFolderPath()
	{
		string pluginFolderPath = GetPluginFolderPath();
		if (string.IsNullOrEmpty(pluginFolderPath))
		{
			return string.Empty;
		}
		string path = ((!string.IsNullOrEmpty(RuntimeCustomForgeAudioFolderName)) ? RuntimeCustomForgeAudioFolderName : "WeaponReinforcement");
		return Path.Combine(pluginFolderPath, path);
	}

	internal static string GetCustomBlessingAudioFolderPath()
	{
		string pluginFolderPath = GetPluginFolderPath();
		if (string.IsNullOrEmpty(pluginFolderPath))
		{
			return string.Empty;
		}
		string path = ((!string.IsNullOrEmpty(RuntimeCustomBlessingAudioFolderName)) ? RuntimeCustomBlessingAudioFolderName : "WeaponReinforcement");
		return Path.Combine(pluginFolderPath, path);
	}

	internal static string GetCustomReinforcementAudioPath()
	{
		string customReinforcementAudioFolderPath = GetCustomReinforcementAudioFolderPath();
		if (string.IsNullOrEmpty(customReinforcementAudioFolderPath))
		{
			return string.Empty;
		}
		string path = ((!string.IsNullOrEmpty(RuntimeCustomReinforcementAudioFileName)) ? RuntimeCustomReinforcementAudioFileName : "grinding.ogg");
		return Path.Combine(customReinforcementAudioFolderPath, path);
	}

	internal static string GetCustomForgeAudioPath()
	{
		string customForgeAudioFolderPath = GetCustomForgeAudioFolderPath();
		if (string.IsNullOrEmpty(customForgeAudioFolderPath))
		{
			return string.Empty;
		}
		string path = ((!string.IsNullOrEmpty(RuntimeCustomForgeAudioFileName)) ? RuntimeCustomForgeAudioFileName : "forge.ogg");
		return Path.Combine(customForgeAudioFolderPath, path);
	}

	internal static string GetCustomBlessingAudioPath()
	{
		string customBlessingAudioFolderPath = GetCustomBlessingAudioFolderPath();
		if (string.IsNullOrEmpty(customBlessingAudioFolderPath))
		{
			return string.Empty;
		}
		string path = ((!string.IsNullOrEmpty(RuntimeCustomBlessingAudioFileName)) ? RuntimeCustomBlessingAudioFileName : "wand.ogg");
		return Path.Combine(customBlessingAudioFolderPath, path);
	}

	internal static AudioType DetectAudioTypeFromPath(string path)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		return (AudioType)(Path.GetExtension(path).ToLowerInvariant() switch
		{
			".mp3" => 13, 
			".ogg" => 14, 
			".wav" => 20, 
			_ => 0, 
		});
	}

	[IteratorStateMachine(typeof(<EnsureCustomReinforcementClipLoaded>d__159))]
	internal static IEnumerator EnsureCustomReinforcementClipLoaded()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <EnsureCustomReinforcementClipLoaded>d__159(0);
	}

	[IteratorStateMachine(typeof(<EnsureCustomForgeClipLoaded>d__160))]
	internal static IEnumerator EnsureCustomForgeClipLoaded()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <EnsureCustomForgeClipLoaded>d__160(0);
	}

	[IteratorStateMachine(typeof(<EnsureCustomBlessingClipLoaded>d__161))]
	internal static IEnumerator EnsureCustomBlessingClipLoaded()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <EnsureCustomBlessingClipLoaded>d__161(0);
	}

	[IteratorStateMachine(typeof(<LoadClipCoroutine>d__162))]
	private static IEnumerator LoadClipCoroutine(string filePath, Action<AudioClip> onLoaded)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <LoadClipCoroutine>d__162(0)
		{
			filePath = filePath,
			onLoaded = onLoaded
		};
	}

	internal static void StartCustomAudioLoop(AudioClip clip, Vector3 position, float volume, string objectName)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)clip == (Object)null)
		{
			return;
		}
		try
		{
			StopCustomAudioLoop();
			_activeAudioObject = new GameObject(objectName);
			_activeAudioObject.transform.position = position;
			_activeAudioSource = _activeAudioObject.AddComponent<AudioSource>();
			_activeAudioSource.clip = clip;
			_activeAudioSource.loop = true;
			_activeAudioSource.spatialBlend = 1f;
			_activeAudioSource.volume = volume;
			_activeAudioSource.minDistance = 2f;
			_activeAudioSource.maxDistance = 16f;
			_activeAudioSource.rolloffMode = (AudioRolloffMode)1;
			_activeAudioSource.Play();
		}
		catch (Exception ex)
		{
			LogDebug("StartCustomAudioLoop failed: " + ex.Message);
		}
	}

	internal static void UpdateCustomAudioLoopPosition(Vector3 position)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)_activeAudioObject != (Object)null)
			{
				_activeAudioObject.transform.position = position;
			}
		}
		catch
		{
		}
	}

	internal static void StopCustomAudioLoop()
	{
		try
		{
			if ((Object)(object)_activeAudioSource != (Object)null)
			{
				_activeAudioSource.Stop();
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)_activeAudioObject != (Object)null)
			{
				Object.Destroy((Object)(object)_activeAudioObject);
			}
		}
		catch
		{
		}
		_activeAudioSource = null;
		_activeAudioObject = null;
	}

	[IteratorStateMachine(typeof(<StartProcessSound>d__166))]
	internal static IEnumerator StartProcessSound(Player player, Transform stationTransform, BonusStationType type)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <StartProcessSound>d__166(0)
		{
			player = player,
			stationTransform = stationTransform,
			type = type
		};
	}

	internal static GameObject TryGetPrefab(string prefabName)
	{
		if (string.IsNullOrEmpty(prefabName) || (Object)(object)ZNetScene.instance == (Object)null)
		{
			return null;
		}
		try
		{
			return ZNetScene.instance.GetPrefab(prefabName);
		}
		catch
		{
			return null;
		}
	}

	internal static void TrySpawnEffect(string prefabName, Vector3 position, Quaternion rotation)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(prefabName))
		{
			return;
		}
		try
		{
			GameObject val = TryGetPrefab(prefabName);
			if ((Object)(object)val == (Object)null)
			{
				LogDebug("[EFFECT] Prefab NOT found: " + prefabName);
			}
			else
			{
				Object.Instantiate<GameObject>(val, position, rotation);
			}
		}
		catch (Exception ex)
		{
			LogAlways("[EFFECT] TrySpawnEffect failed for " + prefabName + ": " + ex.Message);
		}
	}

	internal static void TrySpawnEffectVisualOnly(string prefabName, Vector3 position, Quaternion rotation, bool disableShake = true)
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(prefabName))
		{
			return;
		}
		try
		{
			GameObject val = TryGetPrefab(prefabName);
			if ((Object)(object)val == (Object)null)
			{
				LogDebug("[EFFECT] VisualOnly prefab NOT found: " + prefabName);
				return;
			}
			bool activeSelf = val.activeSelf;
			GameObject val2 = null;
			try
			{
				if (activeSelf)
				{
					val.SetActive(false);
				}
				val2 = Object.Instantiate<GameObject>(val, position, rotation);
			}
			finally
			{
				if ((Object)(object)val != (Object)null && activeSelf)
				{
					val.SetActive(true);
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			AudioSource[] componentsInChildren = val2.GetComponentsInChildren<AudioSource>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (!((Object)(object)componentsInChildren[i] == (Object)null))
				{
					componentsInChildren[i].Stop();
					componentsInChildren[i].playOnAwake = false;
					componentsInChildren[i].mute = true;
					componentsInChildren[i].volume = 0f;
					((Behaviour)componentsInChildren[i]).enabled = false;
				}
			}
			MonoBehaviour[] componentsInChildren2 = val2.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val3 in componentsInChildren2)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					string name = ((object)val3).GetType().Name;
					bool flag = name.IndexOf("sfx", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("zsfx", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("audio", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("sound", StringComparison.OrdinalIgnoreCase) >= 0;
					bool flag2 = disableShake && (name.IndexOf("shake", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("camera", StringComparison.OrdinalIgnoreCase) >= 0);
					if (flag || flag2)
					{
						((Behaviour)val3).enabled = false;
					}
				}
			}
			if (disableShake)
			{
				SuppressBlessingCameraShakeFor(1.25f);
			}
			val2.SetActive(true);
			if (disableShake)
			{
				SuppressBlessingCameraShakeFor(1.25f);
			}
		}
		catch (Exception ex)
		{
			LogAlways("[EFFECT] TrySpawnEffectVisualOnly failed for " + prefabName + ": " + ex.Message);
		}
	}

	internal static void SpawnForgeProcessEffects(Vector3 fxPos, Quaternion rotation)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		TrySpawnEffect("vfx_HitSparks", fxPos, rotation);
		if (PrefabExists("vfx_FireAddFuel"))
		{
			TrySpawnEffect("vfx_FireAddFuel", fxPos, rotation);
		}
		if (Time.frameCount % 30 == 0 && PrefabExists("vfx_kiln_addore"))
		{
			TrySpawnEffect("vfx_kiln_addore", fxPos, rotation);
		}
	}

	internal static void SpawnReinforcementProcessEffects(Vector3 fxPos, Quaternion rotation)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		TrySpawnEffect("vfx_HitSparks", fxPos, rotation);
		if (Time.frameCount % 25 == 0 && PrefabExists("vfx_arrowhit"))
		{
			TrySpawnEffect("vfx_arrowhit", fxPos, rotation);
		}
	}

	internal static Vector3 GetProcessEffectPosition(Player player, Transform stationTransform)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = stationTransform.position + Vector3.up * 1f;
		if ((Object)(object)player == (Object)null)
		{
			return val;
		}
		try
		{
			return Vector3.Lerp(val, ((Component)player).transform.position + ((Component)player).transform.forward * 0.6f + Vector3.up * 1.1f, 0.5f);
		}
		catch
		{
		}
		return val;
	}

	internal static bool IsGrindingWheelObject(GameObject go)
	{
		return (Object)(object)go != (Object)null && IsGrindingWheelObject((Component)(object)go.transform);
	}

	internal static bool IsGrindingWheelObject(Component component)
	{
		return IsNamedStationObject(component, "forge_ext3");
	}

	internal static bool IsAnvilObject(GameObject go)
	{
		return (Object)(object)go != (Object)null && IsAnvilObject((Component)(object)go.transform);
	}

	internal static bool IsAnvilObject(Component component)
	{
		return IsNamedStationObject(component, "forge_ext4");
	}

	internal static bool IsRuneTableObject(GameObject go)
	{
		return (Object)(object)go != (Object)null && IsRuneTableObject((Component)(object)go.transform);
	}

	internal static bool IsRuneTableObject(Component component)
	{
		return IsNamedStationObject(component, "piece_magetable_ext");
	}

	internal static bool IsGaldrTableObject(GameObject go)
	{
		return (Object)(object)go != (Object)null && IsGaldrTableObject((Component)(object)go.transform);
	}

	internal static bool IsGaldrTableObject(Component component)
	{
		return IsNamedStationObject(component, "piece_magetable");
	}

	internal static bool IsNamedStationObject(Component component, string prefabName)
	{
		if ((Object)(object)component == (Object)null || string.IsNullOrEmpty(prefabName))
		{
			return false;
		}
		Transform val = component.transform;
		while ((Object)(object)val != (Object)null)
		{
			string name = ((Object)((Component)val).gameObject).name;
			if (!string.IsNullOrEmpty(name))
			{
				name = name.Replace("(Clone)", string.Empty).Trim();
				if (string.Equals(name, prefabName, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			CraftingStation component2 = ((Component)val).GetComponent<CraftingStation>();
			if ((Object)(object)component2 != (Object)null)
			{
				string name2 = ((Object)((Component)component2).gameObject).name;
				if (!string.IsNullOrEmpty(name2))
				{
					name2 = name2.Replace("(Clone)", string.Empty).Trim();
					if (string.Equals(name2, prefabName, StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
				}
			}
			val = val.parent;
		}
		return false;
	}

	internal static bool CanProcessCurrentWeapon(Player player, BonusStationType type, out ItemData weapon)
	{
		weapon = null;
		if (!IsModEnabled() || (Object)(object)player == (Object)null || type == BonusStationType.None)
		{
			return false;
		}
		weapon = ((Humanoid)player).GetCurrentWeapon();
		if (weapon == null)
		{
			return false;
		}
		if (IsUnarmedItem(weapon))
		{
			weapon = null;
			return false;
		}
		switch (type)
		{
		case BonusStationType.Reinforcement:
			if (IsStaffWeapon(weapon) || !IsReinforcementWeapon(weapon))
			{
				weapon = null;
				return false;
			}
			break;
		case BonusStationType.Forge:
			if (IsStaffWeapon(weapon) || !IsBluntWeapon(weapon))
			{
				weapon = null;
				return false;
			}
			break;
		case BonusStationType.Blessing:
			if (!IsElementalStaffWeapon(weapon))
			{
				weapon = null;
				return false;
			}
			break;
		}
		float maxDurabilitySafe = GetMaxDurabilitySafe(weapon);
		if (maxDurabilitySafe <= 0f || weapon.m_durability <= 0f)
		{
			weapon = null;
			return false;
		}
		return true;
	}

	internal static string GetStationHoverText(Component component, BonusStationType type)
	{
		string text = type switch
		{
			BonusStationType.Forge => "Kovácsüllő", 
			BonusStationType.Reinforcement => "Köszörűkő", 
			_ => "Rúnaasztal", 
		};
		Piece val = (((Object)(object)component != (Object)null) ? component.GetComponent<Piece>() : null);
		if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.m_name))
		{
			text = val.m_name;
		}
		Player localPlayer = Player.m_localPlayer;
		if (!CanProcessCurrentWeapon(localPlayer, type, out var _))
		{
			return text;
		}
		if (_isProcessInProgress && localPlayer.GetPlayerID() == _activePlayerId && _activeProcessType == type)
		{
			return text + "\n<color=orange>" + GetActionTextForType(type) + " folyamatban...</color>";
		}
		return text + "\n[<color=yellow><b>E</b></color>] " + GetActionTextForType(type);
	}

	internal static bool StartProcess(Player player, ItemData weapon, Transform stationTransform, BonusStationType type)
	{
		if ((Object)(object)Instance == (Object)null || (Object)(object)player == (Object)null || weapon == null || (Object)(object)stationTransform == (Object)null || type == BonusStationType.None)
		{
			return false;
		}
		if (_isProcessInProgress)
		{
			return false;
		}
		LogDebug("[PROCESS] StartProcess type=" + type.ToString() + " weapon=" + GetItemName(weapon));
		_isProcessInProgress = true;
		_activePlayerId = player.GetPlayerID();
		_activeProcessType = type;
		_reinforcementAnimStartedThisProcess = false;
		_blessingAni