Decompiled source of VeryBalancedRoundsMod v0.16.0

VeryBalancedRoundsMod.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModdingUtils.Patches;
using ModdingUtils.Utils;
using Photon.Pun;
using RarityLib.Utils;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnboundLib.Utils;
using UnityEngine;
using UnityEngine.UI;
using VeryBalancedRoundsMod.Cards;
using VeryBalancedRoundsMod.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("VeryBalancedRoundsMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.16.0.0")]
[assembly: AssemblyInformationalVersion("0.16.0+76a7b9d6cede22c0ebb3484232b43afa9e7896b8")]
[assembly: AssemblyProduct("VeryBalancedRoundsMod")]
[assembly: AssemblyTitle("VeryBalancedRoundsMod")]
[assembly: AssemblyVersion("0.16.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 VeryBalancedRoundsMod
{
	internal class BananaRest : FightScoped
	{
		internal const float StillSeconds = 5f;

		internal const float HealPerSecond = 0.1f;

		private const float StillThreshold = 0.03f;

		private Vector2 lastPosition;

		private float stillFor;

		private bool tracking;

		protected override void OnFightStart()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			lastPosition = Vector2.op_Implicit(((Component)base.Owner).transform.position);
			stillFor = 0f;
			tracking = true;
		}

		protected override void OnFightTick()
		{
			//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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!tracking)
			{
				return;
			}
			int num = CardTools.CountCards(base.Owner, "Banana");
			if (num <= 0)
			{
				return;
			}
			Vector2 val = Vector2.op_Implicit(((Component)base.Owner).transform.position);
			bool num2 = Vector2.Distance(val, lastPosition) > 0.03f;
			lastPosition = val;
			if (num2)
			{
				stillFor = 0f;
				return;
			}
			stillFor += Time.deltaTime;
			if (!(stillFor < 5f) && (Object)(object)data.healthHandler != (Object)null)
			{
				data.healthHandler.Heal(data.maxHealth * 0.1f * (float)num * Time.deltaTime);
			}
		}

		protected override void OnFightEnd()
		{
			tracking = false;
		}

		protected override void ClearAccumulated()
		{
			stillFor = 0f;
		}

		internal static BananaRest Ensure(Player player)
		{
			return FightScoped.EnsureOn<BananaRest>(player);
		}
	}
	internal class BlackHole : FightScoped
	{
		internal const float Radius = 10f;

		internal const float PullStrength = 1f;

		private void FixedUpdate()
		{
			//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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			if (!base.Fighting)
			{
				return;
			}
			int num = CardTools.CountCards(base.Owner, "Black Hole");
			if (num <= 0)
			{
				return;
			}
			Vector2 val = Vector2.op_Implicit(((Component)base.Owner).transform.position);
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val2 = list[i];
				if (CardTools.IsHostile(base.Owner, val2) && CardTools.IsFighting(val2) && CardTools.IsMine(val2) && !((Object)(object)val2.data.movement == (Object)null))
				{
					Vector2 val3 = val - Vector2.op_Implicit(((Component)val2).transform.position);
					float magnitude = ((Vector2)(ref val3)).magnitude;
					if (!(magnitude > 10f) && !(magnitude < 0.01f))
					{
						float num2 = val2.data.movement.force * 1f * (float)num;
						PlayerPhysics.AddForce(val2, val3 / magnitude * num2);
					}
				}
			}
		}

		internal static BlackHole Ensure(Player player)
		{
			return FightScoped.EnsureOn<BlackHole>(player);
		}
	}
	internal class ChrisTimer : FightScoped
	{
		internal const float Deadline = 7f;

		private bool fired;

		protected override void OnFightTick()
		{
			if (!fired && !(base.Elapsed < 7f) && CardTools.HasCard(base.Owner, "Chris's Side Project"))
			{
				fired = true;
				CardTools.Kill(base.Owner);
			}
		}

		protected override void ClearAccumulated()
		{
			fired = false;
		}

		protected override void OnFightEnd()
		{
			fired = false;
		}

		internal static ChrisTimer Ensure(Player player)
		{
			return FightScoped.EnsureOn<ChrisTimer>(player);
		}
	}
	internal class CigaretteBurn : FightScoped
	{
		internal const float HealthLossPerSecond = 0.05f;

		private const float Interval = 0.25f;

		private float pending;

		protected override void OnFightTick()
		{
			if (!CardTools.IsMine(base.Owner))
			{
				return;
			}
			int num = CardTools.CountCards(base.Owner, "500 Cigarettes");
			if (num <= 0 || data.maxHealth <= 0f || LastBreath.IsActiveOn(base.Owner))
			{
				pending = 0f;
				return;
			}
			pending += Time.deltaTime;
			while (pending >= 0.25f)
			{
				pending -= 0.25f;
				float num2 = data.maxHealth * 0.05f * 0.25f * (float)num;
				NetworkingManager.RPC(typeof(CigaretteBurn), "RPCA_LoseHealth", new object[2]
				{
					base.Owner.playerID,
					num2
				});
			}
		}

		protected override void OnFightEnd()
		{
			pending = 0f;
		}

		protected override void ClearAccumulated()
		{
			pending = 0f;
		}

		internal static void SendSmokeHeal(Player player, float amount)
		{
			if (!((Object)(object)player == (Object)null) && !(amount <= 0f))
			{
				NetworkingManager.RPC(typeof(CigaretteBurn), "RPCA_SmokeHeal", new object[2] { player.playerID, amount });
			}
		}

		[UnboundRPC]
		private static void RPCA_LoseHealth(int playerID, float amount)
		{
			Player val = PlayerWithID(playerID);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null) && !val.data.dead)
			{
				CharacterData obj = val.data;
				obj.health -= amount;
				if (val.data.health <= 0f)
				{
					CardTools.Kill(val);
				}
			}
		}

		[UnboundRPC]
		private static void RPCA_SmokeHeal(int playerID, float amount)
		{
			Player val = PlayerWithID(playerID);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null) && !val.data.dead && (Object)(object)val.data.healthHandler != (Object)null)
			{
				val.data.healthHandler.Heal(amount);
			}
		}

		private static Player PlayerWithID(int playerID)
		{
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				if ((Object)(object)list[i] != (Object)null && list[i].playerID == playerID)
				{
					return list[i];
				}
			}
			return null;
		}

		internal static CigaretteBurn Ensure(Player player)
		{
			return FightScoped.EnsureOn<CigaretteBurn>(player);
		}
	}
	internal class ContactDamage : FightScoped
	{
		internal const float DamageFraction = 0.5f;

		private readonly HashSet<int> touching = new HashSet<int>();

		protected override void OnFightTick()
		{
			//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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			int num = CardTools.CountCards(base.Owner, "MTG Player");
			if (num <= 0 || (Object)(object)data.mainCol == (Object)null)
			{
				return;
			}
			Bounds bounds = data.mainCol.bounds;
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val = list[i];
				if (!CardTools.IsHostile(base.Owner, val) || !CardTools.IsFighting(val) || (Object)(object)val.data.mainCol == (Object)null)
				{
					continue;
				}
				if (!((Bounds)(ref bounds)).Intersects(val.data.mainCol.bounds))
				{
					touching.Remove(val.playerID);
				}
				else
				{
					if (!touching.Add(val.playerID) || !CardTools.IsMine(base.Owner))
					{
						continue;
					}
					float num2 = CardTools.BulletDamage(base.Owner) * 0.5f * (float)num;
					if (!(num2 <= 0f))
					{
						Vector2 val2 = Vector2.op_Implicit(((Component)val).transform.position);
						Vector2 val3 = val2 - Vector2.op_Implicit(((Component)base.Owner).transform.position);
						if (val3 == Vector2.zero)
						{
							val3 = Vector2.up;
						}
						((Damagable)val.data.healthHandler).CallTakeDamage(((Vector2)(ref val3)).normalized * num2, val2, (GameObject)null, base.Owner, true);
					}
				}
			}
		}

		protected override void OnFightEnd()
		{
			touching.Clear();
		}

		protected override void ClearAccumulated()
		{
			touching.Clear();
		}

		internal static ContactDamage Ensure(Player player)
		{
			return FightScoped.EnsureOn<ContactDamage>(player);
		}
	}
	internal class DiscordMod : FightScoped
	{
		internal const float Radius = 8f;

		internal const float PushStrength = 1.5f;

		private void FixedUpdate()
		{
			//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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			if (!base.Fighting)
			{
				return;
			}
			int num = CardTools.CountCards(base.Owner, "Discord Mod");
			if (num <= 0)
			{
				return;
			}
			Vector2 val = Vector2.op_Implicit(((Component)base.Owner).transform.position);
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val2 = list[i];
				if (!CardTools.IsHostile(base.Owner, val2) || !CardTools.IsFighting(val2) || !CardTools.IsMine(val2) || (Object)(object)val2.data.movement == (Object)null)
				{
					continue;
				}
				Vector2 val3 = Vector2.op_Implicit(((Component)val2).transform.position) - val;
				float magnitude = ((Vector2)(ref val3)).magnitude;
				if (!(magnitude > 8f))
				{
					if (magnitude < 0.01f)
					{
						val3 = Vector2.up;
					}
					float num2 = 1f - Mathf.Clamp01(magnitude / 8f);
					float num3 = val2.data.movement.force * 1.5f * num2 * (float)num;
					PlayerPhysics.AddForce(val2, ((Vector2)(ref val3)).normalized * num3);
				}
			}
		}

		internal static DiscordMod Ensure(Player player)
		{
			return FightScoped.EnsureOn<DiscordMod>(player);
		}
	}
	internal abstract class FightScoped : MonoBehaviour, IPointReset, IStatReset
	{
		protected CharacterData data;

		private bool wasFighting;

		protected float Elapsed { get; private set; }

		protected bool Fighting => wasFighting;

		protected Player Owner
		{
			get
			{
				if (!((Object)(object)data == (Object)null))
				{
					return data.player;
				}
				return null;
			}
		}

		protected virtual void Awake()
		{
			data = ((Component)this).GetComponent<CharacterData>();
			if ((Object)(object)data == (Object)null)
			{
				data = ((Component)this).GetComponentInParent<CharacterData>();
			}
		}

		private void Update()
		{
			if (!((Object)(object)data == (Object)null) && !((Object)(object)data.player == (Object)null))
			{
				bool flag = data.isPlaying && !data.dead;
				if (flag && !wasFighting)
				{
					wasFighting = true;
					Elapsed = 0f;
					OnFightStart();
				}
				else if (!flag && wasFighting)
				{
					EndFight();
				}
				if (flag)
				{
					Elapsed += Time.deltaTime;
					OnFightTick();
				}
			}
		}

		private void OnDisable()
		{
			if (wasFighting && (Object)(object)data != (Object)null && data.dead)
			{
				EndFight();
			}
		}

		private void EndFight()
		{
			wasFighting = false;
			OnFightEnd();
		}

		protected virtual void OnFightStart()
		{
		}

		protected virtual void OnFightEnd()
		{
		}

		protected virtual void OnFightTick()
		{
		}

		protected virtual void ClearAccumulated()
		{
		}

		protected virtual void ForgetApplied()
		{
		}

		public void ResetForPoint()
		{
			if (wasFighting)
			{
				EndFight();
			}
			Elapsed = 0f;
			ClearAccumulated();
		}

		public void OnStatsReset()
		{
			wasFighting = false;
			Elapsed = 0f;
			ForgetApplied();
			ClearAccumulated();
		}

		protected static T EnsureOn<T>(Player player) where T : FightScoped
		{
			T component = ((Component)player).GetComponent<T>();
			if (!((Object)(object)component != (Object)null))
			{
				return ((Component)player).gameObject.AddComponent<T>();
			}
			return component;
		}
	}
	internal class HighRarityPicks : MonoBehaviour
	{
		internal const int PicksGranted = 3;

		private bool offeredThisPhase;

		internal int PicksRemaining { get; private set; }

		internal void Grant()
		{
			PicksRemaining = 3;
			offeredThisPhase = false;
		}

		internal void MarkOffered()
		{
			offeredThisPhase = true;
		}

		internal void EndPickPhase()
		{
			if (offeredThisPhase && PicksRemaining > 0)
			{
				PicksRemaining--;
			}
			offeredThisPhase = false;
		}

		internal static HighRarityPicks EnsureOn(Player player)
		{
			HighRarityPicks highRarityPicks = ((Component)player).GetComponent<HighRarityPicks>();
			if ((Object)(object)highRarityPicks == (Object)null)
			{
				highRarityPicks = ((Component)player).gameObject.AddComponent<HighRarityPicks>();
			}
			return highRarityPicks;
		}

		internal static bool IsActiveOn(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			HighRarityPicks component = ((Component)player).GetComponent<HighRarityPicks>();
			if ((Object)(object)component != (Object)null && component.PicksRemaining > 0)
			{
				return CardTools.HasCard(player, "Touch the Wall");
			}
			return false;
		}
	}
	internal class IconOfSinRamp : FightScoped
	{
		internal const float GrowthPerSecond = 0.05f;

		private float appliedGrowth = 1f;

		internal float Growth
		{
			get
			{
				if (!base.Fighting || !CardTools.HasCard(base.Owner, "Icon of Sin"))
				{
					return 1f;
				}
				return Mathf.Min(1000f, Mathf.Pow(1.05f, base.Elapsed));
			}
		}

		internal float Shrink
		{
			get
			{
				if (!base.Fighting || !CardTools.HasCard(base.Owner, "Icon of Sin"))
				{
					return 1f;
				}
				return Mathf.Max(0.001f, Mathf.Pow(0.95f, base.Elapsed));
			}
		}

		protected override void OnFightTick()
		{
			Retarget(Growth);
		}

		protected override void OnFightEnd()
		{
			Retarget(1f);
		}

		protected override void ForgetApplied()
		{
			appliedGrowth = 1f;
		}

		private void Retarget(float growth)
		{
			if ((Object)(object)data == (Object)null)
			{
				return;
			}
			if (appliedGrowth <= 0f)
			{
				appliedGrowth = 1f;
			}
			if (growth <= 0f)
			{
				growth = 1f;
			}
			float num = growth / appliedGrowth;
			appliedGrowth = growth;
			if (num != 1f)
			{
				float num2 = data.maxHealth * num;
				float num3 = num2 - data.maxHealth;
				data.maxHealth = num2;
				if (num3 > 0f)
				{
					CharacterData obj = data;
					obj.health += num3;
				}
				else if (data.health > data.maxHealth)
				{
					data.health = data.maxHealth;
				}
			}
		}

		internal static IconOfSinRamp Ensure(Player player)
		{
			return FightScoped.EnsureOn<IconOfSinRamp>(player);
		}

		internal static IconOfSinRamp On(Player player)
		{
			if (!((Object)(object)player == (Object)null))
			{
				return ((Component)player).GetComponent<IconOfSinRamp>();
			}
			return null;
		}
	}
	internal class InfinitySlow : MonoBehaviour
	{
		private const float FrozenTrailTime = 3600f;

		private const float MinStreak = 0.6f;

		private MoveTransform move;

		private RemoveAfterSeconds lifetime;

		private TrailRenderer[] trails;

		private float[] trailTimes;

		private float baseMultiplier;

		private float frozenSeconds;

		private bool captured;

		private bool frozen;

		private void Awake()
		{
			move = ((Component)this).GetComponent<MoveTransform>();
			lifetime = ((Component)this).GetComponent<RemoveAfterSeconds>();
			Capture();
		}

		private void Capture()
		{
			if (!captured && !((Object)(object)move == (Object)null))
			{
				baseMultiplier = move.multiplier;
				captured = true;
			}
		}

		internal void Freeze()
		{
			Capture();
			if ((Object)(object)move == (Object)null)
			{
				return;
			}
			move.multiplier = 0f;
			if (!frozen)
			{
				frozen = true;
				HoldTrails();
				if ((Object)(object)lifetime != (Object)null)
				{
					frozenSeconds = lifetime.seconds;
				}
			}
			if ((Object)(object)lifetime != (Object)null && lifetime.seconds < frozenSeconds)
			{
				lifetime.seconds = frozenSeconds;
			}
		}

		private void HoldTrails()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			trails = ((Component)this).GetComponentsInChildren<TrailRenderer>();
			trailTimes = new float[trails.Length];
			Vector3 velocity = move.velocity;
			float magnitude = ((Vector3)(ref velocity)).magnitude;
			Vector3 val = ((magnitude > 0.001f) ? (velocity / magnitude) : Vector3.zero);
			for (int i = 0; i < trails.Length; i++)
			{
				TrailRenderer val2 = trails[i];
				if (!((Object)(object)val2 == (Object)null))
				{
					trailTimes[i] = val2.time;
					if (val != Vector3.zero && magnitude * val2.time < 0.6f)
					{
						val2.AddPosition(((Component)val2).transform.position - val * 0.6f);
					}
					val2.time = 3600f;
				}
			}
		}

		internal void Release()
		{
			if (captured && (Object)(object)move != (Object)null)
			{
				move.multiplier = baseMultiplier;
			}
			if (trails != null)
			{
				for (int i = 0; i < trails.Length; i++)
				{
					if ((Object)(object)trails[i] != (Object)null && trails[i].time == 3600f)
					{
						trails[i].time = trailTimes[i];
					}
				}
			}
			Object.Destroy((Object)(object)this);
		}
	}
	internal class InvisibleBullet : MonoBehaviour
	{
		private const int SweepFrames = 5;

		private int framesLeft = 5;

		private void Awake()
		{
			Hide();
		}

		private void LateUpdate()
		{
			if (framesLeft > 0)
			{
				framesLeft--;
				Hide();
			}
		}

		private void Hide()
		{
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			Light[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Light>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				((Behaviour)componentsInChildren2[j]).enabled = false;
			}
		}
	}
	internal class KilldozerContact : FightScoped
	{
		internal const float ReferenceSpeed = 18f;

		private const float BaseHealth = 100f;

		private readonly HashSet<int> touching = new HashSet<int>();

		protected override void OnFightTick()
		{
			//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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			int num = CardTools.CountCards(base.Owner, "Killdozer");
			if (num <= 0 || (Object)(object)data.mainCol == (Object)null)
			{
				return;
			}
			Bounds bounds = data.mainCol.bounds;
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val = list[i];
				if (!CardTools.IsHostile(base.Owner, val) || !CardTools.IsFighting(val) || (Object)(object)val.data.mainCol == (Object)null)
				{
					continue;
				}
				if (!((Bounds)(ref bounds)).Intersects(val.data.mainCol.bounds))
				{
					touching.Remove(val.playerID);
				}
				else
				{
					if (!touching.Add(val.playerID) || !CardTools.IsMine(base.Owner))
					{
						continue;
					}
					Vector2 val2 = PlayerPhysics.CurrentVelocity(base.Owner);
					float magnitude = ((Vector2)(ref val2)).magnitude;
					float num2 = CardTools.BulletDamage(base.Owner) * (magnitude / 18f) * 1.8181819f * (float)num;
					if (!(num2 <= 0f))
					{
						Vector2 val3 = Vector2.op_Implicit(((Component)val).transform.position);
						Vector2 val4 = val3 - Vector2.op_Implicit(((Component)base.Owner).transform.position);
						if (val4 == Vector2.zero)
						{
							val4 = Vector2.up;
						}
						((Damagable)val.data.healthHandler).CallTakeDamage(((Vector2)(ref val4)).normalized * num2, val3, (GameObject)null, base.Owner, true);
					}
				}
			}
		}

		protected override void OnFightEnd()
		{
			touching.Clear();
		}

		protected override void ClearAccumulated()
		{
			touching.Clear();
		}

		internal static KilldozerContact Ensure(Player player)
		{
			return FightScoped.EnsureOn<KilldozerContact>(player);
		}
	}
	internal class LastBreath : FightScoped
	{
		internal const float TriggerFraction = 0.2f;

		internal const float Duration = 5f;

		internal const float BuffMultiplier = 2f;

		private float endTime;

		private bool usedThisPoint;

		internal bool Active { get; private set; }

		protected override void OnFightTick()
		{
			if (Active)
			{
				if (Time.time >= endTime)
				{
					Expire();
				}
			}
			else if (!usedThisPoint && CardTools.HasCard(base.Owner, "The Last Breath") && !((Object)(object)data == (Object)null) && !(data.maxHealth <= 0f) && data.health / data.maxHealth <= 0.2f)
			{
				Trigger();
			}
		}

		private void Trigger()
		{
			usedThisPoint = true;
			Active = true;
			endTime = Time.time + 5f;
			data.health = data.maxHealth;
		}

		private void Expire()
		{
			Active = false;
			CardTools.Kill(base.Owner);
		}

		protected override void OnFightEnd()
		{
			Active = false;
		}

		protected override void ForgetApplied()
		{
			Active = false;
		}

		protected override void ClearAccumulated()
		{
			usedThisPoint = false;
			endTime = 0f;
		}

		internal static LastBreath Ensure(Player player)
		{
			return FightScoped.EnsureOn<LastBreath>(player);
		}

		internal static bool IsActiveOn(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			LastBreath component = ((Component)player).GetComponent<LastBreath>();
			if ((Object)(object)component != (Object)null)
			{
				return component.Active;
			}
			return false;
		}
	}
	internal class MahoragaAdaptation : MonoBehaviour, IPointReset
	{
		internal const float ReductionPerHit = 0.1f;

		private int hitsTaken;

		internal float GetMultiplier(int stacks)
		{
			if (stacks <= 0 || hitsTaken <= 0)
			{
				return 1f;
			}
			return Mathf.Pow(0.9f, (float)(hitsTaken * stacks));
		}

		internal void RegisterHit()
		{
			hitsTaken++;
		}

		public void ResetForPoint()
		{
			hitsTaken = 0;
		}

		internal static float MultiplierFor(Player victim)
		{
			int num = CardTools.CountCards(victim, "Eight Handled Sword Divine General Mahoraga");
			if (num <= 0)
			{
				return 1f;
			}
			MahoragaAdaptation component = ((Component)victim).GetComponent<MahoragaAdaptation>();
			if (!((Object)(object)component == (Object)null))
			{
				return component.GetMultiplier(num);
			}
			return 1f;
		}

		internal static void RegisterHitOn(Player victim)
		{
			if (CardTools.HasCard(victim, "Eight Handled Sword Divine General Mahoraga"))
			{
				MahoragaAdaptation component = ((Component)victim).GetComponent<MahoragaAdaptation>();
				if ((Object)(object)component != (Object)null)
				{
					component.RegisterHit();
				}
			}
		}
	}
	internal class ParticleAccelerator : FightScoped
	{
		internal const float SpeedPerHit = 0.5f;

		private int hits;

		internal float SpeedMultiplier
		{
			get
			{
				if (!base.Fighting || hits <= 0)
				{
					return 1f;
				}
				int num = CardTools.CountCards(base.Owner, "Particle Accelerator");
				if (num <= 0)
				{
					return 1f;
				}
				return Mathf.Min(1000f, Mathf.Pow(1.5f, (float)(hits * num)));
			}
		}

		protected override void ClearAccumulated()
		{
			hits = 0;
		}

		internal void RegisterHit()
		{
			hits++;
		}

		internal static ParticleAccelerator Ensure(Player player)
		{
			return FightScoped.EnsureOn<ParticleAccelerator>(player);
		}
	}
	internal class PatienceHold : FightScoped
	{
		internal bool Locked
		{
			get
			{
				if (base.Fighting)
				{
					return base.Elapsed < 3f;
				}
				return false;
			}
		}

		internal static PatienceHold Ensure(Player player)
		{
			return FightScoped.EnsureOn<PatienceHold>(player);
		}
	}
	internal class PointTimer : MonoBehaviour, IPointReset
	{
		private CharacterData data;

		private bool wasPlaying;

		internal float Elapsed { get; private set; }

		private void Awake()
		{
			data = ((Component)this).GetComponent<CharacterData>();
			if ((Object)(object)data == (Object)null)
			{
				data = ((Component)this).GetComponentInParent<CharacterData>();
			}
		}

		private void Update()
		{
			if (!((Object)(object)data == (Object)null))
			{
				bool flag = data.isPlaying && !data.dead;
				if (flag && !wasPlaying)
				{
					Elapsed = 0f;
				}
				if (flag)
				{
					Elapsed += Time.deltaTime;
				}
				wasPlaying = flag;
			}
		}

		internal void ResetTimer()
		{
			Elapsed = 0f;
		}

		public void ResetForPoint()
		{
			ResetTimer();
		}

		internal static PointTimer EnsureOn(Player player)
		{
			PointTimer pointTimer = ((Component)player).GetComponent<PointTimer>();
			if ((Object)(object)pointTimer == (Object)null)
			{
				pointTimer = ((Component)player).gameObject.AddComponent<PointTimer>();
			}
			return pointTimer;
		}
	}
	internal class TreeAnchor : FightScoped
	{
		private Vector2 anchor;

		private bool anchored;

		protected override void OnFightTick()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!anchored && CardTools.IsMine(base.Owner) && TreeCard.IsRooted(base.Owner) && data.isGrounded)
			{
				anchor = data.playerVel.position;
				anchored = true;
			}
		}

		private void FixedUpdate()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (anchored && base.Fighting && CardTools.IsMine(base.Owner) && TreeCard.IsRooted(base.Owner))
			{
				PlayerPhysics.Teleport(base.Owner, anchor);
			}
		}

		protected override void OnFightEnd()
		{
			anchored = false;
		}

		protected override void ClearAccumulated()
		{
			anchored = false;
		}

		internal static TreeAnchor Ensure(Player player)
		{
			return FightScoped.EnsureOn<TreeAnchor>(player);
		}
	}
	internal class WanderingBullet : MonoBehaviour
	{
		private const float MaxTurnRate = 720f;

		private const float Frequency = 3f;

		private MoveTransform move;

		private float noiseRow;

		private float age;

		internal void Init(float randomSeed)
		{
			move = ((Component)this).GetComponent<MoveTransform>();
			noiseRow = randomSeed * 997f;
		}

		private void Update()
		{
			//IL_006b: 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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)move == (Object)null))
			{
				float num = TimeHandler.deltaTime * move.multiplier;
				if (!(num <= 0f))
				{
					age += num;
					float num2 = (Mathf.PerlinNoise(noiseRow, age * 3f) * 2f - 1f) * 720f * num;
					move.velocity = Quaternion.AngleAxis(num2, Vector3.forward) * move.velocity;
				}
			}
		}
	}
	internal static class BulletHit
	{
		private static bool pending;

		private static Player shooter;

		private static Player victim;

		private static float impactSpeed;

		private static bool crit;

		internal static void Begin(Player hitShooter, Player hitVictim, float speed, bool isCrit)
		{
			pending = true;
			shooter = hitShooter;
			victim = hitVictim;
			impactSpeed = speed;
			crit = isCrit;
		}

		internal static void End()
		{
			pending = false;
			shooter = null;
			victim = null;
			impactSpeed = 0f;
			crit = false;
		}

		internal static bool TryClaim(Player attacker, Player target, out float speed, out bool isCrit)
		{
			speed = 0f;
			isCrit = false;
			if (!pending || (Object)(object)attacker == (Object)null || (Object)(object)target == (Object)null)
			{
				return false;
			}
			if ((Object)(object)attacker != (Object)(object)shooter || (Object)(object)target != (Object)(object)victim)
			{
				return false;
			}
			speed = impactSpeed;
			isCrit = crit;
			End();
			return true;
		}
	}
	internal static class CardArt
	{
		private static readonly Dictionary<string, string> resourceByCard = new Dictionary<string, string>
		{
			{ "McDonalds", "mcdonalds.jpg" },
			{ "Gremlin", "gremlin.jpg" },
			{ "Bird Killer", "birdkiller.jpg" },
			{ "Inevitable", "inevitable.jpg" },
			{ "Ihateblockbuild", "blockhater.jpg" },
			{ "Iloveblockbuild", "blocklover.jpg" },
			{ "Eight Handled Sword Divine General Mahoraga", "mahoraga.jpg" },
			{ "Titan Killer", "titankiller.jpg" },
			{ "Glasser Cannon", "glassercannon.jpg" },
			{ "Balanced", "balanced.jpg" },
			{ "Rev Up", "revup.jpg" },
			{ "Giga Drum Mag", "gigadrummag.jpg" },
			{ "Card Counter", "cardcounter.jpg" },
			{ "Random Crits", "randomcrits.jpg" },
			{ "Infinity", "infinity.jpg" },
			{ "Sword", "sword.jpg" },
			{ "Conner's Pride", "connerspride.jpg" },
			{ "The Last Breath", "lastbreath.jpg" },
			{ "Fraud", "fraud.jpg" },
			{ "Prestige", "prestige.jpg" },
			{ "Touch the Wall", "touchthewall.jpg" },
			{ "Whipped", "whipped.jpg" },
			{ "Super Quick Reload", "superquickreload.jpg" },
			{ "Icon of Sin", "iconofsin.jpg" },
			{ "Particle Accelerator", "particleaccelerator.jpg" },
			{ "Density", "density.jpg" },
			{ "MTG Player", "mtgplayer.jpg" },
			{ "Black Hole", "blackhole.jpg" },
			{ "Invisible Bullets", "invisiblebullets.jpg" },
			{ "Tree", "tree.jpg" },
			{ "Chris's Side Project", "chrissideproject.jpg" },
			{ "The Kirk Special", "kirkspecial.jpg" },
			{ "Portal Gun", "portalgun.jpg" },
			{ "Lowe's Worker", "lowesworker.jpg" },
			{ "Leg Day", "legday.jpg" },
			{ "AK", "ak.jpg" },
			{ "Go Blue", "goblue.jpg" },
			{ "Claude's Choice", "claudeschoice.jpg" },
			{ "Up", "up.jpg" },
			{ "Down", "down.jpg" },
			{ "Conner Hack Special", "connerhackspecial.jpg" },
			{ "Onceler", "onceler.jpg" },
			{ "Banana", "banana.jpg" },
			{ "Xane's Wire Management", "xaneswiremanagement.jpg" },
			{ "Border Hop", "borderhop.jpg" },
			{ "Ronald McDonald", "ronaldmcdonald.jpg" },
			{ "Hitscan", "hitscan.jpg" },
			{ "Railgun", "railgun.jpg" },
			{ "Discord Mod", "discordmod.jpg" },
			{ "Hollow Purple", "hollowpurple.jpg" },
			{ "Dense Bullets", "densebullets.jpg" },
			{ "The Block Build Special", "blockbuildspecial.jpg" },
			{ "Killdozer", "killdozer.jpg" },
			{ "Shulker", "shulker.jpg" },
			{ "Drone Strike", "dronestrike.jpg" },
			{ "C-Ram", "cram.jpg" },
			{ "The Island", "theisland.jpg" },
			{ "The Lorax", "thelorax.jpg" },
			{ "Super Shotgun", "supershotgun.jpg" },
			{ "500 Cigarettes", "500cigarettes.jpg" },
			{ "Atomic Bomb", "atomicbomb.jpg" },
			{ "ASU Frat Leader", "asufratleader.jpg" },
			{ "The Flavorful Garlic", "flavorfulgarlic.jpg" },
			{ "Projectile Dysfunction", "projectiledysfunction.jpg" },
			{ "Rare Artifact", "rareartifact.jpg" },
			{ "Legendary Artifact", "legendaryartifact.jpg" },
			{ "Daedalus Stormbow", "daedalusstormbow.jpg" },
			{ "Patience", "patience.jpg" }
		};

		private static readonly Dictionary<string, GameObject> cache = new Dictionary<string, GameObject>();

		private static GameObject templateRoot;

		internal static GameObject For(string cardTitle)
		{
			if (string.IsNullOrEmpty(cardTitle))
			{
				return null;
			}
			if (!resourceByCard.TryGetValue(cardTitle, out var value))
			{
				return null;
			}
			if (cache.TryGetValue(value, out var value2))
			{
				return value2;
			}
			GameObject val = Build(value);
			cache[value] = val;
			return val;
		}

		private static GameObject Build(string resourceName)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0120: 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_0145: Expected O, but got Unknown
			byte[] array = ReadResource(resourceName);
			if (array == null)
			{
				Debug.LogWarning("[VeryBalancedRoundsMod] card art resource missing: " + resourceName);
				return null;
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, array))
			{
				Debug.LogWarning("[VeryBalancedRoundsMod] could not decode card art: " + resourceName);
				Object.Destroy((Object)(object)val);
				return null;
			}
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)61;
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			((Object)val2).hideFlags = (HideFlags)61;
			GameObject val3 = new GameObject("VBArt_" + resourceName, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val3.transform.SetParent(EnsureTemplateRoot().transform, false);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			component.pivot = new Vector2(0.5f, 0.5f);
			Image component2 = val3.GetComponent<Image>();
			component2.sprite = val2;
			component2.preserveAspect = true;
			((Graphic)component2).raycastTarget = false;
			return val3;
		}

		private static GameObject EnsureTemplateRoot()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if ((Object)(object)templateRoot != (Object)null)
			{
				return templateRoot;
			}
			templateRoot = new GameObject("VeryBalancedRoundsMod_CardArt");
			Object.DontDestroyOnLoad((Object)(object)templateRoot);
			templateRoot.SetActive(false);
			return templateRoot;
		}

		private static byte[] ReadResource(string name)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			int i;
			int num;
			for (i = 0; i < array.Length; i += num)
			{
				num = stream.Read(array, i, array.Length - i);
				if (num <= 0)
				{
					break;
				}
			}
			return (i == array.Length) ? array : null;
		}
	}
	internal static class CardNames
	{
		public const string McDonalds = "McDonalds";

		public const string Gremlin = "Gremlin";

		public const string BirdKiller = "Bird Killer";

		public const string Inevitable = "Inevitable";

		public const string BlockHater = "Ihateblockbuild";

		public const string BlockLover = "Iloveblockbuild";

		public const string Mahoraga = "Eight Handled Sword Divine General Mahoraga";

		public const string TitanKiller = "Titan Killer";

		public const string GlasserCannon = "Glasser Cannon";

		public const string Balanced = "Balanced";

		public const string RevUp = "Rev Up";

		public const string GigaDrumMag = "Giga Drum Mag";

		public const string CardCounter = "Card Counter";

		public const string RandomCrits = "Random Crits";

		public const string Infinity = "Infinity";

		public const string Sword = "Sword";

		public const string ConnersPride = "Conner's Pride";

		public const string LastBreath = "The Last Breath";

		public const string Fraud = "Fraud";

		public const string Prestige = "Prestige";

		public const string TouchTheWall = "Touch the Wall";

		public const string Whipped = "Whipped";

		public const string SuperQuickReload = "Super Quick Reload";

		public const string IconOfSin = "Icon of Sin";

		public const string ParticleAccelerator = "Particle Accelerator";

		public const string Density = "Density";

		public const string MtgPlayer = "MTG Player";

		public const string BlackHole = "Black Hole";

		public const string InvisibleBullets = "Invisible Bullets";

		public const string Tree = "Tree";

		public const string ChrisSideProject = "Chris's Side Project";

		public const string KirkSpecial = "The Kirk Special";

		public const string PortalGun = "Portal Gun";

		public const string LowesWorker = "Lowe's Worker";

		public const string LegDay = "Leg Day";

		public const string AK = "AK";

		public const string GoBlue = "Go Blue";

		public const string ClaudesChoice = "Claude's Choice";

		public const string Up = "Up";

		public const string Down = "Down";

		public const string ConnerHackSpecial = "Conner Hack Special";

		public const string Onceler = "Onceler";

		public const string Banana = "Banana";

		public const string XanesWireManagement = "Xane's Wire Management";

		public const string BorderHop = "Border Hop";

		public const string RonaldMcDonald = "Ronald McDonald";

		public const string Hitscan = "Hitscan";

		public const string Railgun = "Railgun";

		public const string DiscordMod = "Discord Mod";

		public const string HollowPurple = "Hollow Purple";

		public const string DenseBullets = "Dense Bullets";

		public const string BlockBuildSpecial = "The Block Build Special";

		public const string Killdozer = "Killdozer";

		public const string Shulker = "Shulker";

		public const string DroneStrike = "Drone Strike";

		public const string CRam = "C-Ram";

		public const string TheIsland = "The Island";

		public const string TheLorax = "The Lorax";

		public const string SuperShotgun = "Super Shotgun";

		public const string FiveHundredCigarettes = "500 Cigarettes";

		public const string AtomicBomb = "Atomic Bomb";

		public const string AsuFratLeader = "ASU Frat Leader";

		public const string FlavorfulGarlic = "The Flavorful Garlic";

		public const string ProjectileDysfunction = "Projectile Dysfunction";

		public const string RareArtifact = "Rare Artifact";

		public const string LegendaryArtifact = "Legendary Artifact";

		public const string DaedalusStormbow = "Daedalus Stormbow";

		public const string Patience = "Patience";
	}
	internal static class CardTools
	{
		internal const float LethalDamage = 1000000f;

		internal const float BaseBulletDamage = 55f;

		internal static int CountCards(Player player, string cardName)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null)
			{
				return 0;
			}
			List<CardInfo> currentCards = player.data.currentCards;
			if (currentCards == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < currentCards.Count; i++)
			{
				if ((Object)(object)currentCards[i] != (Object)null && currentCards[i].cardName == cardName)
				{
					num++;
				}
			}
			return num;
		}

		internal static bool HasCard(Player player, string cardName)
		{
			return CountCards(player, cardName) > 0;
		}

		internal static bool IsHostile(Player attacker, Player victim)
		{
			if ((Object)(object)attacker != (Object)null && (Object)(object)victim != (Object)null)
			{
				return attacker.playerID != victim.playerID;
			}
			return false;
		}

		internal static bool IsMine(Player player)
		{
			if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.view != (Object)null)
			{
				return player.data.view.IsMine;
			}
			return false;
		}

		internal static bool IsFighting(Player player)
		{
			if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && player.data.isPlaying)
			{
				return !player.data.dead;
			}
			return false;
		}

		internal static List<Player> AllPlayers()
		{
			if ((Object)(object)PlayerManager.instance == (Object)null || PlayerManager.instance.players == null)
			{
				return new List<Player>();
			}
			return PlayerManager.instance.players;
		}

		internal static CardInfo FindCard(string cardName)
		{
			CardInfo val = null;
			foreach (Card value in CardManager.cards.Values)
			{
				CardInfo val2 = value?.cardInfo;
				if (!((Object)(object)val2 == (Object)null))
				{
					if (string.Equals(((Object)((Component)val2).gameObject).name, cardName, StringComparison.OrdinalIgnoreCase))
					{
						return val2;
					}
					if ((Object)(object)val == (Object)null && string.Equals(val2.cardName, cardName, StringComparison.OrdinalIgnoreCase))
					{
						val = val2;
					}
				}
			}
			return val;
		}

		internal static float BulletDamage(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || (Object)(object)player.data.weaponHandler == (Object)null)
			{
				return 0f;
			}
			Gun gun = player.data.weaponHandler.gun;
			if (!((Object)(object)gun == (Object)null))
			{
				return gun.damage * 55f;
			}
			return 0f;
		}

		internal static bool PointDecided()
		{
			if ((Object)(object)PlayerManager.instance != (Object)null)
			{
				return PlayerManager.instance.TeamsAlive() < 2;
			}
			return false;
		}

		internal static void Kill(Player player)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (IsMine(player) && IsFighting(player) && !((Object)(object)player.data.view == (Object)null) && !PointDecided())
			{
				player.data.view.RPC("RPCA_SendTakeDamage", (RpcTarget)0, new object[4]
				{
					(object)new Vector2(0f, 1000000f),
					Vector2.op_Implicit(((Component)player).transform.position),
					true,
					-1
				});
			}
		}
	}
	internal static class DamageMath
	{
		internal const float RampCap = 1000f;

		internal static float AttackerMultiplier(Player attacker, Player victim)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)attacker == (Object)null || (Object)(object)attacker.data == (Object)null)
			{
				return 1f;
			}
			float num = 1f;
			int num2 = CardTools.CountCards(attacker, "Inevitable");
			if (num2 > 0)
			{
				PointTimer component = ((Component)attacker).GetComponent<PointTimer>();
				if ((Object)(object)component != (Object)null)
				{
					num *= Mathf.Min(1000f, Mathf.Pow(1.05f, component.Elapsed * (float)num2));
				}
			}
			if (CardTools.HasCard(attacker, "Icon of Sin"))
			{
				IconOfSinRamp iconOfSinRamp = IconOfSinRamp.On(attacker);
				if ((Object)(object)iconOfSinRamp != (Object)null)
				{
					num *= iconOfSinRamp.Growth;
				}
			}
			int num3 = CardTools.CountCards(attacker, "Card Counter");
			if (num3 > 0)
			{
				int num4 = attacker.data.currentCards?.Count ?? 0;
				num *= 1f + 0.15f * (float)num4 * (float)num3;
			}
			if ((Object)(object)victim != (Object)null)
			{
				int num5 = CardTools.CountCards(attacker, "Lowe's Worker");
				if (num5 > 0 && ((Component)victim).transform.position.y < ((Component)attacker).transform.position.y)
				{
					num *= 1f + 1.5f * (float)num5;
				}
				int num6 = CardTools.CountCards(attacker, "Conner Hack Special");
				if (num6 > 0)
				{
					float distance = Vector2.Distance(Vector2.op_Implicit(((Component)attacker).transform.position), Vector2.op_Implicit(((Component)victim).transform.position));
					num *= Mathf.Pow(ConnerHackSpecialCard.MultiplierAt(distance), (float)num6);
				}
			}
			if (LastBreath.IsActiveOn(attacker))
			{
				num *= 2f;
			}
			if (float.IsNaN(num) || float.IsInfinity(num))
			{
				num = 1000f;
			}
			return num;
		}

		internal static float BulletDamage(Player attacker, Player victim, float gameDamage, float impactSpeed)
		{
			return (gameDamage + RailgunBonus(attacker, impactSpeed)) * AttackerMultiplier(attacker, victim) * AsuFratLeaderCard.DamageMultiplier(attacker, victim) + BulletFlatBonus(attacker);
		}

		internal static float RailgunBonus(Player attacker, float impactSpeed)
		{
			int num = CardTools.CountCards(attacker, "Railgun");
			if (num > 0)
			{
				return impactSpeed * 0.5f * (float)num;
			}
			return 0f;
		}

		internal static float BulletFlatBonus(Player attacker)
		{
			if ((Object)(object)attacker == (Object)null || (Object)(object)attacker.data == (Object)null)
			{
				return 0f;
			}
			int num = CardTools.CountCards(attacker, "Ronald McDonald");
			if (num > 0)
			{
				return attacker.data.health * 0.25f * (float)num;
			}
			return 0f;
		}
	}
	internal static class Explosions
	{
		private static readonly string[] preferredSources = new string[2] { "Supernova", "Explosive Bullet" };

		private static GameObject prefab;

		private static bool searchedPopulatedPool;

		internal static GameObject Prefab
		{
			get
			{
				if ((Object)(object)prefab != (Object)null)
				{
					return prefab;
				}
				if (searchedPopulatedPool)
				{
					return null;
				}
				CardChoice instance = CardChoice.instance;
				if ((Object)(object)instance == (Object)null || instance.cards == null || instance.cards.Length == 0)
				{
					return null;
				}
				searchedPopulatedPool = true;
				prefab = Find();
				return prefab;
			}
		}

		private static GameObject Find()
		{
			if ((Object)(object)CardChoice.instance == (Object)null || CardChoice.instance.cards == null)
			{
				return null;
			}
			GameObject result = null;
			int num = int.MaxValue;
			CardInfo[] cards = CardChoice.instance.cards;
			foreach (CardInfo val in cards)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Gun component = ((Component)val).GetComponent<Gun>();
				if ((Object)(object)component == (Object)null || component.objectsToSpawn == null)
				{
					continue;
				}
				ObjectsToSpawn[] objectsToSpawn = component.objectsToSpawn;
				foreach (ObjectsToSpawn val2 in objectsToSpawn)
				{
					if (val2 == null || (Object)(object)val2.effect == (Object)null || (Object)(object)val2.effect.GetComponent<Explosion>() == (Object)null)
					{
						continue;
					}
					int num2 = preferredSources.Length;
					for (int k = 0; k < preferredSources.Length; k++)
					{
						if (string.Equals(val.cardName, preferredSources[k], StringComparison.OrdinalIgnoreCase))
						{
							num2 = k;
							break;
						}
					}
					if (num2 < num)
					{
						num = num2;
						result = val2.effect;
						if (num2 == 0)
						{
							return result;
						}
					}
				}
			}
			return result;
		}

		internal static void Detonate(Player attacker, Vector2 position, float damage, float range)
		{
			//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			bool flag = CardTools.IsMine(attacker);
			GameObject val = Prefab;
			if ((Object)(object)val == (Object)null)
			{
				if (flag)
				{
					AreaDamage(attacker, position, damage, range);
				}
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, Vector2.op_Implicit(position), Quaternion.identity);
			Explosion component = val2.GetComponent<Explosion>();
			component.auto = true;
			component.range = range;
			component.damage = (flag ? damage : 0f);
			component.scaleDmg = false;
			component.scaleRadius = false;
			component.scaleForce = false;
			component.scaleStun = false;
			component.scaleSlow = false;
			component.scaleSilence = false;
			SpawnedAttack val3 = val2.GetComponent<SpawnedAttack>();
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = val2.AddComponent<SpawnedAttack>();
			}
			val3.spawner = attacker;
		}

		private static void AreaDamage(Player attacker, Vector2 position, float damage, float range)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0040: 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)
			//IL_0047: 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_0069: 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)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val = list[i];
				if (!CardTools.IsHostile(attacker, val) || !CardTools.IsFighting(val))
				{
					continue;
				}
				Vector2 val2 = Vector2.op_Implicit(((Component)val).transform.position);
				if (!(Vector2.Distance(val2, position) > range))
				{
					Vector2 val3 = val2 - position;
					if (val3 == Vector2.zero)
					{
						val3 = Vector2.up;
					}
					((Damagable)val.data.healthHandler).CallTakeDamage(((Vector2)(ref val3)).normalized * damage, val2, (GameObject)null, attacker, true);
				}
			}
		}

		internal static IEnumerator DetonateAfter(Player attacker, Player victim, float delay, float damage, float range)
		{
			yield return (object)new WaitForSeconds(delay);
			if (!((Object)(object)victim == (Object)null) && CardTools.IsFighting(victim))
			{
				Detonate(attacker, Vector2.op_Implicit(((Component)victim).transform.position), damage, range);
			}
		}
	}
	internal interface IPointReset
	{
		void ResetForPoint();
	}
	internal interface IStatReset
	{
		void OnStatsReset();
	}
	internal static class PlayerPhysics
	{
		private static readonly FieldRef<PlayerVelocity, Vector2> velocityRef = AccessTools.FieldRefAccess<PlayerVelocity, Vector2>("velocity");

		private static readonly FieldRef<PlayerVelocity, float> massRef = AccessTools.FieldRefAccess<PlayerVelocity, float>("mass");

		private static readonly Action<PlayerVelocity, Vector2, ForceMode2D> addForce = AccessTools.MethodDelegate<Action<PlayerVelocity, Vector2, ForceMode2D>>(AccessTools.Method(typeof(PlayerVelocity), "AddForce", new Type[2]
		{
			typeof(Vector2),
			typeof(ForceMode2D)
		}, (Type[])null), (object)null, true);

		private const float JumpScale = 0.01f;

		internal static void AddForce(Player player, Vector2 force)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			PlayerVelocity val = Velocity(player);
			if ((Object)(object)val != (Object)null)
			{
				addForce(val, force, (ForceMode2D)0);
			}
		}

		internal static void Impulse(Player player, Vector2 impulse)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			PlayerVelocity val = Velocity(player);
			if ((Object)(object)val != (Object)null)
			{
				addForce(val, impulse, (ForceMode2D)1);
			}
		}

		internal static Vector2 CurrentVelocity(Player player)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			PlayerVelocity val = Velocity(player);
			if (!((Object)(object)val == (Object)null))
			{
				return velocityRef.Invoke(val);
			}
			return Vector2.zero;
		}

		internal static void Stop(Player player)
		{
			//IL_001b: 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)
			PlayerVelocity val = Velocity(player);
			if ((Object)(object)val != (Object)null)
			{
				velocityRef.Invoke(val) = Vector2.zero;
			}
		}

		internal static void Teleport(Player player, Vector2 target)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			PlayerVelocity val = Velocity(player);
			if (!((Object)(object)val == (Object)null))
			{
				val.position = target;
				velocityRef.Invoke(val) = Vector2.zero;
			}
		}

		internal static void Launch(Player player, float jumpMultiplier)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			PlayerVelocity val = Velocity(player);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)player.data.jump == (Object)null))
			{
				Vector2 val2 = velocityRef.Invoke(val);
				if (val2.y < 0f)
				{
					val2.y = 0f;
					velocityRef.Invoke(val) = val2;
				}
				float num = 0.01f * jumpMultiplier * massRef.Invoke(val) * player.data.jump.upForce;
				addForce(val, Vector2.up * num, (ForceMode2D)1);
			}
		}

		private static PlayerVelocity Velocity(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.data == (Object)null))
			{
				return player.data.playerVel;
			}
			return null;
		}
	}
	internal static class PlayerRegistry
	{
		private static readonly List<Player> known = new List<Player>();

		internal static List<Player> Known => known;

		internal static void Register(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			known.RemoveAll((Player p) => (Object)(object)p == (Object)null);
			for (int num = 0; num < known.Count; num++)
			{
				if (known[num] == player)
				{
					return;
				}
			}
			known.Add(player);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("Rounds.exe")]
	[BepInPlugin("com.pengu.rounds.verybalancedroundsmod", "Very Balanced Rounds Mod", "0.16.0")]
	public class VeryBalancedPlugin : BaseUnityPlugin
	{
		private const string UnboundGuid = "com.willis.rounds.unbound";

		private const string ModdingUtilsGuid = "pykess.rounds.plugins.moddingutils";

		private const string RarityLibGuid = "root.rarity.lib";

		public const string ModId = "com.pengu.rounds.verybalancedroundsmod";

		public const string ModName = "Very Balanced Rounds Mod";

		public const string Version = "0.16.0";

		public const string ModInitials = "VB";

		internal static VeryBalancedPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			new Harmony("com.pengu.rounds.verybalancedroundsmod").PatchAll();
		}

		private void Start()
		{
			if (RarityUtils.Rarities.Count > 0)
			{
				RegisterCards();
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(RegisterCardsWhenRaritiesReady());
			}
			GameModeManager.AddHook("PointStart", (Func<IGameModeHandler, IEnumerator>)ResetPerPointState);
			GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)ConsumeHighRarityPicks);
			Unbound.RegisterCredits("Very Balanced Rounds Mod", new string[1] { "Pengu" }, "Thunderstore", "https://thunderstore.io/c/rounds/p/SigmaCharple/VeryBalancedRoundsMod/");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Very Balanced Rounds Mod v0.16.0 loaded.");
		}

		private IEnumerator RegisterCardsWhenRaritiesReady()
		{
			int waited = 0;
			while (RarityUtils.Rarities.Count == 0 && waited++ < 60)
			{
				yield return null;
			}
			if (RarityUtils.Rarities.Count == 0)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"RarityLib never finished registering rarities; Legendary cards cannot be built.");
			}
			RegisterCards();
		}

		internal static void RegisterCards()
		{
			CustomCard.BuildCard<GlasserCannonCard>();
			CustomCard.BuildCard<McDonaldsCard>();
			CustomCard.BuildCard<GremlinCard>();
			CustomCard.BuildCard<BirdKillerCard>();
			CustomCard.BuildCard<InevitableCard>();
			CustomCard.BuildCard<BlockHaterCard>();
			CustomCard.BuildCard<BlockLoverCard>();
			CustomCard.BuildCard<MahoragaCard>();
			CustomCard.BuildCard<TitanKillerCard>();
			CustomCard.BuildCard<BalancedCard>();
			CustomCard.BuildCard<RevUpCard>();
			CustomCard.BuildCard<GigaDrumMagCard>();
			CustomCard.BuildCard<CardCounterCard>();
			CustomCard.BuildCard<RandomCritsCard>();
			CustomCard.BuildCard<InfinityCard>();
			CustomCard.BuildCard<SwordCard>();
			CustomCard.BuildCard<ConnersPrideCard>();
			CustomCard.BuildCard<LastBreathCard>();
			CustomCard.BuildCard<FraudCard>();
			CustomCard.BuildCard<PrestigeCard>();
			CustomCard.BuildCard<TouchTheWallCard>();
			CustomCard.BuildCard<WhippedCard>();
			CustomCard.BuildCard<SuperQuickReloadCard>();
			CustomCard.BuildCard<IconOfSinCard>();
			CustomCard.BuildCard<ParticleAcceleratorCard>();
			CustomCard.BuildCard<DensityCard>();
			CustomCard.BuildCard<MtgPlayerCard>();
			CustomCard.BuildCard<BlackHoleCard>();
			CustomCard.BuildCard<InvisibleBulletsCard>();
			CustomCard.BuildCard<TreeCard>();
			CustomCard.BuildCard<ChrisSideProjectCard>();
			CustomCard.BuildCard<KirkSpecialCard>();
			CustomCard.BuildCard<PortalGunCard>();
			CustomCard.BuildCard<LowesWorkerCard>();
			CustomCard.BuildCard<LegDayCard>();
			CustomCard.BuildCard<AKCard>();
			CustomCard.BuildCard<GoBlueCard>();
			CustomCard.BuildCard<ClaudesChoiceCard>();
			CustomCard.BuildCard<UpCard>();
			CustomCard.BuildCard<DownCard>();
			CustomCard.BuildCard<ConnerHackSpecialCard>();
			CustomCard.BuildCard<OncelerCard>();
			CustomCard.BuildCard<BananaCard>();
			CustomCard.BuildCard<XanesWireManagementCard>();
			CustomCard.BuildCard<BorderHopCard>();
			CustomCard.BuildCard<RonaldMcDonaldCard>();
			CustomCard.BuildCard<HitscanCard>();
			CustomCard.BuildCard<RailgunCard>();
			CustomCard.BuildCard<DiscordModCard>();
			CustomCard.BuildCard<HollowPurpleCard>();
			CustomCard.BuildCard<DenseBulletsCard>();
			CustomCard.BuildCard<BlockBuildSpecialCard>();
			CustomCard.BuildCard<KilldozerCard>();
			CustomCard.BuildCard<ShulkerCard>();
			CustomCard.BuildCard<DroneStrikeCard>();
			CustomCard.BuildCard<CRamCard>();
			CustomCard.BuildCard<TheIslandCard>();
			CustomCard.BuildCard<TheLoraxCard>();
			CustomCard.BuildCard<SuperShotgunCard>();
			CustomCard.BuildCard<FiveHundredCigarettesCard>();
			CustomCard.BuildCard<AtomicBombCard>();
			CustomCard.BuildCard<AsuFratLeaderCard>();
			CustomCard.BuildCard<FlavorfulGarlicCard>();
			CustomCard.BuildCard<ProjectileDysfunctionCard>();
			CustomCard.BuildCard<RareArtifactCard>();
			CustomCard.BuildCard<LegendaryArtifactCard>();
			CustomCard.BuildCard<DaedalusStormbowCard>();
			CustomCard.BuildCard<PatienceCard>();
		}

		private static IEnumerator ResetPerPointState(IGameModeHandler gameModeHandler)
		{
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val = list[i];
				if (!((Object)(object)val == (Object)null))
				{
					IPointReset[] componentsInChildren = ((Component)val).GetComponentsInChildren<IPointReset>(true);
					for (int j = 0; j < componentsInChildren.Length; j++)
					{
						componentsInChildren[j].ResetForPoint();
					}
				}
			}
			GoBlueGrace.ResetForPoint();
			ClaudesChoiceCard.ResetCooldowns();
			XanesWireManagementCard.ResetGuards();
			yield break;
		}

		private static IEnumerator ConsumeHighRarityPicks(IGameModeHandler gameModeHandler)
		{
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val = list[i];
				if (!((Object)(object)val == (Object)null))
				{
					HighRarityPicks[] componentsInChildren = ((Component)val).GetComponentsInChildren<HighRarityPicks>(true);
					for (int j = 0; j < componentsInChildren.Length; j++)
					{
						componentsInChildren[j].EndPickPhase();
					}
				}
			}
			yield break;
		}
	}
}
namespace VeryBalancedRoundsMod.Patches
{
	[HarmonyPatch(typeof(Block), "blocked")]
	internal static class Block_Blocked_Patch
	{
		internal const float LeakFraction = 0.25f;

