Decompiled source of CursedMaskMod v1.4.0

BepInEx\plugins\CursedMaskMod\CursedMaskMod.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CursedMaskMod;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using On;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CursedMaskMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Lethal Company Mod: Cursed Comedy Mask - Wear it to become invisible to monsters, but a death timer starts ticking.")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0")]
[assembly: AssemblyProduct("CursedMaskMod")]
[assembly: AssemblyTitle("CursedMaskMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class CursedMaskBehaviour : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <PermanentCurseSequence>d__84 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public CursedMaskBehaviour <>4__this;

		private bool <loc>5__2;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			int num = <>1__state;
			CursedMaskBehaviour cursedMaskBehaviour = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if ((Object)(object)cursedMaskBehaviour._wearingPlayer == (Object)null)
				{
					return false;
				}
				<loc>5__2 = (Object)(object)cursedMaskBehaviour._localPlayer != (Object)null && cursedMaskBehaviour._wearingPlayer == cursedMaskBehaviour._localPlayer;
				Debug.Log((object)"[CursedMask] Timer abgelaufen - PERMANENT VERFLUCHT!");
				if (<loc>5__2 && (Object)(object)cursedMaskBehaviour._purpleFilter != (Object)null)
				{
					((Graphic)cursedMaskBehaviour._purpleFilter).color = new Color(0.4f, 0f, 0.5f, 0.6f);
				}
				if (<loc>5__2 && (Object)(object)cursedMaskBehaviour._heartbeatSource != (Object)null)
				{
					cursedMaskBehaviour._heartbeatSource.volume = 1f;
					cursedMaskBehaviour._heartbeatSource.pitch = 3f;
				}
				if (<loc>5__2)
				{
					((MonoBehaviour)cursedMaskBehaviour).StartCoroutine(cursedMaskBehaviour.ScreenShake(0.6f, 0.15f));
				}
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				cursedMaskBehaviour._permanentCurse = true;
				cursedMaskBehaviour._timerActive = false;
				cursedMaskBehaviour.StopHeartbeat();
				if (<loc>5__2)
				{
					if ((Object)(object)cursedMaskBehaviour._timerText != (Object)null)
					{
						cursedMaskBehaviour._timerText.text = "PERMANENT";
						cursedMaskBehaviour._timerText.fontSize = 40;
						((Graphic)cursedMaskBehaviour._timerText).color = new Color(0.8f, 0.2f, 0.2f, 0.9f);
					}
					if ((Object)(object)cursedMaskBehaviour._cursedLabel != (Object)null)
					{
						cursedMaskBehaviour._cursedLabel.text = "MASKE FEST - Nähre dich Spielern um sie zu verfluchen";
						cursedMaskBehaviour._cursedLabel.fontSize = 18;
						((Graphic)cursedMaskBehaviour._cursedLabel).color = new Color(0.7f, 0.3f, 0.3f, 0.8f);
					}
					if ((Object)(object)cursedMaskBehaviour._searchHint != (Object)null)
					{
						cursedMaskBehaviour._searchHint.text = "Nähre dich anderen Spielern um den Fluch weiterzugeben!";
						((Graphic)cursedMaskBehaviour._searchHint).color = new Color(1f, 0.3f, 0.3f, 0.9f);
					}
					if ((Object)(object)cursedMaskBehaviour._purpleFilter != (Object)null)
					{
						((Graphic)cursedMaskBehaviour._purpleFilter).color = new Color(0.3f, 0.05f, 0.4f, 0.2f);
					}
				}
				Debug.Log((object)"[CursedMask] Spieler ist jetzt PERMANENT verflucht!");
				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 <ScreenShake>d__85 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public CursedMaskBehaviour <>4__this;

		public float mag;

		public float dur;

		private Transform <cam>5__2;

		private Vector3 <orig>5__3;

		private float <t>5__4;

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

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

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

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

		private bool MoveNext()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			int num = <>1__state;
			CursedMaskBehaviour cursedMaskBehaviour = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if ((Object)(object)cursedMaskBehaviour._localPlayer?.gameplayCamera == (Object)null)
				{
					return false;
				}
				<cam>5__2 = ((Component)cursedMaskBehaviour._localPlayer.gameplayCamera).transform;
				<orig>5__3 = <cam>5__2.localPosition;
				<t>5__4 = 0f;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (<t>5__4 < dur)
			{
				<cam>5__2.localPosition = <orig>5__3 + new Vector3(Random.Range(0f - mag, mag), Random.Range(0f - mag, mag), 0f);
				<t>5__4 += Time.deltaTime;
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			<cam>5__2.localPosition = <orig>5__3;
			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 <TakeoverAnimation>d__69 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public CursedMaskBehaviour <>4__this;

		private float <holdTime>5__2;

		private float <t>5__3;

		private float <fadeTime>5__4;

		private float <fadeT>5__5;

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

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

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

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

		private bool MoveNext()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			int num = <>1__state;
			CursedMaskBehaviour cursedMaskBehaviour = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				cursedMaskBehaviour._inAnimation = true;
				cursedMaskBehaviour._timerActive = false;
				cursedMaskBehaviour.PlayMaskSound();
				if ((Object)(object)cursedMaskBehaviour._localPlayer != (Object)null && (Object)(object)cursedMaskBehaviour._localPlayer.gameplayCamera != (Object)null)
				{
					((MonoBehaviour)cursedMaskBehaviour).StartCoroutine(cursedMaskBehaviour.ScreenShake(0.5f, 0.1f));
				}
				cursedMaskBehaviour._needsDrop = true;
				cursedMaskBehaviour._dropFrameDelay = 0;
				if ((Object)(object)cursedMaskBehaviour._blackout != (Object)null)
				{
					((Graphic)cursedMaskBehaviour._blackout).color = new Color(0f, 0f, 0f, 0.97f);
				}
				if ((Object)(object)cursedMaskBehaviour._takeoverText != (Object)null)
				{
					((Component)cursedMaskBehaviour._takeoverText).gameObject.SetActive(true);
					cursedMaskBehaviour._takeoverText.text = "Die Maske übernimmt dich...";
				}
				if ((Object)(object)cursedMaskBehaviour._purpleFilter != (Object)null)
				{
					((Graphic)cursedMaskBehaviour._purpleFilter).color = new Color(0f, 0f, 0f, 0f);
				}
				if ((Object)(object)cursedMaskBehaviour._timerText != (Object)null)
				{
					((Component)cursedMaskBehaviour._timerText).gameObject.SetActive(false);
				}
				if ((Object)(object)cursedMaskBehaviour._cursedLabel != (Object)null)
				{
					((Component)cursedMaskBehaviour._cursedLabel).gameObject.SetActive(false);
				}
				if ((Object)(object)cursedMaskBehaviour._transferPrompt != (Object)null)
				{
					((Component)cursedMaskBehaviour._transferPrompt).gameObject.SetActive(false);
				}
				if ((Object)(object)cursedMaskBehaviour._searchHint != (Object)null)
				{
					((Component)cursedMaskBehaviour._searchHint).gameObject.SetActive(false);
				}
				<holdTime>5__2 = 5f;
				<t>5__3 = 0f;
				goto IL_0276;
			case 1:
				<>1__state = -1;
				goto IL_0276;
			case 2:
				{
					<>1__state = -1;
					break;
				}
				IL_0276:
				if (<t>5__3 < <holdTime>5__2)
				{
					<t>5__3 += Time.deltaTime;
					if ((Object)(object)cursedMaskBehaviour._blackout != (Object)null)
					{
						float num2 = Mathf.Sin(<t>5__3 * 1.5f) * 0.03f;
						((Graphic)cursedMaskBehaviour._blackout).color = new Color(0.02f, 0f, 0.04f, 0.94f + num2);
					}
					if ((Object)(object)cursedMaskBehaviour._takeoverText != (Object)null)
					{
						float num3 = Mathf.Abs(Mathf.Sin(<t>5__3 * 1.2f));
						((Graphic)cursedMaskBehaviour._takeoverText).color = new Color(0.6f, 0.2f, 0.8f, Mathf.Lerp(0.4f, 1f, num3));
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)cursedMaskBehaviour._takeoverText != (Object)null)
				{
					((Component)cursedMaskBehaviour._takeoverText).gameObject.SetActive(false);
				}
				<fadeTime>5__4 = 1.5f;
				<fadeT>5__5 = 0f;
				break;
			}
			if (<fadeT>5__5 < <fadeTime>5__4)
			{
				<fadeT>5__5 += Time.deltaTime;
				float num4 = Mathf.Lerp(0.95f, 0f, <fadeT>5__5 / <fadeTime>5__4);
				if ((Object)(object)cursedMaskBehaviour._blackout != (Object)null)
				{
					((Graphic)cursedMaskBehaviour._blackout).color = new Color(0.02f, 0f, 0.04f, num4);
				}
				<>2__current = null;
				<>1__state = 2;
				return true;
			}
			if ((Object)(object)cursedMaskBehaviour._blackout != (Object)null)
			{
				((Graphic)cursedMaskBehaviour._blackout).color = new Color(0f, 0f, 0f, 0f);
			}
			cursedMaskBehaviour._inAnimation = false;
			cursedMaskBehaviour._timerActive = true;
			if ((Object)(object)cursedMaskBehaviour._purpleFilter != (Object)null)
			{
				((Graphic)cursedMaskBehaviour._purpleFilter).color = new Color(0.35f, 0.1f, 0.5f, 0.15f);
			}
			if ((Object)(object)cursedMaskBehaviour._timerText != (Object)null)
			{
				((Component)cursedMaskBehaviour._timerText).gameObject.SetActive(true);
			}
			if ((Object)(object)cursedMaskBehaviour._cursedLabel != (Object)null)
			{
				((Component)cursedMaskBehaviour._cursedLabel).gameObject.SetActive(true);
			}
			if ((Object)(object)cursedMaskBehaviour._searchHint != (Object)null)
			{
				((Component)cursedMaskBehaviour._searchHint).gameObject.SetActive(true);
				cursedMaskBehaviour._searchHint.text = "Finde einen Spieler um den Fluch loszuwerden!";
			}
			cursedMaskBehaviour.MuteVoice(mute: 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();
		}
	}

	private float _maxTime = 60f;

	private float _remainingTime = 60f;

	private bool _timerActive;

	private bool _cursed;

	private bool _inAnimation;

	private bool _permanentCurse;

	private const float INFECT_RANGE = 2.5f;

	private const float INFECT_COOLDOWN = 8f;

	private float _lastInfectTime;

	public bool AlreadyCursed;

	public bool IsTransferring;

	private float _transferCooldownEnd;

	private const float TRANSFER_COOLDOWN = 5f;

	private const float TRANSFER_RANGE = 3.5f;

	private PlayerControllerB _wearingPlayer;

	private PlayerControllerB _localPlayer;

	private GameObject _hudCanvas;

	private Text _timerText;

	private Text _cursedLabel;

	private Image _purpleFilter;

	private Image _blackout;

	private Text _takeoverText;

	private Text _transferPrompt;

	private Text _searchHint;

	private AudioSource _heartbeatSource;

	private AudioClip _heartbeatClip;

	private bool _voiceWasMuffled;

	private float _originalVoiceVolume = 1f;

	private float _originalIngameVoiceVolume = 1f;

	private bool _broadcastWasEnabled = true;

	private MonoBehaviour _voiceBroadcastTrigger;

	private Canvas _savedUsernameCanvas;

	private CanvasGroup _usernameCanvasGroup;

	private float _savedUsernameAlpha = 1f;

	private static Canvas _staticSavedCanvas;

	private static CanvasGroup _staticCanvasGroup;

	private static float _staticSavedAlpha = 1f;

	private static GameObject _staticBillboardGO;

	private bool _deathTriggered;

	private bool _intentionalDespawn;

	private bool _needsDrop;

	private int _dropFrameDelay;

	private HauntedMaskItem _maskItem;

	private static CursedMaskBehaviour _activeInstance = null;

	private static readonly BindingFlags BF = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static readonly BindingFlags BFS = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

	private bool _dissonanceWasMuted;

	private MonoBehaviour _dissonanceComms;

	private void Awake()
	{
		_maskItem = ((Component)this).GetComponent<HauntedMaskItem>();
		try
		{
			Type type = Type.GetType("CursedMaskMod.Plugin, CursedMaskMod");
			if (type != null)
			{
				FieldInfo field = type.GetField("cfgTimerDuration", BFS);
				if (field != null)
				{
					object value = field.GetValue(null);
					PropertyInfo property = value.GetType().GetProperty("Value");
					if (property != null)
					{
						_maxTime = (float)property.GetValue(value);
						_remainingTime = _maxTime;
					}
				}
			}
		}
		catch
		{
		}
		_heartbeatClip = GenerateHeartbeatClip();
	}

	private void Update()
	{
		if ((Object)(object)_localPlayer == (Object)null)
		{
			_localPlayer = GameNetworkManager.Instance?.localPlayerController;
		}
		if (_needsDrop)
		{
			_dropFrameDelay--;
			if (_dropFrameDelay <= 0)
			{
				_needsDrop = false;
				ExecuteDrop();
			}
		}
		bool flag = (Object)(object)_localPlayer != (Object)null && (Object)(object)_wearingPlayer != (Object)null && _wearingPlayer == _localPlayer;
		if (_cursed && (Object)(object)_wearingPlayer != (Object)null)
		{
			KeepNameHidden();
		}
		if (_permanentCurse && flag)
		{
			ReduceStamina();
			HandleInfectNearby();
			return;
		}
		if (_timerActive && !_inAnimation && (Object)(object)_wearingPlayer != (Object)null)
		{
			_remainingTime -= Time.deltaTime;
			if (flag)
			{
				UpdateHUD();
				UpdateHeartbeat();
				ReduceStamina();
			}
			if (_remainingTime <= 0f && !_deathTriggered)
			{
				_deathTriggered = true;
				((MonoBehaviour)this).StartCoroutine(PermanentCurseSequence());
			}
		}
		if (flag && _cursed && !_inAnimation && !_deathTriggered && !_permanentCurse)
		{
			HandleTransferInput();
		}
	}

	public void OnMaskEquipped(PlayerControllerB player)
	{
		if (!((Object)(object)player == (Object)null) && (!_cursed || !((Object)(object)_wearingPlayer != (Object)null) || _wearingPlayer != player) && !(Time.time < _transferCooldownEnd))
		{
			_wearingPlayer = player;
			_cursed = true;
			_deathTriggered = false;
			_transferCooldownEnd = Time.time + 5f;
			_activeInstance = this;
			try
			{
				Type.GetType("CursedMaskMod.Plugin, CursedMaskMod")?.GetField("CurseActive", BFS)?.SetValue(null, true);
			}
			catch
			{
			}
			SetMaskedPlayerRef(player);
			HidePlayerName(player);
			if ((Object)(object)_localPlayer != (Object)null && player == _localPlayer)
			{
				CreateHUD();
				((MonoBehaviour)this).StartCoroutine(TakeoverAnimation());
			}
			else
			{
				_timerActive = true;
			}
		}
	}

	public void OnMaskRemoved()
	{
		ClearMaskedPlayerRef();
		if ((Object)(object)_wearingPlayer != (Object)null)
		{
			ShowPlayerName(_wearingPlayer);
		}
		if (((Object)(object)_localPlayer != (Object)null && (Object)(object)_wearingPlayer != (Object)null && _wearingPlayer == _localPlayer) || (Object)(object)_hudCanvas != (Object)null)
		{
			DestroyHUD();
			MuteVoice(mute: false);
			StopHeartbeat();
		}
		_wearingPlayer = null;
		_timerActive = false;
		_cursed = false;
		_inAnimation = false;
		_permanentCurse = false;
		_deathTriggered = false;
		AlreadyCursed = false;
		try
		{
			Type.GetType("CursedMaskMod.Plugin, CursedMaskMod")?.GetField("CurseActive", BFS)?.SetValue(null, false);
		}
		catch
		{
		}
		if ((Object)(object)_activeInstance == (Object)(object)this)
		{
			_activeInstance = null;
		}
		Debug.Log((object)"[CursedMask] Fluch KOMPLETT aufgeraeumt");
	}

	public static void ActivateLocalCurse(PlayerControllerB player)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Expected O, but got Unknown
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		CursedMaskBehaviour cursedMaskBehaviour = _activeInstance;
		if ((Object)(object)cursedMaskBehaviour == (Object)null)
		{
			HauntedMaskItem val = FindMaskOnPlayer(player);
			if ((Object)(object)val != (Object)null)
			{
				cursedMaskBehaviour = ((Component)val).GetComponent<CursedMaskBehaviour>();
				if ((Object)(object)cursedMaskBehaviour == (Object)null)
				{
					cursedMaskBehaviour = ((Component)val).gameObject.AddComponent<CursedMaskBehaviour>();
				}
			}
			else
			{
				GameObject val2 = new GameObject("CursedMaskEffect_Standalone");
				Object.DontDestroyOnLoad((Object)val2);
				cursedMaskBehaviour = val2.AddComponent<CursedMaskBehaviour>();
			}
		}
		cursedMaskBehaviour.OnMaskEquipped(player);
	}

	public static void ActivateLocalCurseWithTime(PlayerControllerB player, float remainingTime)
	{
		//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_004c: Expected O, but got Unknown
		if (!((Object)(object)player == (Object)null))
		{
			if ((Object)(object)_activeInstance != (Object)null && _activeInstance._cursed)
			{
				_activeInstance.CleanupLocalEffects();
			}
			CursedMaskBehaviour cursedMaskBehaviour = _activeInstance;
			if ((Object)(object)cursedMaskBehaviour == (Object)null)
			{
				GameObject val = new GameObject("CursedMaskEffect_Transfer");
				Object.DontDestroyOnLoad((Object)val);
				cursedMaskBehaviour = val.AddComponent<CursedMaskBehaviour>();
			}
			cursedMaskBehaviour._remainingTime = remainingTime;
			cursedMaskBehaviour.OnMaskEquipped(player);
		}
	}

	public static void RemoveLocalCurse()
	{
		if ((Object)(object)_activeInstance != (Object)null && _activeInstance._cursed)
		{
			_activeInstance.OnMaskRemoved();
		}
	}

	private static HauntedMaskItem FindMaskOnPlayer(PlayerControllerB player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return null;
		}
		try
		{
			GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer;
			HauntedMaskItem val = (HauntedMaskItem)(object)((currentlyHeldObjectServer is HauntedMaskItem) ? currentlyHeldObjectServer : null);
			if (val != null)
			{
				return val;
			}
			if (player.ItemSlots != null)
			{
				GrabbableObject[] itemSlots = player.ItemSlots;
				foreach (GrabbableObject obj in itemSlots)
				{
					HauntedMaskItem val2 = (HauntedMaskItem)(object)((obj is HauntedMaskItem) ? obj : null);
					if (val2 != null)
					{
						return val2;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	public static void HidePlayerNameStatic(PlayerControllerB player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		try
		{
			FieldInfo field = typeof(PlayerControllerB).GetField("usernameCanvas", BF);
			if (field != null)
			{
				object? value = field.GetValue(player);
				_staticSavedCanvas = (Canvas)((value is Canvas) ? value : null);
				if ((Object)(object)_staticSavedCanvas != (Object)null)
				{
					((Behaviour)_staticSavedCanvas).enabled = false;
				}
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field2 = typeof(PlayerControllerB).GetField("usernameAlpha", BF);
			if (field2 != null)
			{
				object value2 = field2.GetValue(player);
				CanvasGroup val = (CanvasGroup)((value2 is CanvasGroup) ? value2 : null);
				if (val != null)
				{
					_staticCanvasGroup = val;
					_staticSavedAlpha = val.alpha;
					val.alpha = 0f;
				}
				else if (value2 is float)
				{
					float staticSavedAlpha = (float)value2;
					_staticSavedAlpha = staticSavedAlpha;
					field2.SetValue(player, 0f);
				}
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field3 = typeof(PlayerControllerB).GetField("usernameBillboard", BF);
			if (field3 != null)
			{
				object value3 = field3.GetValue(player);
				Component val2 = (Component)((value3 is Component) ? value3 : null);
				if (val2 != null && (Object)(object)val2.gameObject != (Object)null)
				{
					_staticBillboardGO = val2.gameObject;
					val2.gameObject.SetActive(false);
				}
				else
				{
					GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null);
					if (val3 != null)
					{
						_staticBillboardGO = val3;
						val3.SetActive(false);
					}
				}
			}
		}
		catch
		{
		}
		Debug.Log((object)("[CursedMask] Name STATISCH versteckt: " + player.playerUsername));
	}

	public static void ShowPlayerNameStatic(PlayerControllerB player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		try
		{
			if ((Object)(object)_staticSavedCanvas != (Object)null)
			{
				((Behaviour)_staticSavedCanvas).enabled = true;
				_staticSavedCanvas = null;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)_staticCanvasGroup != (Object)null)
			{
				_staticCanvasGroup.alpha = _staticSavedAlpha;
				_staticCanvasGroup = null;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)_staticBillboardGO != (Object)null)
			{
				_staticBillboardGO.SetActive(true);
				_staticBillboardGO = null;
			}
		}
		catch
		{
		}
		Debug.Log((object)("[CursedMask] Name STATISCH sichtbar: " + player.playerUsername));
	}

	public static void KeepNameHiddenStatic()
	{
		try
		{
			if ((Object)(object)_staticCanvasGroup != (Object)null)
			{
				_staticCanvasGroup.alpha = 0f;
			}
			if ((Object)(object)_staticSavedCanvas != (Object)null && ((Behaviour)_staticSavedCanvas).enabled)
			{
				((Behaviour)_staticSavedCanvas).enabled = false;
			}
		}
		catch
		{
		}
	}

	public static void CleanupAllCurses()
	{
		Debug.Log((object)"[CursedMask] === GLOBALES CLEANUP ===");
		try
		{
			CursedMaskBehaviour[] array = Object.FindObjectsOfType<CursedMaskBehaviour>();
			foreach (CursedMaskBehaviour cursedMaskBehaviour in array)
			{
				if ((Object)(object)cursedMaskBehaviour != (Object)null && cursedMaskBehaviour._cursed)
				{
					Debug.Log((object)"[CursedMask] Fluch aufgeraeumt auf Behaviour");
					cursedMaskBehaviour.OnMaskRemoved();
				}
			}
		}
		catch
		{
		}
		try
		{
			Type type = Type.GetType("CursedMaskMod.Plugin, CursedMaskMod");
			if (type != null)
			{
				FieldInfo field = type.GetField("MaskedPlayer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(null, null);
				}
				FieldInfo field2 = type.GetField("CurseActive", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 != null)
				{
					field2.SetValue(null, false);
				}
			}
		}
		catch
		{
		}
		_staticSavedCanvas = null;
		_staticCanvasGroup = null;
		_staticBillboardGO = null;
		_activeInstance = null;
		Debug.Log((object)"[CursedMask] === CLEANUP FERTIG ===");
	}

	private void ExecuteDrop()
	{
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB val = _wearingPlayer ?? _localPlayer;
		if ((Object)(object)val == (Object)null || (Object)(object)_maskItem == (Object)null)
		{
			return;
		}
		Debug.Log((object)"[CursedMask] === DROP ===");
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
		try
		{
			if (val.ItemSlots != null)
			{
				for (int i = 0; i < val.ItemSlots.Length; i++)
				{
					if (!((Object)(object)val.ItemSlots[i] != (Object)null) || val.ItemSlots[i] != _maskItem)
					{
						continue;
					}
					val.ItemSlots[i] = null;
					try
					{
						HUDManager instance = HUDManager.Instance;
						if ((Object)(object)instance != (Object)null && instance.itemSlotIcons != null && i < instance.itemSlotIcons.Length)
						{
							instance.itemSlotIcons[i].sprite = null;
							((Behaviour)instance.itemSlotIcons[i]).enabled = false;
						}
					}
					catch
					{
					}
					break;
				}
			}
		}
		catch
		{
		}
		((GrabbableObject)_maskItem).isHeld = false;
		((GrabbableObject)_maskItem).isPocketed = false;
		((GrabbableObject)_maskItem).heldByPlayerOnServer = false;
		((GrabbableObject)_maskItem).grabbable = true;
		((GrabbableObject)_maskItem).grabbableToEnemies = true;
		((GrabbableObject)_maskItem).playerHeldBy = null;
		((GrabbableObject)_maskItem).parentObject = null;
		try
		{
			FieldInfo field = typeof(HauntedMaskItem).GetField("previousPlayerHeldBy", bindingAttr);
			if (field != null)
			{
				field.SetValue(_maskItem, null);
			}
		}
		catch
		{
		}
		try
		{
			Transform val2 = StartOfRound.Instance?.propsContainer;
			((Component)_maskItem).transform.SetParent(val2, true);
			Vector3 val3 = ((Component)val).transform.position + ((Component)val).transform.forward * 1.5f;
			val3.y = ((Component)val).transform.position.y;
			((Component)_maskItem).transform.position = val3;
			((GrabbableObject)_maskItem).startFallingPosition = val3;
			((GrabbableObject)_maskItem).targetFloorPosition = val3;
			((GrabbableObject)_maskItem).floorYRot = -1;
			((GrabbableObject)_maskItem).fallTime = 0f;
		}
		catch
		{
		}
		try
		{
			((GrabbableObject)_maskItem).EnablePhysics(true);
		}
		catch
		{
		}
		try
		{
			Collider[] componentsInChildren = ((Component)_maskItem).GetComponentsInChildren<Collider>(true);
			foreach (Collider val4 in componentsInChildren)
			{
				if (!val4.enabled)
				{
					val4.enabled = true;
				}
			}
			Renderer[] componentsInChildren2 = ((Component)_maskItem).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val5 in componentsInChildren2)
			{
				if (!val5.enabled)
				{
					val5.enabled = true;
				}
			}
		}
		catch
		{
		}
		try
		{
			val.SetObjectAsNoLongerHeld(val.isInElevator, val.isInHangarShipRoom, ((Component)_maskItem).transform.position, (GrabbableObject)(object)_maskItem, -1);
		}
		catch
		{
		}
		int num = -1;
		GrabbableObject val6 = null;
		try
		{
			if (val.ItemSlots != null)
			{
				for (int k = 0; k < val.ItemSlots.Length; k++)
				{
					if ((Object)(object)val.ItemSlots[k] != (Object)null)
					{
						num = k;
						val6 = val.ItemSlots[k];
						break;
					}
				}
			}
		}
		catch
		{
		}
		if ((Object)(object)val6 != (Object)null)
		{
			try
			{
				val.currentlyHeldObjectServer = val6;
				val.currentlyHeldObject = val6;
				val.currentItemSlot = num;
				val.isHoldingObject = true;
				val.twoHanded = (Object)(object)val6.itemProperties != (Object)null && val6.itemProperties.twoHanded;
				MethodInfo method = typeof(PlayerControllerB).GetMethod("SwitchToItemSlot", bindingAttr);
				if (method != null)
				{
					method.Invoke(val, new object[2] { num, null });
				}
			}
			catch
			{
			}
			Debug.Log((object)$"[CursedMask] Gewechselt zu Slot {num}");
		}
		else
		{
			try
			{
				val.currentlyHeldObjectServer = null;
			}
			catch
			{
			}
			try
			{
				val.currentlyHeldObject = null;
			}
			catch
			{
			}
			try
			{
				FieldInfo field2 = typeof(PlayerControllerB).GetField("currentlyGrabbingObject", bindingAttr);
				if (field2 != null)
				{
					field2.SetValue(val, null);
				}
			}
			catch
			{
			}
			try
			{
				val.isHoldingObject = false;
			}
			catch
			{
			}
			try
			{
				val.twoHanded = false;
			}
			catch
			{
			}
			try
			{
				val.twoHandedAnimation = false;
			}
			catch
			{
			}
			try
			{
				val.carryWeight = 1f;
			}
			catch
			{
			}
			try
			{
				val.heldObjectServerCopy = null;
			}
			catch
			{
			}
			Debug.Log((object)"[CursedMask] Keine Items mehr, Haende leer");
		}
		try
		{
			if ((Object)(object)((GrabbableObject)_maskItem).itemProperties != (Object)null)
			{
				float num2 = ((GrabbableObject)_maskItem).itemProperties.weight - 1f;
				val.carryWeight = Mathf.Max(1f, val.carryWeight - num2);
			}
		}
		catch
		{
		}
		try
		{
			MethodInfo method2 = typeof(PlayerControllerB).GetMethod("SetSpecialGrabAnimationBool", bindingAttr);
			if (method2 != null)
			{
				method2.Invoke(val, new object[2] { false, _maskItem });
			}
			if ((Object)(object)((GrabbableObject)_maskItem).itemProperties != (Object)null && !string.IsNullOrEmpty(((GrabbableObject)_maskItem).itemProperties.grabAnim))
			{
				Animator playerBodyAnimator = val.playerBodyAnimator;
				if (playerBodyAnimator != null)
				{
					playerBodyAnimator.SetBool(((GrabbableObject)_maskItem).itemProperties.grabAnim, false);
				}
			}
			Animator playerBodyAnimator2 = val.playerBodyAnimator;
			if ((Object)(object)playerBodyAnimator2 != (Object)null)
			{
				playerBodyAnimator2.SetBool("cancelHolding", true);
				playerBodyAnimator2.SetBool("Grab", false);
				playerBodyAnimator2.SetBool("GrabValidated", false);
				playerBodyAnimator2.SetBool("GrabInvalidated", true);
				playerBodyAnimator2.SetBool("Hold", false);
				playerBodyAnimator2.SetBool("holdingObject", false);
				playerBodyAnimator2.SetTrigger("Throw");
			}
			val.isGrabbingObjectAnimation = false;
			val.activatingItem = false;
		}
		catch
		{
		}
		Debug.Log((object)"[CursedMask] === DROP FERTIG ===");
	}

	private void HidePlayerName(PlayerControllerB player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		try
		{
			FieldInfo field = typeof(PlayerControllerB).GetField("usernameCanvas", BF);
			if (field != null)
			{
				ref Canvas savedUsernameCanvas = ref _savedUsernameCanvas;
				object? value = field.GetValue(player);
				savedUsernameCanvas = (Canvas)((value is Canvas) ? value : null);
				if ((Object)(object)_savedUsernameCanvas != (Object)null)
				{
					((Behaviour)_savedUsernameCanvas).enabled = false;
				}
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field2 = typeof(PlayerControllerB).GetField("usernameAlpha", BF);
			if (field2 != null)
			{
				object value2 = field2.GetValue(player);
				CanvasGroup val = (CanvasGroup)((value2 is CanvasGroup) ? value2 : null);
				if (val != null)
				{
					_usernameCanvasGroup = val;
					_savedUsernameAlpha = val.alpha;
					val.alpha = 0f;
				}
				else if (value2 is float)
				{
					float savedUsernameAlpha = (float)value2;
					_savedUsernameAlpha = savedUsernameAlpha;
					field2.SetValue(player, 0f);
				}
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field3 = typeof(PlayerControllerB).GetField("usernameBillboard", BF);
			if (field3 != null)
			{
				object value3 = field3.GetValue(player);
				Component val2 = (Component)((value3 is Component) ? value3 : null);
				if (val2 != null && (Object)(object)val2.gameObject != (Object)null)
				{
					val2.gameObject.SetActive(false);
				}
				else
				{
					GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null);
					if (val3 != null)
					{
						val3.SetActive(false);
					}
				}
			}
		}
		catch
		{
		}
		HidePlayerNameStatic(player);
	}

	private void ShowPlayerName(PlayerControllerB player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		try
		{
			if ((Object)(object)_savedUsernameCanvas != (Object)null)
			{
				((Behaviour)_savedUsernameCanvas).enabled = true;
				_savedUsernameCanvas = null;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)_usernameCanvasGroup != (Object)null)
			{
				_usernameCanvasGroup.alpha = _savedUsernameAlpha;
				_usernameCanvasGroup = null;
			}
			else
			{
				FieldInfo field = typeof(PlayerControllerB).GetField("usernameAlpha", BF);
				if (field != null)
				{
					field.SetValue(player, _savedUsernameAlpha);
				}
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field2 = typeof(PlayerControllerB).GetField("usernameBillboard", BF);
			if (field2 != null)
			{
				object value = field2.GetValue(player);
				Component val = (Component)((value is Component) ? value : null);
				if (val != null && (Object)(object)val.gameObject != (Object)null)
				{
					val.gameObject.SetActive(true);
				}
				else
				{
					GameObject val2 = (GameObject)((value is GameObject) ? value : null);
					if (val2 != null)
					{
						val2.SetActive(true);
					}
				}
			}
		}
		catch
		{
		}
		ShowPlayerNameStatic(player);
	}

	private void KeepNameHidden()
	{
		try
		{
			if ((Object)(object)_usernameCanvasGroup != (Object)null)
			{
				_usernameCanvasGroup.alpha = 0f;
			}
			if ((Object)(object)_savedUsernameCanvas != (Object)null && ((Behaviour)_savedUsernameCanvas).enabled)
			{
				((Behaviour)_savedUsernameCanvas).enabled = false;
			}
		}
		catch
		{
		}
	}

	public bool IsOnCooldown()
	{
		return Time.time < _transferCooldownEnd;
	}

	private void CleanupLocalEffects()
	{
		DestroyHUD();
		MuteVoice(mute: false);
		StopHeartbeat();
		_cursed = false;
		_timerActive = false;
		_permanentCurse = false;
		_deathTriggered = false;
		_inAnimation = false;
		if ((Object)(object)_activeInstance == (Object)(object)this)
		{
			_activeInstance = null;
		}
	}

	private void HandleTransferInput()
	{
		//IL_002a: 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)
		if ((Object)(object)_localPlayer == (Object)null)
		{
			return;
		}
		PlayerControllerB val = FindNearestPlayer();
		UpdateTransferPrompt(val);
		bool flag = false;
		try
		{
			MovementActions movement = _localPlayer.playerActions.Movement;
			flag = ((MovementActions)(ref movement)).Interact.WasPressedThisFrame();
		}
		catch
		{
			try
			{
				flag = Input.GetKeyDown((KeyCode)101);
			}
			catch
			{
			}
		}
		if (flag && !((Object)(object)val == (Object)null) && !(Time.time < _transferCooldownEnd))
		{
			Debug.Log((object)("[CursedMask] E-Transfer an " + val.playerUsername + "!"));
			ulong actualClientId = _localPlayer.actualClientId;
			ulong actualClientId2 = val.actualClientId;
			float maxTime = _maxTime;
			CurseNetwork.ClientRequestTransfer(actualClientId, actualClientId2, maxTime);
		}
	}

	private void HandleInfectNearby()
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_localPlayer == (Object)null || Time.time < _lastInfectTime + 8f)
		{
			return;
		}
		try
		{
			PlayerControllerB[] array = Object.FindObjectsOfType<PlayerControllerB>();
			foreach (PlayerControllerB val in array)
			{
				if (!((Object)(object)val == (Object)null) && val != _localPlayer && !val.isPlayerDead && val.isPlayerControlled && !(Vector3.Distance(((Component)_localPlayer).transform.position, ((Component)val).transform.position) > 2.5f))
				{
					Debug.Log((object)("[CursedMask] INFECT! " + val.playerUsername + " ist zu nah!"));
					_lastInfectTime = Time.time;
					ulong actualClientId = _localPlayer.actualClientId;
					ulong actualClientId2 = val.actualClientId;
					CurseNetwork.ClientRequestTransfer(actualClientId, actualClientId2, _maxTime);
					break;
				}
			}
		}
		catch
		{
		}
	}

	private PlayerControllerB FindNearestPlayer()
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_localPlayer == (Object)null)
		{
			return null;
		}
		PlayerControllerB result = null;
		float num = 3.5f;
		try
		{
			PlayerControllerB[] array = Object.FindObjectsOfType<PlayerControllerB>();
			foreach (PlayerControllerB val in array)
			{
				if (!((Object)(object)val == (Object)null) && val != _localPlayer && !val.isPlayerDead && val.isPlayerControlled)
				{
					float num2 = Vector3.Distance(((Component)_localPlayer).transform.position, ((Component)val).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = val;
					}
				}
			}
		}
		catch
		{
		}
		return result;
	}

	private void UpdateTransferPrompt(PlayerControllerB nearest)
	{
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_transferPrompt == (Object)null))
		{
			bool flag = Time.time < _transferCooldownEnd;
			if ((Object)(object)nearest != (Object)null && !flag)
			{
				((Component)_transferPrompt).gameObject.SetActive(true);
				_transferPrompt.text = "[E] Fluch übertragen\n→ " + nearest.playerUsername;
				((Graphic)_transferPrompt).color = new Color(0.8f, 0.5f, 1f, 0.9f);
			}
			else if (flag)
			{
				((Component)_transferPrompt).gameObject.SetActive(true);
				_transferPrompt.text = $"Cooldown: {_transferCooldownEnd - Time.time:F1}s";
				((Graphic)_transferPrompt).color = new Color(0.6f, 0.3f, 0.3f, 0.7f);
			}
			else
			{
				((Component)_transferPrompt).gameObject.SetActive(false);
			}
		}
	}

	private void ReduceStamina()
	{
		if ((Object)(object)_localPlayer == (Object)null || !_cursed)
		{
			return;
		}
		try
		{
			FieldInfo field = typeof(PlayerControllerB).GetField("sprintMeter", BF);
			if (field != null && (float)field.GetValue(_localPlayer) > 0.5f)
			{
				field.SetValue(_localPlayer, 0.5f);
			}
		}
		catch
		{
		}
	}

	[IteratorStateMachine(typeof(<TakeoverAnimation>d__69))]
	private IEnumerator TakeoverAnimation()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <TakeoverAnimation>d__69(0)
		{
			<>4__this = this
		};
	}

	private void PlayMaskSound()
	{
		if ((Object)(object)_maskItem == (Object)null)
		{
			return;
		}
		try
		{
			if ((Object)(object)_maskItem.maskAudio != (Object)null && (Object)(object)_maskItem.maskAttachAudioLocal != (Object)null)
			{
				_maskItem.maskAudio.PlayOneShot(_maskItem.maskAttachAudioLocal, 1f);
			}
			else if ((Object)(object)_maskItem.maskAudio != (Object)null && (Object)(object)_maskItem.maskAttachAudio != (Object)null)
			{
				_maskItem.maskAudio.PlayOneShot(_maskItem.maskAttachAudio, 1f);
			}
		}
		catch
		{
		}
	}

	private void CreateHUD()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: 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_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0302: Unknown result type (might be due to invalid IL or missing references)
		//IL_0311: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_035d: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_hudCanvas != (Object)null))
		{
			_hudCanvas = new GameObject("CursedMaskHUD");
			Object.DontDestroyOnLoad((Object)(object)_hudCanvas);
			Canvas obj = _hudCanvas.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 1000;
			CanvasScaler obj2 = _hudCanvas.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			_blackout = MakeImage("Blackout", Vector2.zero, Vector2.one, new Color(0f, 0f, 0f, 0f));
			_takeoverText = MakeText("TakeoverText", 36, (TextAnchor)4, new Vector2(0.15f, 0.4f), new Vector2(0.85f, 0.6f), new Color(0.6f, 0.2f, 0.8f, 0f));
			((Component)_takeoverText).gameObject.SetActive(false);
			_purpleFilter = MakeImage("PurpleFilter", Vector2.zero, Vector2.one, new Color(0f, 0f, 0f, 0f));
			_timerText = MakeText("Timer", 48, (TextAnchor)1, new Vector2(0.3f, 0.85f), new Vector2(0.7f, 0.95f), new Color(0.7f, 0.3f, 0.9f, 0.9f));
			((Shadow)((Component)_timerText).gameObject.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.8f);
			((Component)_timerText).gameObject.SetActive(false);
			_cursedLabel = MakeText("Cursed", 24, (TextAnchor)1, new Vector2(0.35f, 0.95f), new Vector2(0.65f, 1f), new Color(0.6f, 0.2f, 0.8f, 0.6f));
			_cursedLabel.text = "V E R F L U C H T";
			((Shadow)((Component)_cursedLabel).gameObject.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.8f);
			((Component)_cursedLabel).gameObject.SetActive(false);
			_searchHint = MakeText("SearchHint", 18, (TextAnchor)2, new Vector2(0.55f, 0.72f), new Vector2(0.98f, 0.8f), new Color(1f, 0.7f, 0.3f, 0.9f));
			((Shadow)((Component)_searchHint).gameObject.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.8f);
			_searchHint.text = "Finde einen Spieler um den Fluch loszuwerden!";
			((Component)_searchHint).gameObject.SetActive(false);
			_transferPrompt = MakeText("Transfer", 22, (TextAnchor)2, new Vector2(0.62f, 0.86f), new Vector2(0.98f, 0.98f), new Color(0.8f, 0.5f, 1f, 0.9f));
			((Shadow)((Component)_transferPrompt).gameObject.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.8f);
			((Component)_transferPrompt).gameObject.SetActive(false);
		}
	}

	private Image MakeImage(string name, Vector2 anchorMin, Vector2 anchorMax, Color color)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0039: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(_hudCanvas.transform, false);
		Image val2 = val.AddComponent<Image>();
		((Graphic)val2).color = color;
		((Graphic)val2).raycastTarget = false;
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = anchorMin;
		component.anchorMax = anchorMax;
		component.offsetMin = Vector2.zero;
		component.offsetMax = Vector2.zero;
		return val2;
	}

	private Text MakeText(string name, int size, TextAnchor align, Vector2 anchorMin, Vector2 anchorMax, Color color)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(_hudCanvas.transform, false);
		Text val2 = val.AddComponent<Text>();
		val2.font = Font.CreateDynamicFontFromOSFont("Arial", size);
		val2.fontSize = size;
		val2.alignment = align;
		((Graphic)val2).color = color;
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = anchorMin;
		component.anchorMax = anchorMax;
		component.offsetMin = Vector2.zero;
		component.offsetMax = Vector2.zero;
		return val2;
	}

	private void UpdateHUD()
	{
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: 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)
		if ((Object)(object)_timerText == (Object)null)
		{
			return;
		}
		float num = Mathf.Max(0f, _remainingTime);
		_timerText.text = $"{(int)(num / 60f):D1}:{(int)(num % 60f):D2}.{(int)(num % 1f * 100f):D2}";
		if ((Object)(object)_searchHint != (Object)null && ((Component)_searchHint).gameObject.activeSelf)
		{
			float num2 = Mathf.Abs(Mathf.Sin(Time.time * 1.5f));
			((Graphic)_searchHint).color = new Color(1f, 0.7f, 0.3f, Mathf.Lerp(0.5f, 1f, num2));
		}
		if (!((Object)(object)_purpleFilter == (Object)null))
		{
			float num3 = 1f - Mathf.Clamp01(_remainingTime / _maxTime);
			if (_remainingTime < 10f)
			{
				float num4 = Mathf.Abs(Mathf.Sin(Time.time * 3f));
				((Graphic)_purpleFilter).color = new Color(0.5f, 0.05f, 0.3f, Mathf.Lerp(0.2f, 0.45f, num4));
				((Graphic)_timerText).color = new Color(1f, 0.2f, 0.2f, 1f);
				_timerText.fontSize = (int)Mathf.Lerp(48f, 72f, num4);
			}
			else if (_remainingTime < 30f)
			{
				((Graphic)_purpleFilter).color = new Color(0.4f, 0.08f, 0.45f, Mathf.Lerp(0.15f, 0.25f, num3));
				((Graphic)_timerText).color = new Color(0.9f, 0.4f, 0.9f, 0.9f);
				_timerText.fontSize = 52;
			}
			else
			{
				((Graphic)_purpleFilter).color = new Color(0.35f, 0.1f, 0.5f, 0.15f);
				((Graphic)_timerText).color = new Color(0.7f, 0.3f, 0.9f, 0.85f);
				_timerText.fontSize = 48;
			}
		}
	}

	private void DestroyHUD()
	{
		if ((Object)(object)_hudCanvas != (Object)null)
		{
			Object.Destroy((Object)(object)_hudCanvas);
			_hudCanvas = null;
			_timerText = null;
			_purpleFilter = null;
			_blackout = null;
			_takeoverText = null;
			_cursedLabel = null;
			_transferPrompt = null;
			_searchHint = null;
		}
	}

	private void UpdateHeartbeat()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		if (!((Object)(object)_heartbeatClip == (Object)null))
		{
			if ((Object)(object)_heartbeatSource == (Object)null && (Object)(object)_localPlayer?.gameplayCamera != (Object)null)
			{
				GameObject val = new GameObject("CursedMaskHB");
				val.transform.SetParent(((Component)_localPlayer.gameplayCamera).transform);
				_heartbeatSource = val.AddComponent<AudioSource>();
				_heartbeatSource.clip = _heartbeatClip;
				_heartbeatSource.loop = true;
				_heartbeatSource.spatialBlend = 0f;
				_heartbeatSource.volume = 0f;
				_heartbeatSource.Play();
			}
			if (!((Object)(object)_heartbeatSource == (Object)null))
			{
				float num = 1f - Mathf.Clamp01(_remainingTime / _maxTime);
				_heartbeatSource.volume = Mathf.Lerp(0.05f, 0.6f, num);
				_heartbeatSource.pitch = Mathf.Lerp(0.7f, 2f, num);
			}
		}
	}

	private void StopHeartbeat()
	{
		if ((Object)(object)_heartbeatSource != (Object)null)
		{
			_heartbeatSource.Stop();
			Object.Destroy((Object)(object)((Component)_heartbeatSource).gameObject);
			_heartbeatSource = null;
		}
	}

	private AudioClip GenerateHeartbeatClip()
	{
		int num = 22050;
		float num2 = 1f;
		int num3 = (int)((float)num * num2);
		float[] array = new float[num3];
		for (int i = 0; i < num3; i++)
		{
			float num4 = (float)i / (float)num;
			float num5 = ((num4 < 0.08f) ? (Mathf.Sin(num4 * 2f * MathF.PI * 55f) * Mathf.Exp((0f - num4) * 40f)) : 0f);
			float num6 = ((num4 > 0.15f && num4 < 0.23f) ? (Mathf.Sin((num4 - 0.15f) * 2f * MathF.PI * 50f) * Mathf.Exp((0f - (num4 - 0.15f)) * 45f) * 0.8f) : 0f);
			array[i] = Mathf.Clamp(num5 + num6, -1f, 1f);
		}
		AudioClip obj = AudioClip.Create("hb", num3, 1, num, false);
		obj.SetData(array, 0);
		return obj;
	}

	private void MuteVoice(bool mute)
	{
		try
		{
			Type type = Type.GetType("CursedMaskMod.Plugin, CursedMaskMod");
			if (type != null)
			{
				FieldInfo field = type.GetField("cfgVoiceMute", BFS);
				if (field != null)
				{
					object value = field.GetValue(null);
					PropertyInfo property = value.GetType().GetProperty("Value");
					if (property != null && !(bool)property.GetValue(value))
					{
						return;
					}
				}
			}
		}
		catch
		{
		}
		if ((Object)(object)_localPlayer == (Object)null)
		{
			return;
		}
		if (mute)
		{
			MuteDissonanceMic(mute: true);
			_voiceWasMuffled = _localPlayer.voiceMuffledByEnemy;
			_localPlayer.voiceMuffledByEnemy = true;
			if ((Object)(object)_localPlayer.currentVoiceChatAudioSource != (Object)null)
			{
				_originalVoiceVolume = _localPlayer.currentVoiceChatAudioSource.volume;
				_localPlayer.currentVoiceChatAudioSource.volume = 0f;
			}
			try
			{
				FieldInfo field2 = typeof(PlayerControllerB).GetField("currentVoiceChatIngameAudio", BF);
				if (field2 != null)
				{
					object? value2 = field2.GetValue(_localPlayer);
					AudioSource val = (AudioSource)((value2 is AudioSource) ? value2 : null);
					if ((Object)(object)val != (Object)null)
					{
						_originalIngameVoiceVolume = val.volume;
						val.volume = 0f;
					}
				}
			}
			catch
			{
			}
			DisableVoiceBroadcast(disable: true);
			Debug.Log((object)"[CursedMask] MIKROFON + Voice KOMPLETT gemutet (Dissonance IsMuted + Broadcast + Audio)");
			return;
		}
		MuteDissonanceMic(mute: false);
		_localPlayer.voiceMuffledByEnemy = _voiceWasMuffled;
		if ((Object)(object)_localPlayer.currentVoiceChatAudioSource != (Object)null)
		{
			_localPlayer.currentVoiceChatAudioSource.volume = _originalVoiceVolume;
		}
		try
		{
			FieldInfo field3 = typeof(PlayerControllerB).GetField("currentVoiceChatIngameAudio", BF);
			if (field3 != null)
			{
				object? value3 = field3.GetValue(_localPlayer);
				AudioSource val2 = (AudioSource)((value3 is AudioSource) ? value3 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.volume = _originalIngameVoiceVolume;
				}
			}
		}
		catch
		{
		}
		DisableVoiceBroadcast(disable: false);
		Debug.Log((object)"[CursedMask] MIKROFON + Voice WIEDERHERGESTELLT");
	}

	private void MuteDissonanceMic(bool mute)
	{
		try
		{
			if ((Object)(object)_dissonanceComms == (Object)null)
			{
				MonoBehaviour[] array = Object.FindObjectsOfType<MonoBehaviour>();
				foreach (MonoBehaviour val in array)
				{
					if ((Object)(object)val != (Object)null && ((object)val).GetType().FullName == "Dissonance.DissonanceComms")
					{
						_dissonanceComms = val;
						Debug.Log((object)("[CursedMask] DissonanceComms gefunden: " + ((Object)((Component)val).gameObject).name));
						break;
					}
				}
			}
			if ((Object)(object)_dissonanceComms != (Object)null)
			{
				PropertyInfo property = ((object)_dissonanceComms).GetType().GetProperty("IsMuted");
				if (property != null)
				{
					if (mute)
					{
						_dissonanceWasMuted = (bool)property.GetValue(_dissonanceComms);
						property.SetValue(_dissonanceComms, true);
						Debug.Log((object)"[CursedMask] DissonanceComms.IsMuted = TRUE (Mikrofon AUS)");
					}
					else
					{
						property.SetValue(_dissonanceComms, _dissonanceWasMuted);
						Debug.Log((object)$"[CursedMask] DissonanceComms.IsMuted = {_dissonanceWasMuted} (wiederhergestellt)");
					}
				}
			}
			else
			{
				Debug.LogWarning((object)"[CursedMask] DissonanceComms NICHT gefunden - Mic-Mute Fallback aktiv");
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[CursedMask] DissonanceComms Mute Fehler: " + ex.Message));
		}
	}

	private void DisableVoiceBroadcast(bool disable)
	{
		if ((Object)(object)_localPlayer == (Object)null)
		{
			return;
		}
		try
		{
			if ((Object)(object)_voiceBroadcastTrigger == (Object)null)
			{
				MonoBehaviour[] componentsInChildren = ((Component)_localPlayer).GetComponentsInChildren<MonoBehaviour>(true);
				foreach (MonoBehaviour val in componentsInChildren)
				{
					if ((Object)(object)val != (Object)null && ((object)val).GetType().Name.Contains("VoiceBroadcast"))
					{
						_voiceBroadcastTrigger = val;
						_broadcastWasEnabled = ((Behaviour)val).enabled;
						break;
					}
				}
				if ((Object)(object)_voiceBroadcastTrigger == (Object)null)
				{
					componentsInChildren = Object.FindObjectsOfType<MonoBehaviour>();
					foreach (MonoBehaviour val2 in componentsInChildren)
					{
						if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name.Contains("VoiceBroadcast"))
						{
							_voiceBroadcastTrigger = val2;
							_broadcastWasEnabled = ((Behaviour)val2).enabled;
							Debug.Log((object)("[CursedMask] VoiceBroadcastTrigger GLOBAL gefunden: " + ((Object)((Component)val2).gameObject).name));
							break;
						}
					}
				}
			}
			if ((Object)(object)_voiceBroadcastTrigger != (Object)null)
			{
				if (disable)
				{
					_broadcastWasEnabled = ((Behaviour)_voiceBroadcastTrigger).enabled;
					((Behaviour)_voiceBroadcastTrigger).enabled = false;
					Debug.Log((object)"[CursedMask] VoiceBroadcast DEAKTIVIERT");
				}
				else
				{
					((Behaviour)_voiceBroadcastTrigger).enabled = _broadcastWasEnabled;
					Debug.Log((object)"[CursedMask] VoiceBroadcast AKTIVIERT");
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[CursedMask] Voice-Broadcast Fehler: " + ex.Message));
		}
	}

	[IteratorStateMachine(typeof(<PermanentCurseSequence>d__84))]
	private IEnumerator PermanentCurseSequence()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PermanentCurseSequence>d__84(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<ScreenShake>d__85))]
	private IEnumerator ScreenShake(float dur, float mag)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ScreenShake>d__85(0)
		{
			<>4__this = this,
			dur = dur,
			mag = mag
		};
	}

	private void SetMaskedPlayerRef(PlayerControllerB p)
	{
		try
		{
			Type.GetType("CursedMaskMod.Plugin, CursedMaskMod")?.GetField("MaskedPlayer", BFS)?.SetValue(null, p);
		}
		catch
		{
		}
	}

	private void ClearMaskedPlayerRef()
	{
		try
		{
			Type.GetType("CursedMaskMod.Plugin, CursedMaskMod")?.GetField("MaskedPlayer", BFS)?.SetValue(null, null);
		}
		catch
		{
		}
	}

	private void OnDestroy()
	{
		OnMaskRemoved();
		DestroyHUD();
		StopHeartbeat();
	}

	private void OnDisable()
	{
		if (!_intentionalDespawn && _cursed)
		{
			Debug.Log((object)"[CursedMask] OnDisable → Fluch aufräumen");
			OnMaskRemoved();
		}
	}
}
namespace CursedMaskMod
{
	internal static class CurseNetwork
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnCurseReceived;

