DepYourFriend.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using FishNet;
using FishNet.Broadcast;
using FishNet.Object;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[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("DepYourFriend")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ef205c0bc5ececb180383e6f0d0df5f930d38e0a")]
[assembly: AssemblyProduct("DepYourFriend")]
[assembly: AssemblyTitle("DepYourFriend")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DepYourFriend
{
	[BepInPlugin("com.antigravity.depyourfriend", "DEP YOUR FRIEND", "1.0.0")]
	public class DepPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.antigravity.depyourfriend";

		public const string ModName = "DEP YOUR FRIEND";

		public const string ModVersion = "1.0.0";

		private Harmony _harmony;

		public static ManualLogSource ModLogger { get; private set; }

		public static DepPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			Instance = this;
			ModLogger = ((BaseUnityPlugin)this).Logger;
			ModLogger.LogInfo((object)"DEP YOUR FRIEND v1.0.0 is loading...");
			_harmony = new Harmony("com.antigravity.depyourfriend");
			_harmony.PatchAll();
			FriendBailManager.Initialize();
			((Component)this).gameObject.AddComponent<FriendBailHUD>();
			ModLogger.LogInfo((object)"DEP YOUR FRIEND loaded successfully! Ready to gamble your friends on the roulette table.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public class FriendBailHUD : MonoBehaviour
	{
		public static DeadPlayer? HoveredCorpse;

		private static Texture2D? _panelTex;

		private static GUIStyle? _panelStyle;

		private void OnGUI()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.LocalPlayer == (Object)null || (Object)(object)Player.LocalPlayer.Holding == (Object)null)
			{
				return;
			}
			Item heldItem = Player.LocalPlayer.Holding.HeldItem;
			DeadPlayer val = (DeadPlayer)(((object)((heldItem is DeadPlayer) ? heldItem : null)) ?? ((object)(((Object)(object)HoveredCorpse != (Object)null) ? HoveredCorpse : null)));
			if (!((Object)(object)val == (Object)null))
			{
				string bailStatusString = FriendBailManager.GetBailStatusString(FriendBailManager.GetBail(val));
				if (_panelStyle == null)
				{
					_panelTex = new Texture2D(1, 1);
					_panelTex.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.72f));
					_panelTex.Apply();
					GUIStyle val2 = new GUIStyle(GUI.skin.box)
					{
						fontSize = 17,
						fontStyle = (FontStyle)1,
						alignment = (TextAnchor)3,
						richText = true,
						wordWrap = true
					};
					val2.normal.textColor = Color.white;
					val2.normal.background = _panelTex;
					_panelStyle = val2;
				}
				Item heldItem2 = Player.LocalPlayer.Holding.HeldItem;
				string text = (((Object)(object)((heldItem2 is DeadPlayer) ? heldItem2 : null) != (Object)null) ? "Держи ЛКМ, чтобы оживить · или неси на стол рулетки, чтобы сыграть" : "Возьми в руки, чтобы оживить или понести на стол рулетки");
				string text2 = "<color=#FFD700>[ ТРУП ДРУГА ]</color>  " + bailStatusString + "\n<size=14><color=#BBBBBB>" + text + "</color></size>";
				GUI.Box(new Rect(16f, (float)(Screen.height - 104), (float)Mathf.Min(840, Screen.width - 32), 76f), text2, _panelStyle);
			}
		}
	}
	public struct BailSyncBroadcast : IBroadcast
	{
		public int DeadPlayerNetworkId;

		public int CurrentBail;
	}
	public static class FriendBailManager
	{
		public const int BaseValue = -100;

		public const int FreeThreshold = 99;

		private static readonly Dictionary<int, int> _deadPlayerBails = new Dictionary<int, int>();

		private static bool _broadcastRegistered;

		public static void Initialize()
		{
			_broadcastRegistered = false;
			EnsureBroadcastRegistered();
		}

		private static void EnsureBroadcastRegistered()
		{
			if (!_broadcastRegistered && (Object)(object)InstanceFinder.ClientManager != (Object)null)
			{
				InstanceFinder.ClientManager.RegisterBroadcast<BailSyncBroadcast>((Action<BailSyncBroadcast, Channel>)OnBailSyncReceived);
				_broadcastRegistered = true;
			}
		}

		public static void Reset()
		{
			_deadPlayerBails.Clear();
		}

		public static int GetBail(DeadPlayer deadPlayer)
		{
			EnsureBroadcastRegistered();
			if ((Object)(object)deadPlayer == (Object)null)
			{
				return -100;
			}
			int objectId = GetObjectId(deadPlayer);
			if (objectId == 0)
			{
				return -100;
			}
			if (_deadPlayerBails.TryGetValue(objectId, out var value))
			{
				return value;
			}
			_deadPlayerBails[objectId] = -100;
			return -100;
		}

		public static void SetBail(DeadPlayer deadPlayer, int amount, bool broadcast = true)
		{
			EnsureBroadcastRegistered();
			if ((Object)(object)deadPlayer == (Object)null)
			{
				return;
			}
			int objectId = GetObjectId(deadPlayer);
			if (objectId != 0)
			{
				_deadPlayerBails[objectId] = amount;
				if (broadcast && (Object)(object)InstanceFinder.ServerManager != (Object)null && InstanceFinder.ServerManager.Started)
				{
					BailSyncBroadcast bailSyncBroadcast = new BailSyncBroadcast
					{
						DeadPlayerNetworkId = objectId,
						CurrentBail = amount
					};
					InstanceFinder.ServerManager.Broadcast<BailSyncBroadcast>(bailSyncBroadcast, true, (Channel)0);
				}
			}
		}

		public static int ResolveRoulette(DeadPlayer deadPlayer, int multiplier, bool won)
		{
			int bail = GetBail(deadPlayer);
			if (won)
			{
				bail = ((bail <= 0) ? Mathf.CeilToInt((float)bail / (float)multiplier) : (bail * multiplier));
				if (Mathf.Abs(bail) <= 99)
				{
					bail = 99;
				}
			}
			else
			{
				bail = ((bail >= 0) ? Mathf.FloorToInt((float)bail / (float)multiplier) : (bail * multiplier));
				if (Mathf.Abs(bail) <= 99)
				{
					bail = -99;
				}
			}
			SetBail(deadPlayer, bail);
			return bail;
		}

		public static void RemoveBail(DeadPlayer deadPlayer)
		{
			if (!((Object)(object)deadPlayer == (Object)null))
			{
				int objectId = GetObjectId(deadPlayer);
				if (objectId != 0)
				{
					_deadPlayerBails.Remove(objectId);
				}
			}
		}

		private static int GetObjectId(DeadPlayer deadPlayer)
		{
			if ((Object)(object)((NetworkBehaviour)deadPlayer).NetworkObject != (Object)null)
			{
				return ((NetworkBehaviour)deadPlayer).NetworkObject.ObjectId;
			}
			return ((Object)((Component)deadPlayer).gameObject).GetInstanceID();
		}

		private static void OnBailSyncReceived(BailSyncBroadcast msg, Channel channel)
		{
			_deadPlayerBails[msg.DeadPlayerNetworkId] = msg.CurrentBail;
		}

		public static string GetBailStatusString(int bail)
		{
			if (bail < 0)
			{
				return $"Залог: ${Math.Abs(bail)}";
			}
			if (bail == 0)
			{
				return "Бесплатный выкуп! ($0)";
			}
			return $"Прибыль при оживлении: +${bail}!";
		}
	}
}
namespace DepYourFriend.Patches
{
	[HarmonyPatch(typeof(CasinoBox))]
	public static class CasinoBoxPatch
	{
		[HarmonyPatch("FixedUpdate")]
		[HarmonyPrefix]
		public static bool FixedUpdatePrefix(CasinoBox __instance, BoxCollider ____col)
		{
			//IL_0034: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Server.Instance) || !((NetworkBehaviour)Server.Instance).IsServerInitialized || (Object.op_Implicit((Object)(object)CasinoManager.Instance) && CasinoManager.IsBetting))
			{
				return false;
			}
			Vector3 val = ((Component)____col).transform.TransformPoint(____col.center);
			Vector3 val2 = Vector3.Scale(____col.size * 0.5f, ((Component)__instance).transform.localScale);
			int num = LayerMask.op_Implicit(GameInfo.ItemLayer) | LayerMask.op_Implicit(GameInfo.ItemPartLayer) | LayerMask.op_Implicit(GameInfo.ItemAndInHandLayer) | (1 << LayerMask.NameToLayer("Default"));
			Collider[] array = Physics.OverlapBox(val, val2, ((Component)__instance).transform.rotation, num);
			List<Item> list = new List<Item>();
			Collider[] array2 = array;
			foreach (Collider val3 in array2)
			{
				Item val4 = ItemManager.Get(val3);
				if ((Object)(object)val4 == (Object)null)
				{
					DeadPlayer componentInParent = ((Component)val3).GetComponentInParent<DeadPlayer>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						val4 = (Item)(object)componentInParent;
					}
				}
				if ((Object)(object)val4 != (Object)null && !list.Contains(val4) && (!Object.op_Implicit((Object)(object)val4.Creature) || val4.Creature.IsDead))
				{
					list.Add(val4);
				}
			}
			CasinoManager.SetBetItems(list);
			return false;
		}
	}
	[HarmonyPatch(typeof(LocalCasino))]
	public static class LocalCasinoSignedPatch
	{
		[HarmonyPatch("SetTotalWorthText")]
		[HarmonyPrefix]
		public static bool SetTotalWorthTextPrefix(LocalCasino __instance)
		{
			List<Item> value = Traverse.Create(typeof(CasinoManager)).Field("_itemsToBet").GetValue<List<Item>>();
			if (value == null)
			{
				return true;
			}
			int num = 0;
			bool flag = false;
			bool flag2 = false;
			foreach (Item item in value)
			{
				if (!((Object)(object)item == (Object)null))
				{
					if ((Object)(object)item.DeadPlayer != (Object)null)
					{
						flag = true;
						num += FriendBailManager.GetBail(item.DeadPlayer);
					}
					else
					{
						num += Mathf.Max(0, item.TotalWorth);
					}
					flag2 = true;
				}
			}
			if (!flag)
			{
				return true;
			}
			Coroutine value2 = Traverse.Create((object)__instance).Field("_worthRoutine").GetValue<Coroutine>();
			if (value2 != null)
			{
				((MonoBehaviour)__instance).StopCoroutine(value2);
				Traverse.Create((object)__instance).Field("_worthRoutine").SetValue((object)null);
			}
			Traverse.Create((object)__instance).Field("_curBetWorth").SetValue((object)num);
			Traverse.Create((object)__instance).Field("_targetBetWorth").SetValue((object)num);
			TextMeshProUGUI value3 = Traverse.Create((object)__instance).Field("_curWorthText").GetValue<TextMeshProUGUI>();
			if ((Object)(object)value3 != (Object)null)
			{
				((TMP_Text)value3).text = ((num < 0) ? $"-${Mathf.Abs(num)}" : $"${num}");
			}
			BetButton.ToggleAll(flag2 && num != 0);
			return false;
		}
	}
	[HarmonyPatch(typeof(CasinoManager))]
	public static class CasinoManagerPatch
	{
		private static int _lastSignedTotal;

		[HarmonyPatch("CalculateWorth")]
		[HarmonyPrefix]
		public static bool CalculateWorthPrefix(bool won)
		{
			List<Item> value = Traverse.Create(typeof(CasinoManager)).Field("_itemsToBet").GetValue<List<Item>>();
			if (value == null)
			{
				return true;
			}
			int num = 0;
			int num2 = 0;
			foreach (Item item in value)
			{
				if (!((Object)(object)item == (Object)null))
				{
					if ((Object)(object)item.DeadPlayer != (Object)null)
					{
						int bail = FriendBailManager.GetBail(item.DeadPlayer);
						num += Mathf.Max(1, Mathf.Abs(bail));
						num2 += bail;
					}
					else
					{
						num += item.TotalWorth;
						num2 += item.TotalWorth;
					}
				}
			}
			if ((Object)(object)CasinoManager.Instance != (Object)null && (num != CasinoManager.Instance._totalWorth.Value || num2 != _lastSignedTotal))
			{
				_lastSignedTotal = num2;
				CasinoManager.Instance._totalWorth.Value = num;
				Traverse.Create((object)CasinoManager.Instance).Method("UpdateTotalWorth", new object[2] { num, won }).GetValue();
			}
			return false;
		}

		[HarmonyPatch("ServerRouletteResult")]
		[HarmonyPrefix]
		public static bool ServerRouletteResultPrefix(CasinoManager __instance, BetColor winColor)
		{
			//IL_0038: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Invalid comparison between Unknown and I4
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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)
			List<Item> value = Traverse.Create(typeof(CasinoManager)).Field("_itemsToBet").GetValue<List<Item>>();
			BetColor value2 = Traverse.Create(typeof(CasinoManager)).Field("_curBetColor").GetValue<BetColor>();
			bool flag = winColor == value2;
			int num = 0;
			if (flag)
			{
				if ((int)winColor > 1)
				{
					if ((int)winColor == 2)
					{
						num = 35;
					}
				}
				else
				{
					num = 2;
				}
			}
			if (value != null)
			{
				foreach (Item item in value)
				{
					if ((Object)(object)item == (Object)null)
					{
						continue;
					}
					if ((Object)(object)item.DeadPlayer != (Object)null)
					{
						item.ToggleInteractable(true);
						int multiplier = (((int)value2 == 2) ? 35 : 2);
						int bail = FriendBailManager.ResolveRoulette(item.DeadPlayer, multiplier, flag);
						if ((Object)(object)LocalCasino.Instance != (Object)null)
						{
							Transform value3 = Traverse.Create((object)LocalCasino.Instance).Field("_effectsPos").GetValue<Transform>();
							Vector3 val = (((Object)(object)value3 != (Object)null) ? (value3.position + Vector3.up * 0.4f) : (((Component)item).transform.position + Vector3.up * 1f));
							WorldText val2 = Object.Instantiate<WorldText>(GameInfo.WorldTextPrefab, val, Quaternion.identity);
							if ((Object)(object)val2 != (Object)null)
							{
								string text = (flag ? ("<color=#55FF55>ДЕП ЗАШЕЛ!</color>\n" + FriendBailManager.GetBailStatusString(bail)) : ("<color=#FF5555>ДЕП НЕ ЗАШЕЛ!</color>\n" + FriendBailManager.GetBailStatusString(bail)));
								val2.SetText(text, 0.25f);
								val2.FloatAndRemoveAnimation();
							}
						}
					}
					else if (flag)
					{
						item.ToggleInteractable(true);
						item.AddBetMultiplier((float)num);
					}
					else
					{
						item.DestroyItem((byte)0, byte.MaxValue);
					}
				}
			}
			bool flag2 = value != null && value.Count > 0;
			Traverse.Create(typeof(CasinoManager)).Method("CalculateWorth", new object[1] { flag }).GetValue();
			Traverse.Create((object)__instance).Method("BetResultEffects", new object[2]
			{
				(byte)value2,
				flag || flag2
			}).GetValue();
			Traverse.Create(typeof(CasinoManager)).Property("IsBetting", (object[])null).SetValue((object)false);
			return false;
		}
	}
	[HarmonyPatch(typeof(Item))]
	public static class DeadPlayerHoverPatch
	{
		[HarmonyPatch("Hover")]
		[HarmonyPostfix]
		public static void HoverPostfix(Item __instance)
		{
			DeadPlayer val = (DeadPlayer)(object)((__instance is DeadPlayer) ? __instance : null);
			if (val != null)
			{
				FriendBailHUD.HoveredCorpse = val;
				PlayerUI.HideLookAtText("");
			}
		}

		[HarmonyPatch("UnHover")]
		[HarmonyPostfix]
		public static void UnHoverPostfix(Item __instance)
		{
			if (__instance is DeadPlayer && (Object)(object)FriendBailHUD.HoveredCorpse == (Object)(object)__instance)
			{
				FriendBailHUD.HoveredCorpse = null;
			}
		}
	}
	[HarmonyPatch(typeof(DeadPlayer))]
	public static class DeadPlayerPatch
	{
		[HarmonyPatch("PrimaryInput")]
		[HarmonyPrefix]
		public static bool PrimaryInputPrefix(DeadPlayer __instance, Player ____holder)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)____holder == (Object)null)
			{
				return true;
			}
			int bail = FriendBailManager.GetBail(__instance);
			if (bail < 0 && !MoneyManager.CanAfford(Mathf.Abs(bail), (Currency)0))
			{
				PlayerUI.SetLookAtText($"<color=#FF4444>НЕ ХВАТАЕТ ДЕНЕГ НА ВЫКУП!</color>\nТребуется: ${Mathf.Abs(bail)} (В банке: ${MoneyManager.Money})", ((Component)__instance).transform, default(Vector3), false);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerVitals))]
	public static class ServerResurrectPatch
	{
		[HarmonyPatch("OnResurrect")]
		[HarmonyPostfix]
		public static void OnResurrectPostfix(PlayerVitals __instance, Player ____player)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)____player == (Object)null || (Object)(object)____player.Dying == (Object)null || !((NetworkBehaviour)__instance).IsServerInitialized)
			{
				return;
			}
			DeadPlayer deadPlayer = ____player.Dying.DeadPlayer;
			if ((Object)(object)deadPlayer == (Object)null)
			{
				return;
			}
			int bail = FriendBailManager.GetBail(deadPlayer);
			Player val = (Player)(((Object)(object)((Item)deadPlayer).LastHolder != (Object)null) ? ((object)((Item)deadPlayer).LastHolder) : ((object)____player));
			if (!((Object)(object)val == (Object)null))
			{
				if (bail < 0)
				{
					MoneyManager.RemoveMoney(Mathf.Abs(bail), val, (Currency)0);
				}
				else if (bail > 0)
				{
					MoneyManager.AddMoney(bail, val, (Currency)0);
				}
				FriendBailManager.RemoveBail(deadPlayer);
			}
		}
	}
	[HarmonyPatch(typeof(DeathUI))]
	public static class DeathUIPatch
	{
		[HarmonyPatch("FixedUpdate")]
		[HarmonyPostfix]
		public static void FixedUpdatePostfix(DeathUI __instance, bool ____isOn, GameObject ____noBossUI, GameObject ____friendsHelpText)
		{
			if (!____isOn)
			{
				return;
			}
			if (PlayerDyingPatch.ShouldBlockSelfRespawn())
			{
				if ((Object)(object)____noBossUI != (Object)null && ____noBossUI.activeSelf)
				{
					____noBossUI.SetActive(false);
				}
				if (!((Object)(object)____friendsHelpText != (Object)null))
				{
					return;
				}
				____friendsHelpText.SetActive(true);
				TextMeshProUGUI componentInChildren = ____friendsHelpText.GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					int bail = -100;
					if ((Object)(object)Player.LocalPlayer != (Object)null && (Object)(object)Player.LocalPlayer.Dying != (Object)null && (Object)(object)Player.LocalPlayer.Dying.DeadPlayer != (Object)null)
					{
						bail = FriendBailManager.GetBail(Player.LocalPlayer.Dying.DeadPlayer);
					}
					((TMP_Text)componentInChildren).text = "<color=#FFD700>" + FriendBailManager.GetBailStatusString(bail) + "</color>\n<size=75%><color=#AAAAAA>Ждите оживления от союзника или депа на рулетке!</color></size>";
				}
			}
			else
			{
				if (PlayerManager.AlivePlayers.Count != 0 || !((Object)(object)____noBossUI != (Object)null) || ____noBossUI.activeSelf || !((Object)(object)BossManager.Boss == (Object)null))
				{
					return;
				}
				____noBossUI.SetActive(true);
				if ((Object)(object)____friendsHelpText != (Object)null)
				{
					TextMeshProUGUI componentInChildren2 = ____friendsHelpText.GetComponentInChildren<TextMeshProUGUI>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						((TMP_Text)componentInChildren2).text = "<color=#FF5555>ВСЕ ПОГИБЛИ! Удерживайте ЛКМ для респавна лодки</color>";
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerDying))]
	public static class PlayerDyingPatch
	{
		public static bool ShouldBlockSelfRespawn()
		{
			if (PlayerManager.Players.Count >= 2 && (Object)(object)BossManager.Boss == (Object)null)
			{
				return PlayerManager.AlivePlayers.Count > 0;
			}
			return false;
		}

		[HarmonyPatch("MouseClick")]
		[HarmonyPrefix]
		public static bool MouseClickPrefix(PlayerDying __instance)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (ShouldBlockSelfRespawn() && __instance.IsDead)
			{
				int bail = -100;
				if ((Object)(object)__instance.DeadPlayer != (Object)null)
				{
					bail = FriendBailManager.GetBail(__instance.DeadPlayer);
				}
				PlayerUI.SetLookAtText("<color=#FF5555>САМОВОСКРЕШЕНИЕ ЗАБЛОКИРОВАНО!</color>\n" + FriendBailManager.GetBailStatusString(bail), (Transform)null, default(Vector3), false);
				return false;
			}
			return true;
		}

		[HarmonyPatch("LocalRespawn")]
		[HarmonyPrefix]
		public static bool LocalRespawnPrefix()
		{
			if (ShouldBlockSelfRespawn())
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static void UpdatePrefix(PlayerDying __instance, ref bool ____isGivingUp, ref float ____curGiveUpTime)
		{
			if (ShouldBlockSelfRespawn() && __instance.IsDead && ____isGivingUp)
			{
				____isGivingUp = false;
				____curGiveUpTime = 0f;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerDying))]
	public static class VoiceFilterPatch
	{
		private const float DeadPitch = 0.8f;

		private const float NormalPitch = 1f;

		[HarmonyPatch("DeathEffects")]
		[HarmonyPostfix]
		public static void DeathEffectsPostfix(PlayerDying __instance, Player ____player)
		{
			if ((Object)(object)____player != (Object)null && (Object)(object)____player.Mouth != (Object)null)
			{
				ApplyDeadVoiceEffects(____player.Mouth);
			}
		}

		[HarmonyPatch("ResurrectEffect")]
		[HarmonyPostfix]
		public static void ResurrectEffectPostfix(PlayerDying __instance, Player ____player)
		{
			if ((Object)(object)____player != (Object)null && (Object)(object)____player.Mouth != (Object)null)
			{
				RemoveDeadVoiceEffects(____player.Mouth);
			}
		}

		private static void ApplyDeadVoiceEffects(PlayerMouth mouth)
		{
			AudioSource value = Traverse.Create((object)mouth).Field("_voiceChatSource").GetValue<AudioSource>();
			if (!((Object)(object)value == (Object)null))
			{
				value.pitch = 0.8f;
				AudioLowPassFilter val = ((Component)value).gameObject.GetComponent<AudioLowPassFilter>();
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)value).gameObject.AddComponent<AudioLowPassFilter>();
				}
				((Behaviour)val).enabled = true;
				val.cutoffFrequency = 1400f;
				AudioEchoFilter val2 = ((Component)value).gameObject.GetComponent<AudioEchoFilter>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)value).gameObject.AddComponent<AudioEchoFilter>();
				}
				((Behaviour)val2).enabled = true;
				val2.delay = 200f;
				val2.decayRatio = 0.45f;
				val2.wetMix = 0.6f;
				val2.dryMix = 0.8f;
				AudioReverbFilter val3 = ((Component)value).gameObject.GetComponent<AudioReverbFilter>();
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = ((Component)value).gameObject.AddComponent<AudioReverbFilter>();
				}
				((Behaviour)val3).enabled = true;
				val3.reverbPreset = (AudioReverbPreset)9;
			}
		}

		private static void RemoveDeadVoiceEffects(PlayerMouth mouth)
		{
			AudioSource value = Traverse.Create((object)mouth).Field("_voiceChatSource").GetValue<AudioSource>();
			if (!((Object)(object)value == (Object)null))
			{
				value.pitch = 1f;
				AudioLowPassFilter component = ((Component)value).gameObject.GetComponent<AudioLowPassFilter>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
				}
				AudioEchoFilter component2 = ((Component)value).gameObject.GetComponent<AudioEchoFilter>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = false;
				}
				AudioReverbFilter component3 = ((Component)value).gameObject.GetComponent<AudioReverbFilter>();
				if ((Object)(object)component3 != (Object)null)
				{
					((Behaviour)component3).enabled = false;
				}
			}
		}
	}
}