		private static readonly FieldRef<ProjectileHit, bool> hasControlRef = AccessTools.FieldRefAccess<ProjectileHit, bool>("hasControl");

		private static void Postfix(Block __instance, GameObject projectile)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)projectile == (Object)null)
			{
				return;
			}
			ProjectileHit component = projectile.GetComponent<ProjectileHit>();
			if ((Object)(object)component == (Object)null || !hasControlRef.Invoke(component))
			{
				return;
			}
			Player ownPlayer = component.ownPlayer;
			if ((Object)(object)ownPlayer == (Object)null)
			{
				return;
			}
			int num = CardTools.CountCards(ownPlayer, "Ihateblockbuild");
			if (num <= 0)
			{
				return;
			}
			CharacterData component2 = ((Component)__instance).GetComponent<CharacterData>();
			if ((Object)(object)component2 == (Object)null || (Object)(object)component2.view == (Object)null)
			{
				return;
			}
			Player player = component2.player;
			if (!CardTools.IsHostile(ownPlayer, player) || LastBreath.IsActiveOn(player))
			{
				return;
			}
			MoveTransform component3 = projectile.GetComponent<MoveTransform>();
			float impactSpeed = (((Object)(object)component3 != (Object)null) ? ((Vector3)(ref component3.velocity)).magnitude : 0f);
			float num2 = DamageMath.BulletDamage(ownPlayer, player, component.damage, impactSpeed) * 0.25f * (float)num * MahoragaAdaptation.MultiplierFor(player);
			if (!(num2 <= 0f) && !float.IsNaN(num2) && !float.IsInfinity(num2))
			{
				Vector2 val = Vector2.op_Implicit(((Component)component2.player).transform.position);
				Vector2 val2 = val - Vector2.op_Implicit(projectile.transform.position);
				if (val2 == Vector2.zero)
				{
					val2 = Vector2.up;
				}
				component2.view.RPC("RPCA_SendTakeDamage", (RpcTarget)0, new object[4]
				{
					((Vector2)(ref val2)).normalized * num2,
					val,
					true,
					ownPlayer.playerID
				});
			}
		}
	}
	[HarmonyPatch(typeof(Block), "Cooldown")]
	internal static class Block_Cooldown_Patch
	{
		private static void Postfix(Block __instance, ref float __result)
		{
			CharacterData component = ((Component)__instance).GetComponent<CharacterData>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component.player == (Object)null) && CardTools.HasCard(component.player, "Chris's Side Project"))
			{
				__result = 0f;
			}
		}
	}
	[HarmonyPatch(typeof(Block), "RPCA_DoBlock")]
	internal static class Block_RPCA_DoBlock_Patch
	{
		private static void Prefix(Block __instance, BlockTriggerType triggerType, bool onlyBlockEffects)
		{
			//IL_0003: 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)
			if (!onlyBlockEffects && (int)triggerType == 0)
			{
				CharacterData component = ((Component)__instance).GetComponent<CharacterData>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component.player == (Object)null) && CardTools.HasCard(component.player, "Portal Gun") && CardTools.IsMine(component.player))
				{
					PlayerPhysics.Teleport(component.player, PortalGunCard.AimPoint(component));
				}
			}
		}

		private static void Postfix(Block __instance, BlockTriggerType triggerType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)triggerType == 2)
			{
				return;
			}
			CharacterData component = ((Component)__instance).GetComponent<CharacterData>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component.player == (Object)null) && !((Object)(object)component.healthHandler == (Object)null))
			{
				int num = CardTools.CountCards(component.player, "Iloveblockbuild");
				if (num > 0)
				{
					component.healthHandler.Heal(component.maxHealth * 0.25f * (float)num);
				}
			}
		}
	}
	internal static class TopRarityDraw
	{
		private static readonly FieldRef<CardChoice, PickerType> pickerTypeRef = AccessTools.FieldRefAccess<CardChoice, PickerType>("pickerType");

		private static readonly FieldRef<CardChoice, List<GameObject>> spawnedCardsRef = AccessTools.FieldRefAccess<CardChoice, List<GameObject>>("spawnedCards");

		private const float SameTier = 0.0001f;

		internal static GameObject Rewrite(GameObject drawn, CardInfo[] pool)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			CardChoice instance = CardChoice.instance;
			if ((Object)(object)instance == (Object)null || !instance.IsPicking || pool == null || pool.Length == 0)
			{
				return drawn;
			}
			Player val = ResolvePicker(instance.pickrID, pickerTypeRef.Invoke(instance));
			if ((Object)(object)val == (Object)null)
			{
				return drawn;
			}
			HighRarityPicks component = ((Component)val).GetComponent<HighRarityPicks>();
			if ((Object)(object)component == (Object)null)
			{
				return drawn;
			}
			component.MarkOffered();
			List<GameObject> spawned = spawnedCardsRef.Invoke(instance);
			float num = float.MaxValue;
			foreach (CardInfo val2 in pool)
			{
				if (!((Object)(object)val2 == (Object)null) && CanTake(val, val2, spawned))
				{
					num = Mathf.Min(num, Rarities.Weight(val2.rarity));
				}
			}
			if (num == float.MaxValue)
			{
				return drawn;
			}
			if ((Object)(object)drawn != (Object)null)
			{
				CardInfo component2 = drawn.GetComponent<CardInfo>();
				if ((Object)(object)component2 != (Object)null && Rarities.Weight(component2.rarity) <= num + 0.0001f)
				{
					return drawn;
				}
			}
			List<CardInfo> list = new List<CardInfo>();
			foreach (CardInfo val3 in pool)
			{
				if (!((Object)(object)val3 == (Object)null) && !(Rarities.Weight(val3.rarity) > num + 0.0001f) && CanTake(val, val3, spawned))
				{
					list.Add(val3);
				}
			}
			if (list.Count == 0)
			{
				return drawn;
			}
			return ((Component)list[Random.Range(0, list.Count)]).gameObject;
		}

		private static Player ResolvePicker(int pickrID, PickerType pickerType)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			List<Player> list = CardTools.AllPlayers();
			for (int i = 0; i < list.Count; i++)
			{
				Player val = list[i];
				if (!((Object)(object)val == (Object)null) && (((int)pickerType == 1) ? (val.playerID == pickrID) : (val.teamID == pickrID)) && HighRarityPicks.IsActiveOn(val))
				{
					return val;
				}
			}
			return null;
		}

		private static bool CanTake(Player picker, CardInfo card, List<GameObject> spawned)
		{
			if (spawned != null)
			{
				for (int i = 0; i < spawned.Count; i++)
				{
					if (!((Object)(object)spawned[i] == (Object)null))
					{
						CardInfo component = spawned[i].GetComponent<CardInfo>();
						if ((Object)(object)component != (Object)null && component.cardName == card.cardName)
						{
							return false;
						}
					}
				}
			}
			if (!card.allowMultiple && CardTools.HasCard(picker, card.cardName))
			{
				return false;
			}
			Gun component2 = ((Component)card).GetComponent<Gun>();
			if ((Object)(object)component2 != (Object)null && component2.lockGunToDefault && (Object)(object)picker.data != (Object)null && (Object)(object)picker.data.weaponHandler != (Object)null && (Object)(object)picker.data.weaponHandler.gun != (Object)null && picker.data.weaponHandler.gun.lockGunToDefault)
			{
				return false;
			}
			if (Cards.instance != null)
			{
				return Cards.instance.PlayerIsAllowedCard(picker, card);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CardChoice), "GetRanomCard")]
	internal static class CardChoice_GetRanomCard_Patch
	{
		private static void Postfix(CardChoice __instance, ref GameObject __result)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				__result = TopRarityDraw.Rewrite(__result, __instance.cards);
			}
		}
	}
	[HarmonyPatch]
	internal static class ModdingUtils_OrignialGetRanomCard_Patch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(CardChoicePatchGetRanomCard), "OrignialGetRanomCard", new Type[1] { typeof(CardInfo[]) }, (Type[])null);
		}

		private static void Postfix(CardInfo[] cards, ref GameObject __result)
		{
			__result = TopRarityDraw.Rewrite(__result, cards);
		}
	}
	internal static class Rarities
	{
		internal static float Weight(Rarity rarity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return RarityUtils.GetRarityData(rarity).relativeRarity;
			}
			catch (Exception)
			{
				return VanillaWeight(rarity);
			}
		}

		private static float VanillaWeight(Rarity rarity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)rarity != 1)
			{
				if ((int)rarity == 2)
				{
					return 0.1f;
				}
				return 1f;
			}
			return 0.4f;
		}
	}
	[HarmonyPatch(typeof(Explosion), "DoExplosionEffects")]
	internal static class Explosion_DoExplosionEffects_Patch
	{
		private const string ToxicCloudPrefab = "E_ToxicCloud";

		internal static bool ToxicCloud { get; private set; }

		private static void Prefix(Explosion __instance)
		{
			ToxicCloud = (Object)(object)__instance != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("E_ToxicCloud", StringComparison.Ordinal);
		}

		private static void Finalizer()
		{
			ToxicCloud = false;
		}
	}
	[HarmonyPatch(typeof(Gun), "get_usedCooldown")]
	internal static class Gun_UsedCooldown_Patch
	{
		private static void Postfix(Gun __instance, ref float __result)
		{
			Player player = __instance.player;
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			int num = CardTools.CountCards(player, "Rev Up");
			if (num > 0)
			{
				PointTimer component = ((Component)player).GetComponent<PointTimer>();
				if ((Object)(object)component != (Object)null)
				{
					float num2 = Mathf.Pow(1.05f, component.Elapsed * (float)num);
					if (num2 > 0f)
					{
						__result /= num2;
					}
				}
			}
			if (CardTools.HasCard(player, "Icon of Sin"))
			{
				IconOfSinRamp iconOfSinRamp = IconOfSinRamp.On(player);
				if ((Object)(object)iconOfSinRamp != (Object)null)
				{
					__result *= iconOfSinRamp.Shrink;
				}
			}
			if (LastBreath.IsActiveOn(player))
			{
				__result /= 2f;
			}
			int num3 = CardTools.CountCards(player, "C-Ram");
			if (num3 <= 0 || !(__result > 0f) || Gun_ApplyProjectileStats_Patch.Running)
			{
				return;
			}
			for (int i = 0; i < num3; i++)
			{
				if (float.IsInfinity(__result))
				{
					break;
				}
				__result = __result * __result / 0.3f;
			}
			if (__result < 0.0001f)
			{
				__result = 0.0001f;
			}
		}
	}
	[HarmonyPatch(typeof(Gun), "Attack")]
	internal static class Gun_Attack_Patch
	{
		private static bool Prefix(Gun __instance)
		{
			Player val = (((Object)(object)__instance == (Object)null) ? null : __instance.player);
			if (!((Object)(object)val == (Object)null))
			{
				return !PatienceCard.IsLocked(val);
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class Gun_FireBurst_Patch
	{
		private static readonly FieldRef<Gun, GunAmmo> gunAmmoRef = AccessTools.FieldRefAccess<Gun, GunAmmo>("gunAmmo");

		private static readonly Stack<KeyValuePair<Gun, int>> restore = new Stack<KeyValuePair<Gun, int>>();

		private static FieldInfo gunField;

		private static MethodBase TargetMethod()
		{
			return AccessTools.EnumeratorMoveNext((MethodBase)AccessTools.Method(typeof(Gun), "FireBurst", (Type[])null, (Type[])null));
		}

		private static void Prefix(object __instance)
		{
			restore.Push(new KeyValuePair<Gun, int>(null, 0));
			if (__instance == null)
			{
				return;
			}
			if (gunField == null)
			{
				gunField = AccessTools.Field(__instance.GetType(), "<>4__this");
			}
			Gun val = (Gun)((gunField == null) ? null : /*isinst with value type is only supported in some contexts*/);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.player == (Object)null) && CardTools.HasCard(val.player, "Atomic Bomb"))
			{
				GunAmmo val2 = gunAmmoRef.Invoke(val);
				if (!((Object)(object)val2 == (Object)null) && val2.maxAmmo > 0)
				{
					restore.Pop();
					restore.Push(new KeyValuePair<Gun, int>(val, val.numberOfProjectiles));
					val.numberOfProjectiles = val2.maxAmmo;
				}
			}
		}

		private static void Finalizer()
		{
			if (restore.Count != 0)
			{
				KeyValuePair<Gun, int> keyValuePair = restore.Pop();
				if ((Object)(object)keyValuePair.Key != (Object)null)
				{
					keyValuePair.Key.numberOfProjectiles = keyValuePair.Value;
				}
			}
		}
	}
	[HarmonyPatch(typeof(GunAmmo), "ReloadTime")]
	internal static class GunAmmo_ReloadTime_Patch
	{
		private static void Postfix(Gun ___gun, ref float __result)
		{
			Player val = (((Object)(object)___gun == (Object)null) ? null : ___gun.player);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (CardTools.HasCard(val, "Icon of Sin"))
			{
				IconOfSinRamp iconOfSinRamp = IconOfSinRamp.On(val);
				if ((Object)(object)iconOfSinRamp != (Object)null)
				{
					__result *= iconOfSinRamp.Shrink;
				}
			}
			if (LastBreath.IsActiveOn(val))
			{
				__result /= 2f;
			}
		}
	}
	[HarmonyPatch(typeof(Gun), "ApplyProjectileStats")]
	internal static class Gun_ApplyProjectileStats_Patch
	{
		private static readonly Dictionary<int, float> lastForcedBlock = new Dictionary<int, float>();

		internal static bool Running { get; private set; }

		private static void Prefix()
		{
			Running = true;
		}

		private static void Finalizer()
		{
			Running = false;
		}

		private static void Postfix(Gun __instance, GameObject obj, float randomSeed)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)obj == (Object)null || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			Player player = __instance.player;
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			if (CardTools.HasCard(player, "Projectile Dysfunction") && (Object)(object)obj.GetComponent<WanderingBullet>() == (Object)null)
			{
				obj.AddComponent<WanderingBullet>().Init(randomSeed);
			}
			if (CardTools.HasCard(player, "Invisible Bullets") && (Object)(object)obj.GetComponent<InvisibleBullet>() == (Object)null)
			{
				obj.AddComponent<InvisibleBullet>();
			}
			if (CardTools.HasCard(player, "Icon of Sin"))
			{
				IconOfSinRamp iconOfSinRamp = IconOfSinRamp.On(player);
				MoveTransform component = obj.GetComponent<MoveTransform>();
				if ((Object)(object)iconOfSinRamp != (Object)null && (Object)(object)component != (Object)null)
				{
					component.localForce *= iconOfSinRamp.Growth;
				}
			}
			if (CardTools.HasCard(player, "The Block Build Special") && (Object)(object)player.data != (Object)null && (Object)(object)player.data.block != (Object)null && (!lastForcedBlock.TryGetValue(player.playerID, out var value) || Time.time - value >= 0.1f))
			{
				lastForcedBlock[player.playerID] = Time.time;
				ForceBlockEffects(player);
			}
		}

		private static void ForceBlockEffects(Player player)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (CardTools.HasCard(player, "Portal Gun") && CardTools.IsMine(player))
			{
				PlayerPhysics.Teleport(player, PortalGunCard.AimPoint(player.data));
			}
			player.data.block.RPCA_DoBlock(true, true, (BlockTriggerType)4, Vector3.zero, true);
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "CallTakeDamage")]
	internal static class HealthHandler_CallTakeDamage_Patch
	{
		private static void Prefix(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer)
		{
			//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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			if (damage == Vector2.zero)
			{
				return;
			}
			CharacterData component = ((Component)__instance).GetComponent<CharacterData>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.player == (Object)null)
			{
				return;
			}
			Player player = component.player;
			if (LastBreath.IsActiveOn(player))
			{
				damage = Vector2.zero;
				return;
			}
			float num = ((Vector2)(ref damage)).magnitude;
			Vector2 val = damage / num;
			if ((Object)(object)damagingPlayer == (Object)null && OutOfBoundsHandler_LateUpdate_Patch.Running)
			{
				int num2 = CardTools.CountCards(player, "Border Hop");
				if (num2 > 0)
				{
					num *= Mathf.Pow(0.19999999f, (float)num2);
				}
			}
			if (CardTools.IsHostile(damagingPlayer, player))
			{
				num = ((!BulletHit.TryClaim(damagingPlayer, player, out var speed, out var isCrit)) ? (num * DamageMath.AttackerMultiplier(damagingPlayer, player)) : (isCrit ? 1000000f : DamageMath.BulletDamage(damagingPlayer, player, num, speed)));
			}
			if (num < 500000f)
			{
				num *= MahoragaAdaptation.MultiplierFor(player);
			}
			if (!float.IsNaN(num))
			{
				if (float.IsInfinity(num))
				{
					num = 1000000f;
				}
				if (Explosion_DoExplosionEffects_Patch.ToxicCloud && CardTools.HasCard(player, "500 Cigarettes") && ((Object)(object)component.block == (Object)null || !component.block.IsBlocking()))
				{
					CigaretteBurn.SendSmokeHeal(player, num);
					damage = Vector2.zero;
				}
				else
				{
					damage = val * num;
				}
			}
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "RPCA_SendTakeDamage")]
	internal static class HealthHandler_RPCA_SendTakeDamage_Patch
	{
		internal static bool Running { get; private set; }

		private static void Prefix()
		{
			Running = true;
		}

		private static void Finalizer()
		{
			Running = false;
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "TakeDamage", new Type[]
	{
		typeof(Vector2),
		typeof(Vector2),
		typeof(Color),
		typeof(GameObject),
		typeof(Player),
		typeof(bool),
		typeof(bool)
	})]
	internal static class HealthHandler_TakeDamage_Patch
	{
		private static readonly FieldRef<PlayerVelocity, bool> simulatedRef = AccessTools.FieldRefAccess<PlayerVelocity, bool>("simulated");

		private static void Prefix(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer, bool ignoreBlock)
		{
			//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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (damage == Vector2.zero)
			{
				return;
			}
			CharacterData component = ((Component)__instance).GetComponent<CharacterData>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.player == (Object)null || !component.isPlaying || component.dead || ((Object)(object)component.playerVel != (Object)null && !simulatedRef.Invoke(component.playerVel)) || (!ignoreBlock && (Object)(object)component.block != (Object)null && component.block.IsBlocking()) || LastBreath.IsActiveOn(component.player))
			{
				return;
			}
			Player player = component.player;
			if (!HealthHandler_RPCA_SendTakeDamage_Patch.Running && ((Vector2)(ref damage)).magnitude < 500000f)
			{
				damage *= MahoragaAdaptation.MultiplierFor(player);
			}
			MahoragaAdaptation.RegisterHitOn(player);
			if (CardTools.IsHostile(damagingPlayer, player) && CardTools.HasCard(damagingPlayer, "Particle Accelerator"))
			{
				ParticleAccelerator component2 = ((Component)damagingPlayer).GetComponent<ParticleAccelerator>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.RegisterHit();
				}
			}
		}
	}
	[HarmonyPatch(typeof(HealthHandler), "DoDamage")]
	internal static class HealthHandler_DoDamage_Patch
	{
		private const int NoRespawnOverride = -1;

		private static bool Prefix(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer, out int __state)
		{
			//IL_0035: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			__state = -1;
			CharacterData component = ((Component)__instance).GetComponent<CharacterData>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			Player player = component.player;
			if (LastBreath.IsActiveOn(player))
			{
				return false;
			}
			if (CardTools.HasCard(player, "Rare Artifact"))
			{
				damage *= 0.8f;
			}
			if (CardTools.HasCard(player, "Legendary Artifact"))
			{
				damage *= 0.6f;
			}
			if (!CardTools.IsHostile(damagingPlayer, player))
			{
				return true;
			}
			if (CardTools.HasCard(damagingPlayer, "Onceler") && CardTools.HasCard(player, "Tree") && !CardTools.HasCard(player, "The Lorax"))
			{
				damage = Direction(damage) * 1000000f;
			}
			if (CardTools.HasCard(damagingPlayer, "Bird Killer") && (Object)(object)component.stats != (Object)null && component.stats.remainingRespawns > 0)
			{
				__state = component.stats.remainingRespawns;
				component.stats.remainingRespawns = 0;
			}
			return true;
		}

		private static void Postfix(HealthHandler __instance, int __state)
		{
			if (__state != -1)
			{
				CharacterData component = ((Component)__instance).GetComponent<CharacterData>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.stats != (Object)null)
				{
					component.stats.remainingRespawns = __state;
				}
			}
		}

		private static Vector2 Direction(Vector2 damage)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!(damage == Vector2.zero))
			{
				return ((Vector2)(ref damage)).normalized;
			}
			return Vector2.up;
		}
	}
	[HarmonyPatch(typeof(OutOfBoundsHandler), "LateUpdate")]
	internal static class OutOfBoundsHandler_LateUpdate_Patch
	{
		internal static bool Running { get; private set; }

		private static void Prefix()
		{
			Running = true;
		}

		private static void Finalizer()
		{
			Running = false;
		}
	}
	[HarmonyPatch(typeof(MoveTransform), "Update")]
	internal static class MoveTransform_Update_Patch
	{
		internal const float Radius = 2.5f;

		private static readonly List<Player> infinityHolders = new List<Player>();

		private static readonly List<Player> garlicHolders = new List<Player>();

		private static int holdersFrame = -1;

		private static void RefreshHolders()
		{
			if (holdersFrame == Time.frameCount)
			{
				return;
			}
			holdersFrame = Time.frameCount;
			infinityHolders.Clear();
			garlicHolders.Clear();
			List<Player> known = PlayerRegistry.Known;
			for (int i = 0; i < known.Count; i++)
			{
				Player val = known[i];
				if (!((Object)(object)val == (Object)null) && CardTools.IsFighting(val))
				{
					if (CardTools.HasCard(val, "Infinity"))
					{
						infinityHolders.Add(val);
					}
					if (CardTools.HasCard(val, "The Flavorful Garlic"))
					{
						garlicHolders.Add(val);
					}
				}
			}
		}

		private static void Postfix(MoveTransform __instance)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			ProjectileHit component = ((Component)__instance).GetComponent<ProjectileHit>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			RefreshHolders();
			Vector2 val = Vector2.op_Implicit(((Component)__instance).transform.position);
			int num = (((Object)(object)component.ownPlayer != (Object)null) ? component.ownPlayer.playerID : (-1));
			if (garlicHolders.Count > 0)
			{
				Swerve(__instance, val, num);
			}
			bool flag = false;
			for (int i = 0; i < infinityHolders.Count; i++)
			{
				if (flag)
				{
					break;
				}
				Player val2 = infinityHolders[i];
				if (!((Object)(object)val2 == (Object)null) && val2.playerID != num && Vector2.Distance(val, Vector2.op_Implicit(((Component)val2).transform.position)) < 2.5f)
				{
					flag = true;
				}
			}
			InfinitySlow infinitySlow = ((Component)__instance).GetComponent<InfinitySlow>();
			if (!flag)
			{
				if ((Object)(object)infinitySlow != (Object)null)
				{
					infinitySlow.Release();
				}
				return;
			}
			if ((Object)(object)infinitySlow == (Object)null)
			{
				infinitySlow = ((Component)__instance).gameObject.AddComponent<InfinitySlow>();
			}
			infinitySlow.Freeze();
		}

		private static void Swerve(MoveTransform move, Vector2 at, int owner)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			float num = TimeHandler.deltaTime * move.multiplier;
			if (num <= 0f)
			{
				return;
			}
			Vector3 val = move.velocity;
			Vector2 val2 = Vector2.op_Implicit(val);
			float magnitude = ((Vector2)(ref val2)).magnitude;
			if (magnitude < 0.01f)
			{
				return;
			}
			for (int i = 0; i < garlicHolders.Count; i++)
			{
				Player val3 = garlicHolders[i];
				if ((Object)(object)val3 == (Object)null || val3.playerID == owner)
				{
					continue;
				}
				Vector2 val4 = at - Vector2.op_Implicit(((Component)val3).transform.position);
				float magnitude2 = ((Vector2)(ref val4)).magnitude;
				if (magnitude2 >= 5.5f || magnitude2 < 0.001f)
				{
					continue;
				}
				Vector2 val5 = Vector2.op_Implicit(val) / magnitude;
				if (!(Vector2.Dot(val5, val4) >= 0f))
				{
					Vector2 val6 = val4 - Vector2.Dot(val4, val5) * val5;
					if (((Vector2)(ref val6)).sqrMagnitude < 1E-06f)
					{
						((Vector2)(ref val6))..ctor(0f - val5.y, val5.x);
					}
					float num2 = ((val5.x * val6.y - val5.y * val6.x >= 0f) ? 1f : (-1f));
					float num3 = 1f - magnitude2 / 5.5f;
					val = Quaternion.AngleAxis(num2 * 900f * num3 * num, Vector3.forward) * val;
				}
			}
			move.velocity = val;
		}
	}
	[HarmonyPatch(typeof(PlayerJump), "Jump")]
	internal static class PlayerJump_Jump_Patch
	{
		private static bool Prefix(CharacterData ___data, bool forceJump)
		{
			if ((Object)(object)___data == (Object)null || (Object)(object)___data.player == (Object)null)
			{
				return true;
			}
			Player player = ___data.player;
			if (TreeCard.IsRooted(player))
			{
				return false;
			}
			if (!forceJump && ___data.currentJumps <= 0 && CardTools.HasCard(player, "Drone Strike"))
			{
				___data.currentJumps = 1;
			}
			return true;
		}
	}
	internal static class GoBlueGrace
	{
		private static readonly HashSet<int> graced = new HashSet<int>();

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

		private static readonly Dictionary<int