			public static HandleNamedMessageDelegate <1>__OnTransferReceived;

			public static HandleNamedMessageDelegate <2>__OnCleanReceived;

			public static HandleNamedMessageDelegate <3>__OnReqTransferReceived;

			public static HandleNamedMessageDelegate <4>__OnReqCurseReceived;
		}

		private const string MSG_CURSE = "CM_Curse";

		private const string MSG_TRANSFER = "CM_Transfer";

		private const string MSG_CLEAN = "CM_Clean";

		private const string MSG_REQT = "CM_ReqT";

		private const string MSG_REQCURSE = "CM_ReqC";

		private static bool _registered;

		internal static bool IsHost
		{
			get
			{
				try
				{
					return (Object)(object)NetworkManager.Singleton != (Object)null && (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer);
				}
				catch
				{
					return true;
				}
			}
		}

		internal static bool Registered => _registered;

		internal static void Register()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			if (_registered)
			{
				return;
			}
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				CustomMessagingManager val = ((singleton != null) ? singleton.CustomMessagingManager : null);
				if (val != null)
				{
					object obj = <>O.<0>__OnCurseReceived;
					if (obj == null)
					{
						HandleNamedMessageDelegate val2 = OnCurseReceived;
						<>O.<0>__OnCurseReceived = val2;
						obj = (object)val2;
					}
					val.RegisterNamedMessageHandler("CM_Curse", (HandleNamedMessageDelegate)obj);
					object obj2 = <>O.<1>__OnTransferReceived;
					if (obj2 == null)
					{
						HandleNamedMessageDelegate val3 = OnTransferReceived;
						<>O.<1>__OnTransferReceived = val3;
						obj2 = (object)val3;
					}
					val.RegisterNamedMessageHandler("CM_Transfer", (HandleNamedMessageDelegate)obj2);
					object obj3 = <>O.<2>__OnCleanReceived;
					if (obj3 == null)
					{
						HandleNamedMessageDelegate val4 = OnCleanReceived;
						<>O.<2>__OnCleanReceived = val4;
						obj3 = (object)val4;
					}
					val.RegisterNamedMessageHandler("CM_Clean", (HandleNamedMessageDelegate)obj3);
					object obj4 = <>O.<3>__OnReqTransferReceived;
					if (obj4 == null)
					{
						HandleNamedMessageDelegate val5 = OnReqTransferReceived;
						<>O.<3>__OnReqTransferReceived = val5;
						obj4 = (object)val5;
					}
					val.RegisterNamedMessageHandler("CM_ReqT", (HandleNamedMessageDelegate)obj4);
					object obj5 = <>O.<4>__OnReqCurseReceived;
					if (obj5 == null)
					{
						HandleNamedMessageDelegate val6 = OnReqCurseReceived;
						<>O.<4>__OnReqCurseReceived = val6;
						obj5 = (object)val6;
					}
					val.RegisterNamedMessageHandler("CM_ReqC", (HandleNamedMessageDelegate)obj5);
					_registered = true;
					Plugin.Logger.LogInfo((object)"[CurseNet] Netzwerk-Handler registriert!");
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("[CurseNet] Register Fehler: " + ex.Message));
			}
		}

		internal static void Unregister()
		{
			if (!_registered)
			{
				return;
			}
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				CustomMessagingManager val = ((singleton != null) ? singleton.CustomMessagingManager : null);
				if (val != null)
				{
					val.UnregisterNamedMessageHandler("CM_Curse");
					val.UnregisterNamedMessageHandler("CM_Transfer");
					val.UnregisterNamedMessageHandler("CM_Clean");
					val.UnregisterNamedMessageHandler("CM_ReqT");
					val.UnregisterNamedMessageHandler("CM_ReqC");
				}
			}
			catch
			{
			}
			_registered = false;
			Plugin.Logger.LogInfo((object)"[CurseNet] Netzwerk-Handler entfernt.");
		}

		internal static void HostBroadcastCurse(ulong playerClientId)
		{
			if (IsHost)
			{
				SendToAll("CM_Curse", delegate(FastBufferWriter w)
				{
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref playerClientId, default(ForPrimitives));
				});
				ApplyCurseLocally(playerClientId);
			}
		}

		internal static void HostBroadcastTransfer(ulong fromId, ulong toId, float remainingTime)
		{
			if (IsHost)
			{
				SendToAll("CM_Transfer", delegate(FastBufferWriter w)
				{
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					//IL_0026: 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_003c: Unknown result type (might be due to invalid IL or missing references)
					((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref fromId, default(ForPrimitives));
					((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref toId, default(ForPrimitives));
					((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref remainingTime, default(ForPrimitives));
				});
				ApplyTransferLocally(fromId, toId, remainingTime);
			}
		}

		internal static void HostBroadcastCleanup()
		{
			if (IsHost)
			{
				SendToAll("CM_Clean", delegate(FastBufferWriter w)
				{
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					byte b = 0;
					((FastBufferWriter)(ref w)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
				});
			}
		}

		internal static void ClientNotifyCurse(ulong playerClientId)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost)
			{
				HostBroadcastCurse(playerClientId);
			}
			else if (_registered)
			{
				try
				{
					FastBufferWriter val = default(FastBufferWriter);
					((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1);
					((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref playerClientId, default(ForPrimitives));
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("CM_ReqC", 0uL, val, (NetworkDelivery)3);
					((FastBufferWriter)(ref val)).Dispose();
					Debug.Log((object)$"[CurseNet] Host informiert: Spieler {playerClientId} ist verflucht");
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[CurseNet] ClientNotifyCurse Fehler: " + ex.Message));
				}
			}
		}

		internal static void ClientRequestTransfer(ulong fromId, ulong toId, float remainingTime)
		{
			//IL_002a: 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)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost)
			{
				HostBroadcastTransfer(fromId, toId, remainingTime);
			}
			else if (_registered)
			{
				try
				{
					FastBufferWriter val = default(FastBufferWriter);
					((FastBufferWriter)(ref val))..ctor(20, (Allocator)2, -1);
					((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref fromId, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref toId, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref remainingTime, default(ForPrimitives));
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("CM_ReqT", 0uL, val, (NetworkDelivery)3);
					((FastBufferWriter)(ref val)).Dispose();
					Debug.Log((object)$"[CurseNet] Transfer-Request an Host gesendet: {fromId}→{toId}");
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[CurseNet] RequestTransfer Fehler: " + ex.Message));
				}
			}
		}

		private static void OnCurseReceived(ulong senderId, FastBufferReader reader)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost)
			{
				return;
			}
			try
			{
				ulong playerClientId = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref playerClientId, default(ForPrimitives));
				ApplyCurseLocally(playerClientId);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[CurseNet] OnCurse Fehler: " + ex.Message));
			}
		}

		private static void OnTransferReceived(ulong senderId, FastBufferReader reader)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost)
			{
				return;
			}
			try
			{
				ulong fromId = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref fromId, default(ForPrimitives));
				ulong toId = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref toId, default(ForPrimitives));
				float remainingTime = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref remainingTime, default(ForPrimitives));
				ApplyTransferLocally(fromId, toId, remainingTime);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[CurseNet] OnTransfer Fehler: " + ex.Message));
			}
		}

		private static void OnCleanReceived(ulong senderId, FastBufferReader reader)
		{
			if (IsHost)
			{
				return;
			}
			try
			{
				if ((Object)(object)Plugin.MaskedPlayer != (Object)null)
				{
					CursedMaskBehaviour.ShowPlayerNameStatic(Plugin.MaskedPlayer);
				}
				CursedMaskBehaviour.CleanupAllCurses();
				Plugin.MaskedPlayer = null;
				Debug.Log((object)"[CurseNet] Cleanup empfangen");
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[CurseNet] OnClean Fehler: " + ex.Message));
			}
		}

		private static void OnReqTransferReceived(ulong senderId, FastBufferReader reader)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost)
			{
				return;
			}
			try
			{
				ulong num = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives));
				ulong num2 = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num2, default(ForPrimitives));
				float remainingTime = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref remainingTime, default(ForPrimitives));
				Debug.Log((object)$"[CurseNet] Transfer-Request empfangen: {num}→{num2}");
				HostBroadcastTransfer(num, num2, remainingTime);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[CurseNet] OnReqTransfer Fehler: " + ex.Message));
			}
		}

		private static void OnReqCurseReceived(ulong senderId, FastBufferReader reader)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost)
			{
				return;
			}
			try
			{
				ulong num = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives));
				Debug.Log((object)$"[CurseNet] Client meldet: Spieler {num} ist verflucht");
				HostBroadcastCurse(num);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[CurseNet] OnReqCurse Fehler: " + ex.Message));
			}
		}

		private static void ApplyCurseLocally(ulong playerClientId)
		{
			PlayerControllerB playerByClientId = GetPlayerByClientId(playerClientId);
			if (!((Object)(object)playerByClientId == (Object)null))
			{
				Plugin.MaskedPlayer = playerByClientId;
				CursedMaskBehaviour.HidePlayerNameStatic(playerByClientId);
				Debug.Log((object)("[CurseNet] MaskedPlayer gesetzt: " + playerByClientId.playerUsername + " (fuer AI + Name)"));
			}
		}

		private static void ApplyTransferLocally(ulong fromId, ulong toId, float remainingTime)
		{
			PlayerControllerB playerByClientId = GetPlayerByClientId(fromId);
			PlayerControllerB playerByClientId2 = GetPlayerByClientId(toId);
			if ((Object)(object)playerByClientId != (Object)null)
			{
				CursedMaskBehaviour.ShowPlayerNameStatic(playerByClientId);
			}
			if ((Object)(object)playerByClientId2 != (Object)null)
			{
				Plugin.MaskedPlayer = playerByClientId2;
				CursedMaskBehaviour.HidePlayerNameStatic(playerByClientId2);
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if (!((Object)(object)val == (Object)null))
			{
				if ((Object)(object)playerByClientId != (Object)null && val.actualClientId == fromId)
				{
					CursedMaskBehaviour.RemoveLocalCurse();
				}
				if ((Object)(object)playerByClientId2 != (Object)null && val.actualClientId == toId)
				{
					CursedMaskBehaviour.ActivateLocalCurseWithTime(playerByClientId2, remainingTime);
				}
				Debug.Log((object)("[CurseNet] Transfer: " + playerByClientId?.playerUsername + " → " + playerByClientId2?.playerUsername));
			}
		}

		internal static PlayerControllerB GetPlayerByClientId(ulong clientId)
		{
			try
			{
				if (StartOfRound.Instance?.allPlayerScripts == null)
				{
					return null;
				}
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val in allPlayerScripts)
				{
					if ((Object)(object)val != (Object)null && val.actualClientId == clientId)
					{
						return val;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static void SendToAll(string msgName, Action<FastBufferWriter> write)
		{
			//IL_0018: 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)
			if (!_registered)
			{
				return;
			}
			try
			{
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, -1);
				write(val);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(msgName, val, (NetworkDelivery)3);
				((FastBufferWriter)(ref val)).Dispose();
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[CurseNet] SendToAll(" + msgName + ") Fehler: " + ex.Message));
			}
		}
	}
	internal class CurseGlobalUpdater : MonoBehaviour
	{
		private static CurseGlobalUpdater _instance;

		internal static void EnsureExists()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)_instance != (Object)null))
			{
				GameObject val = new GameObject("CurseGlobalUpdater");
				Object.DontDestroyOnLoad((Object)val);
				_instance = val.AddComponent<CurseGlobalUpdater>();
			}
		}

		private void Update()
		{
			if (!((Object)(object)Plugin.MaskedPlayer == (Object)null) && !Plugin.MaskedPlayer.isPlayerDead)
			{
				CursedMaskBehaviour.KeepNameHiddenStatic();
			}
		}
	}
	[BepInPlugin("CursedMaskMod", "CursedMaskMod", "1.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		private Harmony _harmony;

		internal static ConfigEntry<float> cfgTimerDuration;

		internal static ConfigEntry<bool> cfgVoiceMute;

		internal static ConfigEntry<bool> cfgMonsterInvisible;

		internal static ConfigEntry<int> cfgAutoAttachChance;

		internal static ConfigEntry<int> cfgShopPrice;

		internal static ConfigEntry<float> cfgTransferCooldown;

		internal static PlayerControllerB MaskedPlayer;

		internal static bool CurseActive;

		private void Awake()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"CursedMaskMod v1.4.0 loaded.");
			cfgTimerDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "Timer (Sekunden)", 60f, new ConfigDescription("Todestimer nach Aufsetzen der Maske", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 300f), Array.Empty<object>()));
			cfgVoiceMute = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "Voice Mute", true, "Voice Chat stumm wenn Maske getragen wird");
			cfgMonsterInvisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "Monster-Unsichtbarkeit", true, "Monster ignorieren den Spieler mit Maske");
			cfgAutoAttachChance = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "Auto-Aufsetz Chance (%)", 20, new ConfigDescription("Chance dass die Maske sich beim Halten/Switchen verflucht", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			cfgShopPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "Shop-Preis", 0, new ConfigDescription("Preis im Shop (0 = gratis)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2000), Array.Empty<object>()));
			cfgTransferCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "Transfer-Cooldown (Sekunden)", 5f, new ConfigDescription("Cooldown nach Uebergabe der Maske", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
			_harmony = new Harmony("CursedMaskMod");
			_harmony.PatchAll(typeof(HauntedMask_EquipItem_Patch));
			_harmony.PatchAll(typeof(HauntedMask_DiscardItem_Patch));
			_harmony.PatchAll(typeof(HauntedMask_BeginAttachment_Patch));
			_harmony.PatchAll(typeof(HauntedMask_Update_Patch));
			_harmony.PatchAll(typeof(HauntedMask_LateUpdate_Patch));
			_harmony.PatchAll(typeof(HauntedMask_MaskClampToHead_Patch));
			_harmony.PatchAll(typeof(HauntedMask_ItemActivate_Patch));
			_harmony.PatchAll(typeof(HauntedMask_AttachServerRpc_Patch));
			_harmony.PatchAll(typeof(HauntedMask_AttachClientRpc_Patch));
			_harmony.PatchAll(typeof(HauntedMask_AttachToPlayerOnLocalClient_Patch));
			_harmony.PatchAll(typeof(HauntedMask_FinishAttaching_Patch));
			_harmony.PatchAll(typeof(HauntedMask_PocketItem_Patch));
			_harmony.PatchAll(typeof(HauntedMask_CreateMimic_Patch));
			_harmony.PatchAll(typeof(EnemyAI_PlayerIsTargetable_Patch));
			_harmony.PatchAll(typeof(EnemyAI_CheckLineOfSightForPlayer_Patch));
			_harmony.PatchAll(typeof(EnemyAI_CheckLineOfSightForClosestPlayer_Patch));
			_harmony.PatchAll(typeof(EnemyAI_GetClosestPlayer_Patch));
			_harmony.PatchAll(typeof(Terminal_Awake_Patch));
			SalesArrayHook.Install();
			_harmony.PatchAll(typeof(Player_SwitchToItemSlot_Patch));
			_harmony.PatchAll(typeof(Player_ScrollMouse_Patch));
			_harmony.PatchAll(typeof(Player_BeginGrabObject_Patch));
			_harmony.PatchAll(typeof(InteractTrigger_Interact_Patch));
			_harmony.PatchAll(typeof(Player_KillPlayer_Patch));
			_harmony.PatchAll(typeof(StartOfRound_ShipLeave_Patch));
			_harmony.PatchAll(typeof(StartOfRound_EndOfGame_Patch));
			_harmony.PatchAll(typeof(StartOfRound_ReviveDeadPlayers_Patch));
			_harmony.PatchAll(typeof(StartOfRound_ResetShip_Patch));
			_harmony.PatchAll(typeof(StartOfRound_Start_Patch));
			_harmony.PatchAll(typeof(GameNetworkManager_Disconnect_Patch));
			Logger.LogInfo((object)"Harmony patches applied (inkl. Netzwerk-Sync).");
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class StartOfRound_Start_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			CurseNetwork.Register();
			CurseGlobalUpdater.EnsureExists();
			Plugin.Logger.LogInfo((object)"[CursedMask] Netzwerk + GlobalUpdater initialisiert!");
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
	internal static class GameNetworkManager_Disconnect_Patch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			try
			{
				CurseNetwork.Unregister();
				CursedMaskBehaviour.CleanupAllCurses();
				Plugin.MaskedPlayer = null;
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "Awake")]
	internal static class Terminal_Awake_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(Terminal __instance)
		{
			try
			{
				Item val = null;
				if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.allItemsList != (Object)null)
				{
					foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
					{
						if (!((Object)(object)items == (Object)null))
						{
							string text = items.itemName?.ToLower() ?? "";
							if (text.Contains("comedy") || text.Contains("tragedy"))
							{
								val = items;
								break;
							}
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Logger.LogWarning((object)"[CursedMask] Keine Maske in allItemsList gefunden!");
					return;
				}
				int num = (val.creditsWorth = Plugin.cfgShopPrice.Value);
				Item[] buyableItemsList = __instance.buyableItemsList;
				Item[] array = buyableItemsList;
				foreach (Item val2 in array)
				{
					if ((Object)(object)val2 != (Object)null && val2.itemName == val.itemName)
					{
						Plugin.Logger.LogInfo((object)("[CursedMask] " + val.itemName + " ist bereits im Shop"));
						return;
					}
				}
				List<Item> list = new List<Item>(buyableItemsList);
				list.Add(val);
				__instance.buyableItemsList = list.ToArray();
				List<int> list2 = ((__instance.itemSalesPercentages == null) ? new List<int>() : new List<int>(__instance.itemSalesPercentages));
				while (list2.Count < __instance.buyableItemsList.Length)
				{
					list2.Add(100);
				}
				__instance.itemSalesPercentages = list2.ToArray();
				int num2 = __instance.buyableItemsList.Length - 1;
				AddMaskToBuyKeywords(__instance, val, num2, num);
				Plugin.Logger.LogInfo((object)$"[CursedMask] {val.itemName} zum Shop hinzugefuegt! Index={num2}, Preis={num}");
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"[CursedMask] Terminal-Patch Fehler: {arg}");
			}
		}

		private static void AddMaskToBuyKeywords(Terminal terminal, Item maskItem, int buyIndex, int price)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			val.displayText = "You have requested to order " + maskItem.itemName + ". Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\n\n";
			val.clearPreviousText = true;
			val.maxCharactersToType = 25;
			val.isConfirmationNode = true;
			val.buyItemIndex = buyIndex;
			val.overrideOptions = true;
			TerminalNode val2 = ScriptableObject.CreateInstance<TerminalNode>();
			val2.displayText = "Ordered [variableAmount] " + maskItem.itemName + ". Your new balance is [playerCredits].\n\n";
			val2.clearPreviousText = true;
			val2.maxCharactersToType = 25;
			val2.buyItemIndex = buyIndex;
			val2.isConfirmationNode = false;
			TerminalNode val3 = ScriptableObject.CreateInstance<TerminalNode>();
			val3.displayText = "Cancelled order.\n\n";
			val3.clearPreviousText = true;
			TerminalKeyword val4 = null;
			TerminalKeyword val5 = null;
			TerminalKeyword[] allKeywords = terminal.terminalNodes.allKeywords;
			foreach (TerminalKeyword val6 in allKeywords)
			{
				if (val6.word == "confirm")
				{
					val4 = val6;
				}
				if (val6.word == "deny")
				{
					val5 = val6;
				}
			}
			if ((Object)(object)val4 != (Object)null && (Object)(object)val5 != (Object)null)
			{
				val.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
				{
					new CompatibleNoun
					{
						noun = val4,
						result = val2
					},
					new CompatibleNoun
					{
						noun = val5,
						result = val3
					}
				};
			}
			TerminalKeyword val7 = ScriptableObject.CreateInstance<TerminalKeyword>();
			val7.word = "mask";
			val7.isVerb = false;
			val7.defaultVerb = null;
			TerminalKeyword val8 = null;
			allKeywords = terminal.terminalNodes.allKeywords;
			foreach (TerminalKeyword val9 in allKeywords)
			{
				if (val9.word == "buy")
				{
					val8 = val9;
					break;
				}
			}
			if ((Object)(object)val8 != (Object)null)
			{
				CompatibleNoun item = new CompatibleNoun
				{
					noun = val7,
					result = val
				};
				List<CompatibleNoun> list = new List<CompatibleNoun>();
				if (val8.compatibleNouns != null)
				{
					list.AddRange(val8.compatibleNouns);
				}
				list.Add(item);
				val8.compatibleNouns = list.ToArray();
			}
			List<TerminalKeyword> list2 = new List<TerminalKeyword>(terminal.terminalNodes.allKeywords);
			list2.Add(val7);
			terminal.terminalNodes.allKeywords = list2.ToArray();
		}
	}
	internal static class SalesArrayHook
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_SetItemSales <0>__Terminal_SetItemSales;
		}

		private static bool _hooked;

		internal static void Install()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (!_hooked)
			{
				object obj = <>O.<0>__Terminal_SetItemSales;
				if (obj == null)
				{
					hook_SetItemSales val = Terminal_SetItemSales;
					<>O.<0>__Terminal_SetItemSales = val;
					obj = (object)val;
				}
				Terminal.SetItemSales += (hook_SetItemSales)obj;
				_hooked = true;
				Plugin.Logger.LogInfo((object)"[CursedMask] MonoMod On-Hook fuer Terminal.SetItemSales installiert!");
			}
		}

		private static void FixSalesArray(Terminal terminal)
		{
			if (terminal.buyableItemsList == null)
			{
				return;
			}
			int num = terminal.buyableItemsList.Length;
			if (terminal.itemSalesPercentages == null || terminal.itemSalesPercentages.Length < num)
			{
				List<int> list = ((terminal.itemSalesPercentages == null) ? new List<int>() : new List<int>(terminal.itemSalesPercentages));
				while (list.Count < num)
				{
					list.Add(100);
				}
				terminal.itemSalesPercentages = list.ToArray();
				Plugin.Logger.LogInfo((object)$"[CursedMask] itemSalesPercentages auf {num} erweitert");
			}
		}

		private static void Terminal_SetItemSales(orig_SetItemSales orig, Terminal self)
		{
			try
			{
				FixSalesArray(self);
			}
			catch
			{
			}
			try
			{
				orig.Invoke(self);
			}
			catch (IndexOutOfRangeException)
			{
				Plugin.Logger.LogWarning((object)"[CursedMask] SetItemSales IndexOutOfRange abgefangen!");
			}
			try
			{
				FixSalesArray(self);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "EquipItem")]
	internal static class HauntedMask_EquipItem_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(HauntedMaskItem __instance)
		{
			CursedMaskBehaviour cursedMaskBehaviour = ((Component)__instance).GetComponent<CursedMaskBehaviour>();
			if ((Object)(object)cursedMaskBehaviour == (Object)null)
			{
				cursedMaskBehaviour = ((Component)__instance).gameObject.AddComponent<CursedMaskBehaviour>();
				Plugin.Logger.LogInfo((object)"[CursedMask] CursedMaskBehaviour hinzugefuegt");
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null || (Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null || ((GrabbableObject)__instance).playerHeldBy != val)
			{
				return;
			}
			if (cursedMaskBehaviour.IsOnCooldown())
			{
				Plugin.Logger.LogInfo((object)"[CursedMask] Transfer-Cooldown aktiv, kein Fluch.");
				return;
			}
			if (cursedMaskBehaviour.AlreadyCursed)
			{
				Plugin.Logger.LogInfo((object)"[CursedMask] Maske ist bereits verflucht! 100% Uebernahme!");
				cursedMaskBehaviour.OnMaskEquipped(val);
				CurseNetwork.ClientNotifyCurse(val.actualClientId);
				return;
			}
			FieldInfo field = typeof(HauntedMaskItem).GetField("maskOn", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null && (bool)field.GetValue(__instance))
			{
				cursedMaskBehaviour.OnMaskEquipped(val);
				CurseNetwork.ClientNotifyCurse(val.actualClientId);
				return;
			}
			int value = Plugin.cfgAutoAttachChance.Value;
			int num = Random.Range(0, 100);
			Plugin.Logger.LogInfo((object)$"[CursedMask] Wuerfeln: {num} (brauche < {value})");
			if (num < value)
			{
				Plugin.Logger.LogInfo((object)"[CursedMask] FLUCH AKTIVIERT! Nur ICH weiss davon.");
				cursedMaskBehaviour.OnMaskEquipped(val);
				CurseNetwork.ClientNotifyCurse(val.actualClientId);
			}
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "DiscardItem")]
	internal static class HauntedMask_DiscardItem_Patch
	{
		[HarmonyPrefix]
		private static void Prefix(HauntedMaskItem __instance)
		{
			CursedMaskBehaviour component = ((Component)__instance).GetComponent<CursedMaskBehaviour>();
			if ((Object)(object)component != (Object)null && component.IsTransferring)
			{
				component.OnMaskRemoved();
				component.IsTransferring = false;
				Plugin.Logger.LogInfo((object)"[CursedMask] E-Transfer: Fluch vom Spieler entfernt");
			}
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "BeginAttachment")]
	internal static class HauntedMask_BeginAttachment_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix(HauntedMaskItem __instance)
		{
			MaskStateHelper.ResetVanillaMaskState(__instance);
			return false;
		}
	}
	internal static class MaskStateHelper
	{
		internal static void ResetVanillaMaskState(HauntedMaskItem mask)
		{
			try
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				FieldInfo field = typeof(HauntedMaskItem).GetField("attaching", bindingAttr);
				if (field != null)
				{
					field.SetValue(mask, false);
				}
				FieldInfo field2 = typeof(HauntedMaskItem).GetField("maskOn", bindingAttr);
				if (field2 != null)
				{
					field2.SetValue(mask, false);
				}
				FieldInfo field3 = typeof(HauntedMaskItem).GetField("maskIsHaunted", bindingAttr);
				if (field3 != null)
				{
					field3.SetValue(mask, false);
				}
				FieldInfo field4 = typeof(HauntedMaskItem).GetField("finishedAttaching", bindingAttr);
				if (field4 != null)
				{
					field4.SetValue(mask, false);
				}
				FieldInfo field5 = typeof(HauntedMaskItem).GetField("clampedToHead", bindingAttr);
				if (field5 != null)
				{
					field5.SetValue(mask, false);
				}
				((GrabbableObject)mask).grabbable = true;
				((GrabbableObject)mask).grabbableToEnemies = true;
				if ((Object)(object)mask.maskEyesFilled != (Object)null && ((Renderer)mask.maskEyesFilled).enabled)
				{
					((Renderer)mask.maskEyesFilled).enabled = false;
				}
				if ((Object)(object)mask.currentHeadMask != (Object)null && ((Component)mask.currentHeadMask).gameObject.activeSelf)
				{
					((Component)mask.currentHeadMask).gameObject.SetActive(false);
				}
			}
			catch
			{
			}
		}

		internal static void SuppressVanillaAttaching(HauntedMaskItem mask)
		{
			try
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				FieldInfo field = typeof(HauntedMaskItem).GetField("attaching", bindingAttr);
				if (field != null && (bool)field.GetValue(mask))
				{
					field.SetValue(mask, false);
				}
				FieldInfo field2 = typeof(HauntedMaskItem).GetField("maskIsHaunted", bindingAttr);
				if (field2 != null && (bool)field2.GetValue(mask))
				{
					field2.SetValue(mask, false);
				}
				FieldInfo field3 = typeof(HauntedMaskItem).GetField("maskOn", bindingAttr);
				if (field3 != null && (bool)field3.GetValue(mask))
				{
					field3.SetValue(mask, false);
				}
				FieldInfo field4 = typeof(HauntedMaskItem).GetField("finishedAttaching", bindingAttr);
				if (field4 != null && (bool)field4.GetValue(mask))
				{
					field4.SetValue(mask, false);
				}
				FieldInfo field5 = typeof(HauntedMaskItem).GetField("clampedToHead", bindingAttr);
				if (field5 != null && (bool)field5.GetValue(mask))
				{
					field5.SetValue(mask, false);
				}
				if (!((GrabbableObject)mask).grabbable)
				{
					((GrabbableObject)mask).grabbable = true;
				}
				if ((Object)(object)mask.maskEyesFilled != (Object)null && ((Renderer)mask.maskEyesFilled).enabled)
				{
					((Renderer)mask.maskEyesFilled).enabled = false;
				}
				if ((Object)(object)mask.currentHeadMask != (Object)null && ((Component)mask.currentHeadMask).gameObject.activeSelf)
				{
					((Component)mask.currentHeadMask).gameObject.SetActive(false);
				}
			}
			catch
			{
			}
		}

		internal static void EnsurePickupable(HauntedMaskItem mask)
		{
			try
			{
				((GrabbableObject)mask).grabbable = true;
				((GrabbableObject)mask).grabbableToEnemies = true;
				Collider[] componentsInChildren = ((Component)mask).GetComponentsInChildren<Collider>(true);
				foreach (Collider val in componentsInChildren)
				{
					if (!val.enabled)
					{
						val.enabled = true;
					}
				}
				Renderer[] componentsInChildren2 = ((Component)mask).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val2 in componentsInChildren2)
				{
					if (!val2.enabled)
					{
						val2.enabled = true;
					}
				}
				try
				{
					ScanNodeProperties componentInChildren = ((Component)mask).GetComponentInChildren<ScanNodeProperties>(true);
					if ((Object)(object)componentInChildren != (Object)null && !((Component)componentInChildren).gameObject.activeSelf)
					{
						((Component)componentInChildren).gameObject.SetActive(true);
					}
				}
				catch
				{
				}
				try
				{
					((GrabbableObject)mask).EnablePhysics(true);
				}
				catch
				{
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "Update")]
	internal static class HauntedMask_Update_Patch
	{
		[HarmonyPrefix]
		private static void Prefix(HauntedMaskItem __instance)
		{
			MaskStateHelper.SuppressVanillaAttaching(__instance);
		}

		[HarmonyPostfix]
		private static void Postfix(HauntedMaskItem __instance)
		{
			MaskStateHelper.SuppressVanillaAttaching(__instance);
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "LateUpdate")]
	internal static class HauntedMask_LateUpdate_Patch
	{
		[HarmonyPrefix]
		private static void Prefix(HauntedMaskItem __instance)
		{
			MaskStateHelper.SuppressVanillaAttaching(__instance);
		}

		[HarmonyPostfix]
		private static void Postfix(HauntedMaskItem __instance)
		{
			MaskStateHelper.SuppressVanillaAttaching(__instance);
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "MaskClampToHeadAnimationEvent")]
	internal static class HauntedMask_MaskClampToHead_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "ItemActivate")]
	internal static class HauntedMask_ItemActivate_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "AttachServerRpc")]
	internal static class HauntedMask_AttachServerRpc_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix(HauntedMaskItem __instance)
		{
			MaskStateHelper.ResetVanillaMaskState(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "AttachClientRpc")]
	internal static class HauntedMask_AttachClientRpc_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix(HauntedMaskItem __instance)
		{
			MaskStateHelper.ResetVanillaMaskState(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "AttachToPlayerOnLocalClient")]
	internal static class HauntedMask_AttachToPlayerOnLocalClient_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix(HauntedMaskItem __instance)
		{
			MaskStateHelper.ResetVanillaMaskState(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "FinishAttaching")]
	internal static class HauntedMask_FinishAttaching_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix(HauntedMaskItem __instance)
		{
			MaskStateHelper.ResetVanillaMaskState(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "PocketItem")]
	internal static class HauntedMask_PocketItem_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(HauntedMaskItem __instance)
		{
			MaskStateHelper.SuppressVanillaAttaching(__instance);
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "CreateMimicServerRpc")]
	internal static class HauntedMask_CreateMimic_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "PlayerIsTargetable")]
	internal static class EnemyAI_PlayerIsTargetable_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerControllerB playerScript, ref bool __result)
		{
			if (Plugin.cfgMonsterInvisible.Value && (Object)(object)Plugin.MaskedPlayer != (Object)null && playerScript == Plugin.MaskedPlayer)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "CheckLineOfSightForPlayer")]
	internal static class EnemyAI_CheckLineOfSightForPlayer_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(ref PlayerControllerB __result)
		{
			if (Plugin.cfgMonsterInvisible.Value && (Object)(object)__result != (Object)null && (Object)(object)Plugin.MaskedPlayer != (Object)null && __result == Plugin.MaskedPlayer && CurseHelper.HasOtherAlivePlayers())
			{
				__result = null;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "CheckLineOfSightForClosestPlayer")]
	internal static class EnemyAI_CheckLineOfSightForClosestPlayer_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(ref PlayerControllerB __result)
		{
			if (Plugin.cfgMonsterInvisible.Value && (Object)(object)__result != (Object)null && (Object)(object)Plugin.MaskedPlayer != (Object)null && __result == Plugin.MaskedPlayer && CurseHelper.HasOtherAlivePlayers())
			{
				__result = null;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "GetClosestPlayer")]
	internal static class EnemyAI_GetClosestPlayer_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(ref PlayerControllerB __result)
		{
			if (Plugin.cfgMonsterInvisible.Value && (Object)(object)__result != (Object)null && (Object)(object)Plugin.MaskedPlayer != (Object)null && __result == Plugin.MaskedPlayer && CurseHelper.HasOtherAlivePlayers())
			{
				__result = null;
			}
		}
	}
	internal static class CurseHelper
	{
		internal static bool HasOtherAlivePlayers()
		{
			try
			{
				if ((Object)(object)StartOfRound.Instance == (Object)null)
				{
					return false;
				}
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				if (allPlayerScripts == null)
				{
					return false;
				}
				PlayerControllerB[] array = allPlayerScripts;
				foreach (PlayerControllerB val