Decompiled source of Bizarre JoJo Stands v1.0.0

BizarreJoJoStands.dll

Decompiled 16 hours 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.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using InControl;
using ModdingUtils.Utils;
using Photon.Pun;
using TMPro;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BizarreJoJoStands")]
[assembly: AssemblyDescription("Stands from JoJo's Bizarre Adventure as ROUNDS cards")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BizarreJoJoStands")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7fcd92c4-5d49-4304-b7e5-56e8fd6484a5")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BizarreJoJoStands;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.kpcnre.rounds.bizarrejojostands", "Bizarre JoJo Stands", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	public const string ModId = "com.kpcnre.rounds.bizarrejojostands";

	public const string ModName = "Bizarre JoJo Stands";

	public const string Version = "1.0.0";

	internal static Plugin Instance;

	private static CardInfo standArrow;

	private static CardInfo requiemArrow;

	private static CardInfo rokakaka;

	private static CardInfo corpsePart;

	private static readonly CardInfo[] statCards = (CardInfo[])(object)new CardInfo[5];

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		StandConfig.Bind(((BaseUnityPlugin)this).Config);
		try
		{
			new Harmony("com.kpcnre.rounds.bizarrejojostands").PatchAll();
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Harmony patches failed (King Crimson / Requiem / shield damage immunity won't work): " + ex));
		}
	}

	private void Start()
	{
		CustomCard.BuildCard<StandArrowCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			standArrow = c;
		});
		CustomCard.BuildCard<RequiemArrowCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			requiemArrow = c;
		});
		CustomCard.BuildCard<RokakakaCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			rokakaka = c;
		});
		CustomCard.BuildCard<SaintsCorpsePartCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			corpsePart = c;
		});
		StandRegistry.Add<StarPlatinumCard, StarPlatinumStand>("Star Platinum");
		StandRegistry.Add<TheWorldCard, TheWorldStand>("The World");
		StandRegistry.Add<KillerQueenCard, KillerQueenStand>("Killer Queen");
		StandRegistry.Add<GoldExperienceCard, GoldExperienceStand>("Gold Experience");
		StandRegistry.Add<CrazyDiamondCard, CrazyDiamondStand>("Crazy Diamond");
		StandRegistry.Add<KingCrimsonCard, KingCrimsonStand>("King Crimson");
		StandRegistry.Add<SilverChariotCard, SilverChariotStand>("Silver Chariot");
		StandRegistry.Add<HierophantGreenCard, HierophantGreenStand>("Hierophant Green");
		StandRegistry.Add<MagiciansRedCard, MagiciansRedStand>("Magician's Red");
		StandRegistry.Add<StickyFingersCard, StickyFingersStand>("Sticky Fingers");
		StandRegistry.Add<TheHandCard, TheHandStand>("The Hand");
		StandRegistry.Add<TuskAct1Card, TuskAct1Stand>("Tusk Act 1");
		StandRegistry.Add<D4CCard, D4CStand>("D4C");
		StandRegistry.Add<StoneFreeCard, StoneFreeStand>("Stone Free");
		StandRegistry.Add<EchoesAct1Card, EchoesAct1Stand>("Echoes Act 1");
		StandRegistry.Add<SexPistolsCard, SexPistolsStand>("Sex Pistols");
		StandRegistry.Add<PurpleHazeCard, PurpleHazeStand>("Purple Haze");
		StandRegistry.Add<HeavensDoorCard, HeavensDoorStand>("Heaven's Door");
		StandRegistry.Add<WhitesnakeCard, WhitesnakeStand>("Whitesnake");
		StandRegistry.Add<HermitPurpleCard, HermitPurpleStand>("Hermit Purple");
		StandRegistry.Add<AerosmithCard, AerosmithStand>("Aerosmith");
		StandRegistry.Add<MoodyBluesCard, MoodyBluesStand>("Moody Blues");
		StandRegistry.Add<SpiceGirlCard, SpiceGirlStand>("Spice Girl");
		StandRegistry.Add<WeatherReportCard, WeatherReportStand>("Weather Report");
		StandRegistry.Add<SoftAndWetCard, SoftAndWetStand>("Soft & Wet");
		StandRegistry.Add<TheEmperorCard, TheEmperorStand>("The Emperor");
		StandRegistry.Add<GoldExperienceRequiemCard, GoldExperienceRequiemStand>("Gold Experience Requiem", evolved: true);
		StandRegistry.Add<EchoesAct2Card, EchoesAct2Stand>("Echoes Act 2", evolved: true);
		StandRegistry.Add<EchoesCard, EchoesStand>("Echoes Act 3", evolved: true);
		StandRegistry.Add<TuskCard, TuskStand>("Tusk Act 4", evolved: true);
		StandRegistry.Add<ChariotRequiemCard, ChariotRequiemStand>("Chariot Requiem", evolved: true);
		StandRegistry.Add<BitesTheDustCard, BitesTheDustStand>("Killer Queen: Bites the Dust", evolved: true);
		StandRegistry.Add<CMoonCard, CMoonStand>("C-Moon", evolved: true);
		StandRegistry.Add<MadeInHeavenCard, MadeInHeavenStand>("Made in Heaven", evolved: true);
		StandRegistry.Add<TheWorldOverHeavenCard, TheWorldOverHeavenStand>("The World Over Heaven", evolved: true);
		StandRegistry.Add<TuskAct2Card, TuskAct2Stand>("Tusk Act 2", evolved: true);
		StandRegistry.Add<TuskAct3Card, TuskAct3Stand>("Tusk Act 3", evolved: true);
		StandRegistry.Add<D4CLoveTrainCard, D4CLoveTrainStand>("D4C Love Train", evolved: true);
		StandConfig.ApplyLocal();
		CustomCard.BuildCard<StandPowerCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			statCards[0] = c;
		});
		CustomCard.BuildCard<StandSpeedCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			statCards[1] = c;
		});
		CustomCard.BuildCard<StandRangeCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			statCards[2] = c;
		});
		CustomCard.BuildCard<StandDurabilityCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			statCards[3] = c;
		});
		CustomCard.BuildCard<StandPrecisionCard>((Action<CardInfo>)delegate(CardInfo c)
		{
			statCards[4] = c;
		});
		((BaseUnityPlugin)this).Logger.LogInfo((object)("JoJo cards registered (" + StandRegistry.All.Count + " Stands)"));
		try
		{
			AddCardGating();
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Card gating unavailable (ModdingUtils too old?), arrows and Stand stats show up for everyone: " + ex.GetType().Name));
		}
		try
		{
			Unbound.RegisterHandshake("com.kpcnre.rounds.bizarrejojostands", (Action)StandConfig.Sync);
		}
		catch (Exception ex2)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("No settings sync with other players: " + ex2.Message));
		}
		GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)EndEffects);
		GameModeManager.AddHook("GameEnd", (Func<IGameModeHandler, IEnumerator>)EndEffects);
		GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)NewGame);
		StandHud.Ensure();
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static void AddCardGating()
	{
		Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)delegate(Player player, CardInfo card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return true;
			}
			if (card.cardName == "Stand Arrow")
			{
				return StandRegistry.CanAwaken(player);
			}
			if (card.cardName == "Requiem Arrow")
			{
				return StandRegistry.Evolvable(player) != null;
			}
			if (card.cardName == "Saint's Corpse Part")
			{
				return StandRegistry.Evolvable(player, StandRegistry.CorpseEvolutions) != null;
			}
			if (card.cardName == "Rokakaka")
			{
				return StandRegistry.HasAnyStand(player);
			}
			return StandStats.IsStatCard(card) ? (StandRegistry.HasAnyStand(player) && StandStats.Grade(player, card.cardName) < 4) : (!StandRegistry.IsStandCard(card));
		});
	}

	internal static void HideFromPicks(CardInfo card)
	{
		try
		{
			HideCard(card);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Could not hide " + card.cardName + " from picks: " + ex.GetType().Name));
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static void HideCard(CardInfo card)
	{
		Cards.instance.AddHiddenCard(card);
	}

	private IEnumerator EndEffects(IGameModeHandler gm)
	{
		TimeStop.End();
		SpeedBoost[] array = Object.FindObjectsOfType<SpeedBoost>();
		for (int i = 0; i < array.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)array[i]);
		}
		yield break;
	}

	private IEnumerator NewGame(IGameModeHandler gm)
	{
		Arrows.ResetSpent();
		StandConfig.Sync();
		yield break;
	}
}
public static class CardArt
{
	private static readonly Dictionary<string, GameObject> templates = new Dictionary<string, GameObject>();

	private static GameObject holder;

	public static GameObject Get(string fileName)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		//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_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: 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_00b9: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		if (templates.TryGetValue(fileName, out var value) && (Object)(object)value != (Object)null)
		{
			return value;
		}
		Texture2D val = LoadTexture(fileName);
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		if ((Object)(object)holder == (Object)null)
		{
			holder = new GameObject("JoJoCardArtHolder");
			holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)holder);
		}
		value = new GameObject("CardArt_" + fileName, new Type[1] { typeof(RectTransform) });
		value.transform.SetParent(holder.transform, false);
		RectTransform val2 = (RectTransform)value.transform;
		val2.anchorMin = Vector2.zero;
		val2.anchorMax = Vector2.one;
		val2.offsetMin = Vector2.zero;
		val2.offsetMax = Vector2.zero;
		Image obj = value.AddComponent<Image>();
		obj.sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		obj.preserveAspect = true;
		((Graphic)obj).raycastTarget = false;
		templates[fileName] = value;
		return value;
	}

	public static Texture2D LoadTexture(string fileName, bool warnIfMissing = true)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		try
		{
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fileName);
			if (File.Exists(text))
			{
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				((Texture)val).filterMode = (FilterMode)1;
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(text)))
				{
					return val;
				}
			}
			if (warnIfMissing)
			{
				Debug.LogWarning("[JoJo] " + fileName + " not found or unreadable at: " + text);
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning("[JoJo] failed to load " + fileName + ": " + ex.Message);
		}
		return null;
	}

	public static CardInfoStat Stat(bool positive, string name, string amount)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: 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)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		return new CardInfoStat
		{
			positive = positive,
			stat = name,
			amount = amount,
			simepleAmount = (SimpleAmount)0
		};
	}

	public static string Percent(float multiplier)
	{
		return "+" + Mathf.RoundToInt((multiplier - 1f) * 100f) + "%";
	}
}
public class StandArrowCard : CustomCard
{
	public const string CardTitle = "Stand Arrow";

	private const float HealthBonus = 1.1f;

	public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
	{
		cardInfo.allowMultiple = true;
		statModifiers.health = 1.1f;
	}

	public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
	{
		Arrows.Grant(player, "Stand Arrow", () => (!StandRegistry.CanAwaken(player)) ? null : StandRegistry.RandomBase(player)?.Card, null);
	}

	protected override string GetTitle()
	{
		return "Stand Arrow";
	}

	protected override string GetDescription()
	{
		return "Pierced by the Arrow, you awaken a random Stand.";
	}

	protected override GameObject GetCardArt()
	{
		return CardArt.Get("stand_arrow_cardart.png");
	}

	protected override Rarity GetRarity()
	{
		return (Rarity)0;
	}

	protected override CardInfoStat[] GetStats()
	{
		return (CardInfoStat[])(object)new CardInfoStat[2]
		{
			CardArt.Stat(positive: true, "Stand", "random"),
			CardArt.Stat(positive: true, "Health", CardArt.Percent(1.1f))
		};
	}

	protected override CardThemeColorType GetTheme()
	{
		return (CardThemeColorType)1;
	}

	public override string GetModName()
	{
		return "Bizarre JoJo Stands";
	}
}
public class RequiemArrowCard : CustomCard
{
	public const string CardTitle = "Requiem Arrow";

	public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
	{
		cardInfo.allowMultiple = true;
	}

	public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
	{
		Arrows.Evolve(player, "Requiem Arrow", StandRegistry.Evolutions);
	}

	protected override string GetTitle()
	{
		return "Requiem Arrow";
	}

	protected override string GetDescription()
	{
		return "Your Stand pierces itself with the Arrow and evolves into its next form.";
	}

	protected override GameObject GetCardArt()
	{
		return CardArt.Get("requiem_arrow_cardart.png");
	}

	protected override Rarity GetRarity()
	{
		return (Rarity)2;
	}

	protected override CardInfoStat[] GetStats()
	{
		return (CardInfoStat[])(object)new CardInfoStat[2]
		{
			CardArt.Stat(positive: true, "Stand", "evolves one step"),
			CardArt.Stat(positive: true, "e.g. Echoes", "Act 1 > 2 > 3")
		};
	}

	protected override CardThemeColorType GetTheme()
	{
		return (CardThemeColorType)4;
	}

	public override string GetModName()
	{
		return "Bizarre JoJo Stands";
	}
}
public class SaintsCorpsePartCard : CustomCard
{
	public const string CardTitle = "Saint's Corpse Part";

	private const float HealthBonus = 1.2f;

	public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
	{
		cardInfo.allowMultiple = true;
		statModifiers.health = 1.2f;
	}

	public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
	{
		Arrows.Evolve(player, "Saint's Corpse Part", StandRegistry.CorpseEvolutions);
	}

	protected override string GetTitle()
	{
		return "Saint's Corpse Part";
	}

	protected override string GetDescription()
	{
		return "A relic of the Saint. Fused with it, a Stand goes beyond: The World, Tusk or D4C.";
	}

	protected override GameObject GetCardArt()
	{
		return CardArt.Get("saints_corpse_part_cardart.png");
	}

	protected override Rarity GetRarity()
	{
		return (Rarity)2;
	}

	protected override CardInfoStat[] GetStats()
	{
		return (CardInfoStat[])(object)new CardInfoStat[3]
		{
			CardArt.Stat(positive: true, "Stand", "evolves one step"),
			CardArt.Stat(positive: true, "e.g. Tusk", "Act 1 > 2 > 3 > 4"),
			CardArt.Stat(positive: true, "Health", CardArt.Percent(1.2f))
		};
	}

	protected override CardThemeColorType GetTheme()
	{
		return (CardThemeColorType)3;
	}

	public override string GetModName()
	{
		return "Bizarre JoJo Stands";
	}
}
public class RokakakaCard : CustomCard
{
	public const string CardTitle = "Rokakaka";

	private const float HealthBonus = 1.2f;

	public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
	{
		cardInfo.allowMultiple = true;
		statModifiers.health = 1.2f;
	}

	public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
	{
		Arrows.Grant(player, "Rokakaka", () => (CardInfo)null, () => StandRegistry.StandOf(player)?.Card);
		Stand[] components = ((Component)player).GetComponents<Stand>();
		foreach (Stand stand in components)
		{
			if (stand.keepWithoutCard)
			{
				Object.Destroy((Object)(object)stand);
			}
		}
	}

	protected override string GetTitle()
	{
		return "Rokakaka";
	}

	protected override string GetDescription()
	{
		return "The fruit of equivalent exchange. Eating it takes your Stand away.";
	}

	protected override GameObject GetCardArt()
	{
		return CardArt.Get("rokakaka_cardart.png");
	}

	protected override Rarity GetRarity()
	{
		return (Rarity)1;
	}

	protected override CardInfoStat[] GetStats()
	{
		return (CardInfoStat[])(object)new CardInfoStat[2]
		{
			CardArt.Stat(positive: true, "Health", CardArt.Percent(1.2f)),
			CardArt.Stat(positive: false, "Stand", "removed")
		};
	}

	protected override CardThemeColorType GetTheme()
	{
		return (CardThemeColorType)6;
	}

	public override string GetModName()
	{
		return "Bizarre JoJo Stands";
	}
}
internal static class Arrows
{
	private static readonly Dictionary<string, int> spent = new Dictionary<string, int>();

	public static void ResetSpent()
	{
		spent.Clear();
	}

	public static void Evolve(Player player, string title, Dictionary<string, string> chain)
	{
		StandRegistry.Entry from = null;
		Grant(player, title, delegate
		{
			from = StandRegistry.Evolvable(player, chain);
			return (from == null) ? null : StandRegistry.Find(chain[from.Title]).Card;
		}, () => (from == null) ? null : from.Card);
		Stand[] components = ((Component)player).GetComponents<Stand>();
		foreach (Stand stand in components)
		{
			if (stand.keepWithoutCard && chain.TryGetValue(stand.CardTitle, out var value) && StandConfig.Enabled(value))
			{
				StandRegistry.Entry entry = StandRegistry.Find(value);
				if (entry != null)
				{
					Object.Destroy((Object)(object)stand);
					((Stand)(object)((Component)player).gameObject.AddComponent(entry.StandType)).keepWithoutCard = true;
					Debug.Log("[JoJo] player " + player.playerID + "'s " + stand.CardTitle + " evolved into " + value + " (debug Stand)");
					break;
				}
			}
		}
	}

	public static void Grant(Player player, string title, Func<CardInfo> pick, Func<CardInfo> remove)
	{
		if (!((Object)(object)Plugin.Instance == (Object)null) && (PhotonNetwork.OfflineMode || PhotonNetwork.IsMasterClient))
		{
			((MonoBehaviour)Plugin.Instance).StartCoroutine(GrantLater(player, title, pick, remove));
		}
	}

	private static IEnumerator GrantLater(Player player, string title, Func<CardInfo> pick, Func<CardInfo> remove)
	{
		yield return (object)new WaitForSeconds(0.2f);
		if ((Object)(object)player == (Object)null)
		{
			yield break;
		}
		int num = 0;
		if (player.data.currentCards != null)
		{
			foreach (CardInfo currentCard in player.data.currentCards)
			{
				if ((Object)(object)currentCard != (Object)null && currentCard.cardName == title)
				{
					num++;
				}
			}
		}
		string key = player.playerID + "|" + title;
		spent.TryGetValue(key, out var value);
		if (num <= value)
		{
			spent[key] = num;
			yield break;
		}
		spent[key] = num;
		CardInfo card = pick();
		CardInfo val = remove?.Invoke();
		if ((Object)(object)val != (Object)null)
		{
			Cards.instance.RemoveCardFromPlayer(player, val, (SelectionType)0, true);
			Debug.Log("[JoJo] player " + player.playerID + " lost " + val.cardName);
			yield return (object)new WaitForSeconds(0.3f);
			if ((Object)(object)player == (Object)null)
			{
				yield break;
			}
		}
		if (!((Object)(object)card == (Object)null))
		{
			Cards.instance.AddCardToPlayer(player, card, false, "", 2f, 0f, true);
			Debug.Log("[JoJo] player " + player.playerID + " awakened " + card.cardName);
		}
	}
}
public static class StandStats
{
	public const int MaxGrade = 4;

	public static readonly string[] Titles = new string[5] { "Stand Power", "Stand Speed", "Stand Range", "Stand Durability", "Stand Precision" };

	public const float PowerPerGrade = 0.2f;

	public const float SpeedPerGrade = 0.85f;

	public const float RangePerGrade = 0.2f;

	public const float CritPerGrade = 0.15f;

	public static int Grade(Player p, string title)
	{
		int num = 0;
		List<CardInfo> list = (((Object)(object)p != (Object)null) ? p.data.currentCards : null);
		if (list != null)
		{
			foreach (CardInfo item in list)
			{
				if ((Object)(object)item != (Object)null && item.cardName == title)
				{
					num++;
				}
			}
		}
		return Mathf.Min(num, 4);
	}

	public static bool IsStatCard(CardInfo card)
	{
		if ((Object)(object)card != (Object)null)
		{
			return Array.IndexOf(Titles, card.cardName) >= 0;
		}
		return false;
	}

	public static float DamageMult(Player p)
	{
		return (1f + 0.2f * (float)Grade(p, Titles[0])) * StandConfig.DamageMult;
	}

	public static float CooldownMult(Player p)
	{
		return Mathf.Pow(0.85f, (float)Grade(p, Titles[1])) * StandConfig.CooldownMult;
	}

	public static float RangeMult(Player p)
	{
		return 1f + 0.2f * (float)Grade(p, Titles[2]);
	}

	public static float CritChance(Player p)
	{
		return 0.15f * (float)Grade(p, Titles[4]);
	}

	public static float Damage(Player owner, float baseDamage)
	{
		Gun val = (((Object)(object)owner.data.weaponHandler != (Object)null) ? owner.data.weaponHandler.gun : null);
		float num = baseDamage * (((Object)(object)val != (Object)null) ? Mathf.Max(0.2f, val.damage) : 1f) * DamageMult(owner);
		if (Random.value < CritChance(owner))
		{
			num *= 2f;
		}
		return num;
	}

	public static string GradeLetter(int grade)
	{
		return "EDCBA".Substring(Mathf.Clamp(grade, 0, 4), 1);
	}
}
public abstract class StandStatCard : CustomCard
{
	protected abstract int Index { get; }

	protected abstract string Effect { get; }

	protected virtual void Stats(Gun gun, CharacterStatModifiers statModifiers, Block block)
	{
	}

	public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
	{
		cardInfo.allowMultiple = true;
		Stats(gun, statModifiers, block);
	}

	public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
	{
	}

	protected override string GetTitle()
	{
		return StandStats.Titles[Index];
	}

	protected override string GetDescription()
	{
		return "Your Stand's " + StandStats.Titles[Index].Substring(6).ToLower() + " goes up a grade: E, D, C, B, A. Only with a Stand.";
	}

	protected override GameObject GetCardArt()
	{
		return CardArt.Get(StandStats.Titles[Index].ToLower().Replace(" ", "_") + "_cardart.png");
	}

	protected override Rarity GetRarity()
	{
		return (Rarity)0;
	}

	protected override CardInfoStat[] GetStats()
	{
		return (CardInfoStat[])(object)new CardInfoStat[1] { CardArt.Stat(positive: true, StandStats.Titles[Index].Substring(6), Effect) };
	}

	protected override CardThemeColorType GetTheme()
	{
		return (CardThemeColorType)8;
	}

	public override string GetModName()
	{
		return "Bizarre JoJo Stands";
	}
}
public class StandPowerCard : StandStatCard
{
	protected override int Index => 0;

	protected override string Effect => "+20% Stand damage";
}
public class StandSpeedCard : StandStatCard
{
	protected override int Index => 1;

	protected override string Effect => "-15% ability cooldowns";
}
public class StandRangeCard : StandStatCard
{
	protected override int Index => 2;

	protected override string Effect => "+20% reach and range";
}
public class StandDurabilityCard : StandStatCard
{
	protected override int Index => 3;

	protected override string Effect => "+30% health, -10% block cooldown";

	protected override void Stats(Gun gun, CharacterStatModifiers statModifiers, Block block)
	{
		statModifiers.health = 1.3f;
		block.cdMultiplier = 0.9f;
	}
}
public class StandPrecisionCard : StandStatCard
{
	protected override int Index => 4;

	protected override string Effect => "+15% chance of double-damage hits";
}
public static class StandConfig
{
	public static ConfigEntry<KeyCode>[] Keys;

	public static ConfigEntry<KeyCode> GunKey;

	public static ConfigEntry<float> Volume;

	public static ConfigEntry<bool> Hud;

	public static ConfigEntry<bool> Hints;

	public static ConfigEntry<bool> CooldownText;

	public static ConfigEntry<bool> Menacing;

	public static ConfigEntry<bool> TimeStopColors;

	private static ConfigEntry<float> cooldownMult;

	private static ConfigEntry<float> damageMult;

	private static ConfigEntry<bool> multipleStands;

	private static readonly Dictionary<string, ConfigEntry<bool>> standEnabled = new Dictionary<string, ConfigEntry<bool>>();

	private static ConfigFile file;

	public static float CooldownMult = 1f;

	public static float DamageMult = 1f;

	public static bool MultipleStands;

	private static readonly HashSet<string> disabled = new HashSet<string>();

	public static void Bind(ConfigFile cfg)
	{
		file = cfg;
		Keys = new ConfigEntry<KeyCode>[4]
		{
			cfg.Bind<KeyCode>("Controls", "Ability1", (KeyCode)113, "Keyboard key for a Stand's first ability (controller: D-pad Down)."),
			cfg.Bind<KeyCode>("Controls", "Ability2", (KeyCode)101, "Keyboard key for a Stand's second ability (controller: D-pad Left)."),
			cfg.Bind<KeyCode>("Controls", "Ability3", (KeyCode)114, "Keyboard key for a Stand's third ability (controller: D-pad Right)."),
			cfg.Bind<KeyCode>("Controls", "Ability4", (KeyCode)116, "Keyboard key for a Stand's fourth ability, for Stands that have one, e.g. The World's time stop (controller: D-pad Up).")
		};
		GunKey = cfg.Bind<KeyCode>("Controls", "GunToggle", (KeyCode)99, "With a Stand your gun is put away and the fire button throws a Stand punch. This key takes the gun out, and puts it away again (controller: right stick click).");
		Volume = cfg.Bind<float>("Presentation", "Volume", 0.6f, "Volume of the mod's sound effects (0 = off, 1 = full).");
		Hud = cfg.Bind<bool>("Presentation", "AbilityHud", true, "Show your Stand's abilities and cooldowns in the bottom-right corner.");
		Hints = cfg.Bind<bool>("Presentation", "AwakeningHints", true, "When you get a Stand, show what each of its buttons does.");
		CooldownText = cfg.Bind<bool>("Presentation", "CooldownsAboveStand", false, "Also show cooldowns as text above your Stand (always on when the HUD is off).");
		Menacing = cfg.Bind<bool>("Presentation", "Menacing", true, "Menacing ゴゴゴ drifts off Stand users now and then.");
		TimeStopColors = cfg.Bind<bool>("Presentation", "TimeStopColors", true, "Shift the screen's colours while time is stopped.");
		cooldownMult = cfg.Bind<float>("Gameplay", "CooldownMultiplier", 1f, "Multiplies every Stand ability cooldown (0.5 = twice as often). The host's value is used online.");
		damageMult = cfg.Bind<float>("Gameplay", "DamageMultiplier", 1f, "Multiplies all Stand damage. The host's value is used online.");
		multipleStands = cfg.Bind<bool>("Gameplay", "AllowMultipleStands", false, "Let the Stand Arrow keep giving new Stands to players who already have one. All of a player's Stands answer the same buttons. The host's value is used online.");
		ApplyLocal();
	}

	public static void BindStand(string title, bool evolved)
	{
		standEnabled[title] = file.Bind<bool>("Stands", SafeKey(title), true, evolved ? (title + ": can be reached by evolving a Stand (Requiem Arrow or Saint's Corpse Part).") : (title + ": can be awakened by the Stand Arrow."));
		if (!standEnabled[title].Value)
		{
			disabled.Add(title);
		}
	}

	private static string SafeKey(string title)
	{
		string text = title;
		string[] array = new string[8] { "=", "\n", "\t", "\\", "\"", "'", "[", "]" };
		foreach (string oldValue in array)
		{
			text = text.Replace(oldValue, "");
		}
		return text;
	}

	public static bool Enabled(string title)
	{
		return !disabled.Contains(title);
	}

	public static void ApplyLocal()
	{
		if (file != null)
		{
			file.Reload();
		}
		CooldownMult = Mathf.Clamp(cooldownMult.Value, 0.1f, 10f);
		DamageMult = Mathf.Clamp(damageMult.Value, 0f, 10f);
		MultipleStands = multipleStands.Value;
		disabled.Clear();
		foreach (KeyValuePair<string, ConfigEntry<bool>> item in standEnabled)
		{
			if (!item.Value.Value)
			{
				disabled.Add(item.Key);
			}
		}
	}

	public static void Sync()
	{
		if (PhotonNetwork.OfflineMode || !PhotonNetwork.InRoom)
		{
			ApplyLocal();
		}
		else if (PhotonNetwork.IsMasterClient)
		{
			ApplyLocal();
			NetworkingManager.RPC_Others(typeof(StandConfig), "RPCA_Sync", new object[4]
			{
				CooldownMult,
				DamageMult,
				MultipleStands,
				string.Join("|", new List<string>(disabled).ToArray())
			});
		}
	}

	[UnboundRPC]
	public static void RPCA_Sync(float cooldown, float damage, bool multiple, string off)
	{
		CooldownMult = cooldown;
		DamageMult = damage;
		MultipleStands = multiple;
		disabled.Clear();
		string[] array = off.Split(new char[1] { '|' });
		foreach (string text in array)
		{
			if (text.Length > 0)
			{
				disabled.Add(text);
			}
		}
		Debug.Log("[JoJo] using the host's settings (cooldowns x" + cooldown + ", damage x" + damage + ", multiple Stands " + multiple + ")");
	}

	public static KeyCode Key(int slot)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (Keys == null)
		{
			return (KeyCode)(slot switch
			{
				2 => 114, 
				1 => 101, 
				0 => 113, 
				_ => 116, 
			});
		}
		return Keys[slot].Value;
	}

	public unsafe static string KeyLabel(int slot)
	{
		//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_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Invalid comparison between Unknown and I4
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Invalid comparison between Unknown and I4
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Invalid comparison between Unknown and I4
		KeyCode val = Key(slot);
		string text = ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString();
		if (text.StartsWith("Alpha"))
		{
			return text.Substring(5);
		}
		if (text.StartsWith("Keypad"))
		{
			return "Num" + text.Substring(6);
		}
		if ((int)val == 325)
		{
			return "MMB";
		}
		if ((int)val == 326)
		{
			return "M4";
		}
		if ((int)val == 327)
		{
			return "M5";
		}
		return text;
	}
}
public class MenacingFx : MonoBehaviour
{
	private static Sprite sprite;

	private static bool loaded;

	private SpriteRenderer sr;

	private float born;

	private float delay;

	private float life = 1.6f;

	private Vector3 drift;

	public static void Burst(Vector3 near, int count)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		if (StandConfig.Menacing == null || !StandConfig.Menacing.Value)
		{
			return;
		}
		if (!loaded)
		{
			loaded = true;
			Texture2D val = CardArt.LoadTexture("menacing.png", warnIfMissing: false);
			if ((Object)(object)val != (Object)null)
			{
				sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)((Texture)val).height / 0.9f);
			}
		}
		if (!((Object)(object)sprite == (Object)null))
		{
			float num = ((Random.value < 0.5f) ? (-1f) : 1f);
			for (int i = 0; i < count; i++)
			{
				GameObject val2 = new GameObject("Menacing");
				val2.transform.position = near + new Vector3(num * (1.4f + (float)i * 0.35f), 0.4f + (float)i * 0.75f, 0f);
				val2.transform.rotation = Quaternion.Euler(0f, 0f, Random.Range(-14f, 14f));
				MenacingFx menacingFx = val2.AddComponent<MenacingFx>();
				menacingFx.sr = val2.AddComponent<SpriteRenderer>();
				menacingFx.sr.sprite = sprite;
				((Renderer)menacingFx.sr).sortingOrder = 30;
				menacingFx.sr.color = new Color(1f, 1f, 1f, 0f);
				menacingFx.born = Time.time;
				menacingFx.delay = (float)i * 0.18f;
				menacingFx.drift = new Vector3(num * 0.25f, 0.6f, 0f);
			}
		}
	}

	private void Update()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
		float num = (Time.time - born - delay) / life;
		if (num >= 1f)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
		else if (!(num < 0f))
		{
			Transform transform = ((Component)this).transform;
			transform.position += drift * Time.deltaTime;
			float num2 = ((num < 0.12f) ? Mathf.Lerp(1.5f, 1f, num / 0.12f) : (1f + Mathf.Sin(num * 30f) * 0.03f));
			((Component)this).transform.localScale = Vector3.one * num2;
			sr.color = new Color(1f, 1f, 1f, (num < 0.7f) ? 0.9f : (0.9f * (1f - (num - 0.7f) / 0.3f)));
		}
	}
}
public static class Sfx
{
	private const int Rate = 44100;

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

	private static AudioSource[] voices;

	private static int next;

	private static readonly Random rnd = new Random(7);

	public static void Play(string name, float volume = 1f, float pitch = 1f)
	{
		try
		{
			float num = ((StandConfig.Volume != null) ? StandConfig.Volume.Value : 0.6f);
			if (num <= 0f)
			{
				return;
			}
			AudioClip val = Clip(name);
			if (!((Object)(object)val == (Object)null))
			{
				if (voices == null)
				{
					MakeVoices();
				}
				AudioSource obj = voices[next];
				next = (next + 1) % voices.Length;
				obj.pitch = pitch;
				obj.PlayOneShot(val, Mathf.Clamp01(volume * num));
			}
		}
		catch (Exception ex)
		{
			Debug.Log("[JoJo] sound " + name + " failed: " + ex.Message);
		}
	}

	private static void MakeVoices()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		GameObject val = new GameObject("JoJoSfx");
		Object.DontDestroyOnLoad((Object)(object)val);
		voices = (AudioSource[])(object)new AudioSource[10];
		for (int i = 0; i < voices.Length; i++)
		{
			voices[i] = val.AddComponent<AudioSource>();
			voices[i].playOnAwake = false;
			voices[i].spatialBlend = 0f;
		}
	}

	private static AudioClip Clip(string name)
	{
		if (clips.TryGetValue(name, out var value))
		{
			return value;
		}
		float[] array;
		switch (name)
		{
		case "punch":
			array = Punch(0.09f, 90f, 0.7f);
			break;
		case "heavy":
			array = Punch(0.22f, 60f, 1f);
			break;
		case "whoosh":
			array = Whoosh(0.28f);
			break;
		case "cast":
			array = Sweep(0.18f, 420f, 980f, 0.35f);
			break;
		case "timestop":
			array = TimeStopSound();
			break;
		case "timeresume":
			array = Sweep(0.7f, 90f, 900f, 0.6f);
			break;
		case "tick":
			array = Tick();
			break;
		case "boom":
			array = Boom();
			break;
		case "zip":
			array = Zip();
			break;
		case "chime":
			array = Chime();
			break;
		case "hum":
			array = Hum();
			break;
		case "awaken":
			array = Awaken();
			break;
		default:
			return null;
		}
		value = AudioClip.Create("jojo_" + name, array.Length, 1, 44100, false);
		value.SetData(array, 0);
		clips[name] = value;
		return value;
	}

	private static float Noise()
	{
		return (float)(rnd.NextDouble() * 2.0 - 1.0);
	}

	private static float[] Punch(float length, float thump, float amp)
	{
		int num = (int)(length * 44100f);
		float[] array = new float[num];
		double num2 = 0.0;
		for (int i = 0; i < num; i++)
		{
			float num3 = (float)i / 44100f / length;
			float num4 = Mathf.Exp((0f - num3) * 6f);
			num2 += Math.PI * 2.0 * (double)thump * (double)(1.6f - num3 * 0.8f) / 44100.0;
			array[i] = amp * (0.75f * (float)Math.Sin(num2) * num4 + 0.45f * Noise() * Mathf.Exp((0f - num3) * 22f));
		}
		return array;
	}

	private static float[] Whoosh(float length)
	{
		int num = (int)(length * 44100f);
		float[] array = new float[num];
		float num2 = 0f;
		for (int i = 0; i < num; i++)
		{
			float num3 = (float)i / (float)num;
			float num4 = Mathf.Lerp(0.02f, 0.25f, Mathf.Sin(num3 * (float)Math.PI));
			num2 += (Noise() - num2) * num4;
			array[i] = num2 * Mathf.Sin(num3 * (float)Math.PI) * 1.4f;
		}
		return array;
	}

	private static float[] Sweep(float length, float from, float to, float amp)
	{
		int num = (int)(length * 44100f);
		float[] array = new float[num];
		double num2 = 0.0;
		for (int i = 0; i < num; i++)
		{
			float num3 = (float)i / (float)num;
			num2 += Math.PI * 2.0 * (double)Mathf.Lerp(from, to, num3 * num3) / 44100.0;
			float num4 = Mathf.Min(1f, num3 * 20f) * (1f - num3);
			array[i] = amp * num4 * ((float)Math.Sin(num2) * 0.7f + (float)Math.Sin(num2 * 2.01) * 0.3f);
		}
		return array;
	}

	private static float[] TimeStopSound()
	{
		int num = 61740;
		float[] array = new float[num];
		double num2 = 0.0;
		double num3 = 0.0;
		double num4 = 0.0;
		for (int i = 0; i < num; i++)
		{
			float num5 = (float)i / (float)num;
			num2 += Math.PI * 2.0 * (double)Mathf.Lerp(900f, 55f, Mathf.Sqrt(num5)) / 44100.0;
			num3 += 0.07451487337085995;
			num4 += 0.11170107212763708;
			float num6 = Mathf.Min(1f, num5 * 30f) * Mathf.Pow(1f - num5, 1.5f);
			float num7 = ((float)Math.Sin(num3) + (float)Math.Sin(num4)) * 0.18f * (1f - num5) * (0.6f + 0.4f * Mathf.Sin(num5 * 60f));
			array[i] = num6 * ((float)Math.Sin(num2) * 0.7f + num7 + Noise() * 0.06f);
		}
		return array;
	}

	private static float[] Tick()
	{
		int num = 2205;
		float[] array = new float[num];
		double num2 = 0.0;
		for (int i = 0; i < num; i++)
		{
			float num3 = (float)i / (float)num;
			num2 += Math.PI * 16.0 / 147.0;
			array[i] = (float)Math.Sin(num2) * Mathf.Exp((0f - num3) * 18f) * 0.5f + Noise() * Mathf.Exp((0f - num3) * 40f) * 0.3f;
		}
		return array;
	}

	private static float[] Boom()
	{
		int num = 39690;
		float[] array = new float[num];
		float num2 = 0f;
		double num3 = 0.0;
		for (int i = 0; i < num; i++)
		{
			float num4 = (float)i / (float)num;
			num2 += (Noise() - num2) * Mathf.Lerp(0.5f, 0.03f, num4);
			num3 += Math.PI * 2.0 * (double)Mathf.Lerp(70f, 35f, num4) / 44100.0;
			array[i] = (num2 * 1.2f + (float)Math.Sin(num3) * 0.6f) * Mathf.Exp((0f - num4) * 4.5f);
		}
		return array;
	}

	private static float[] Zip()
	{
		int num = 14112;
		float[] array = new float[num];
		for (int i = 0; i < 22; i++)
		{
			int num2 = (int)((float)i / 22f * (float)num);
			for (int j = 0; j < 300 && num2 + j < num; j++)
			{
				array[num2 + j] += Noise() * Mathf.Exp((float)(-j) / 40f) * 0.6f;
			}
		}
		return array;
	}

	private static float[] Chime()
	{
		int num = 26460;
		float[] array = new float[num];
		float[] array2 = new float[3] { 660f, 880f, 1320f };
		for (int i = 0; i < array2.Length; i++)
		{
			int num2 = (int)((float)i * 0.08f * 44100f);
			for (int j = num2; j < num; j++)
			{
				float num3 = (float)(j - num2) / 44100f;
				array[j] += (float)Math.Sin(Math.PI * 2.0 * (double)array2[i] * (double)num3) * Mathf.Exp((0f - num3) * 5f) * 0.25f;
			}
		}
		return array;
	}

	private static float[] Hum()
	{
		int num = 24255;
		float[] array = new float[num];
		for (int i = 0; i < num; i++)
		{
			float num2 = (float)i / 44100f;
			float num3 = (float)i / (float)num;
			float num4 = Mathf.Min(1f, num3 * 10f) * (1f - num3);
			array[i] = num4 * 0.4f * (float)Math.Sin(Math.PI * 440.0 * (double)num2) * (0.7f + 0.3f * Mathf.Sin(num2 * 2f * (float)Math.PI * 9f));
		}
		return array;
	}

	private static float[] Awaken()
	{
		int num = 52920;
		float[] array = new float[num];
		float num2 = 0f;
		for (int i = 0; i < num; i++)
		{
			float num3 = (float)i / 44100f;
			float num4 = (float)i / (float)num;
			num2 += (Noise() - num2) * 0.02f;
			float num5 = 0.6f + 0.4f * Mathf.Sin(num3 * 2f * (float)Math.PI * 7f);
			float num6 = Mathf.Sin(num4 * (float)Math.PI);
			array[i] = num6 * num5 * (num2 * 2.2f + (float)Math.Sin(Math.PI * 96.0 * (double)num3) * 0.35f);
		}
		return array;
	}
}
public class StandHud : MonoBehaviour
{
	private class Tile
	{
		public Image border;

		public Image sweep;

		public TextMeshProUGUI key;

		public TextMeshProUGUI time;

		public TextMeshProUGUI name;
	}

	private class Row
	{
		public GameObject go;

		public TextMeshProUGUI title;

		public TextMeshProUGUI grades;

		public string gradeText;

		public Tile[] tiles;
	}

	private static StandHud instance;

	private static readonly HashSet<string> hinted = new HashSet<string>();

	private RectTransform canvas;

	private readonly Dictionary<Stand, Row> rows = new Dictionary<Stand, Row>();

	private float nextScan;

	private static readonly string[] GradeLabels = new string[5] { "PWR", "SPD", "RNG", "DUR", "PRC" };

	private static readonly string[] GradeColors = new string[5] { "#8a86a0", "#b4d2ff", "#8ef0a8", "#ffcf5a", "#ff6a8a" };

	private GameObject hint;

	private CanvasGroup hintGroup;

	private float hintUntil;

	private const float TileStep = 110f;

	private static readonly Vector2 Mid = new Vector2(0.5f, 0.5f);

	private static StandHud Get()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		if ((Object)(object)instance != (Object)null)
		{
			return instance;
		}
		GameObject val = new GameObject("JoJoHud");
		Object.DontDestroyOnLoad((Object)(object)val);
		instance = val.AddComponent<StandHud>();
		Canvas obj = val.AddComponent<Canvas>();
		obj.renderMode = (RenderMode)0;
		obj.sortingOrder = 60;
		CanvasScaler obj2 = val.AddComponent<CanvasScaler>();
		obj2.uiScaleMode = (ScaleMode)1;
		obj2.referenceResolution = new Vector2(1920f, 1080f);
		obj2.matchWidthOrHeight = 0.5f;
		instance.canvas = (RectTransform)val.transform;
		return instance;
	}

	public static void Ensure()
	{
		Get();
	}

	public static void ShowHint(Stand s)
	{
		try
		{
			if (StandConfig.Hints != null && StandConfig.Hints.Value && !((Object)(object)s == (Object)null) && !hinted.Contains(s.CardTitle))
			{
				hinted.Add(s.CardTitle);
				Get().BuildHint(s);
				Sfx.Play("awaken", 0.9f);
			}
		}
		catch (Exception ex)
		{
			Debug.Log("[JoJo] no hint: " + ex.Message);
		}
	}

	private void BuildHint(Stand s)
	{
		//IL_002f: 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_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_009b: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: 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)
		if ((Object)(object)hint != (Object)null)
		{
			Object.Destroy((Object)(object)hint);
		}
		hint = Panel((Transform)(object)canvas, "Hint", new Vector2(0.5f, 0f), new Vector2(0f, 170f), new Vector2(1100f, 150f), new Color(0.05f, 0.03f, 0.1f, 0.78f));
		hintGroup = hint.AddComponent<CanvasGroup>();
		Color color = Color.Lerp(s.Look.Glow, Color.white, 0.2f);
		((TMP_Text)Text(hint.transform, "STAND: " + s.CardTitle.ToUpper(), 40f, color, Mid, new Vector2(0f, 32f), new Vector2(1060f, 60f))).fontStyle = (FontStyles)3;
		string text = "<color=#ffe08a>Block</color>  " + s.BlockName;
		for (int i = 0; i < s.AbilityCount; i++)
		{
			text = text + "     <color=#ffe08a>" + StandConfig.KeyLabel(i) + "</color>  " + s.AbilityName(i);
		}
		if (s.HolstersGun)
		{
			text = text + "     <color=#ffe08a>Fire</color>  Punch     <color=#ffe08a>" + ((StandConfig.GunKey != null) ? ((object)StandConfig.GunKey.Value/*cast due to .constrained prefix*/).ToString() : "C") + "</color>  Gun";
		}
		TextMeshProUGUI obj = Text(hint.transform, text, 24f, Color.white, Mid, new Vector2(0f, -28f), new Vector2(1060f, 60f));
		((TMP_Text)obj).enableAutoSizing = true;
		((TMP_Text)obj).fontSizeMin = 14f;
		((TMP_Text)obj).fontSizeMax = 24f;
		hintUntil = Time.unscaledTime + 7f;
	}

	private void Update()
	{
		if ((Object)(object)hint != (Object)null)
		{
			float num = hintUntil - Time.unscaledTime;
			hintGroup.alpha = Mathf.Clamp01(num / 0.8f);
			if (num <= 0f)
			{
				Object.Destroy((Object)(object)hint);
				hint = null;
			}
		}
		bool flag = StandConfig.Hud != null && StandConfig.Hud.Value;
		if (Time.unscaledTime >= nextScan)
		{
			nextScan = Time.unscaledTime + 0.25f;
			Rescan(flag);
		}
		foreach (KeyValuePair<Stand, Row> row in rows)
		{
			Refresh(row.Key, row.Value);
		}
	}

	private void Rescan(bool on)
	{
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		List<Stand> list = new List<Stand>();
		if (on && (Object)(object)PlayerManager.instance != (Object)null)
		{
			Stand[] array = Object.FindObjectsOfType<Stand>();
			foreach (Stand stand in array)
			{
				if ((Object)(object)stand != (Object)null && (Object)(object)stand.Owner != (Object)null && stand.Owner.data.view.IsMine && !stand.Owner.data.dead)
				{
					list.Add(stand);
				}
			}
		}
		List<Stand> list2 = new List<Stand>();
		foreach (KeyValuePair<Stand, Row> row in rows)
		{
			if (!list.Contains(row.Key))
			{
				list2.Add(row.Key);
			}
		}
		foreach (Stand item in list2)
		{
			if ((Object)(object)rows[item].go != (Object)null)
			{
				Object.Destroy((Object)(object)rows[item].go);
			}
			rows.Remove(item);
		}
		for (int j = 0; j < list.Count && j < 4; j++)
		{
			if (!rows.ContainsKey(list[j]))
			{
				rows[list[j]] = BuildRow(list[j]);
			}
		}
		int num = 0;
		foreach (KeyValuePair<Stand, Row> row2 in rows)
		{
			if ((Object)(object)row2.Value.go != (Object)null)
			{
				((RectTransform)row2.Value.go.transform).anchoredPosition = new Vector2(-30f, (float)(30 + num++ * 175));
			}
		}
		foreach (KeyValuePair<Stand, Row> row3 in rows)
		{
			if (!((Object)(object)row3.Value.go == (Object)null) && !((Object)(object)row3.Key == (Object)null))
			{
				string text = GradeLine(row3.Key.Owner);
				if (!(text == row3.Value.gradeText))
				{
					row3.Value.gradeText = text;
					((TMP_Text)row3.Value.grades).text = text;
				}
			}
		}
	}

	private Row BuildRow(Stand s)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		//IL_005b: 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_0064: 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_006c: 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_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_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0340: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_0382: Unknown result type (might be due to invalid IL or missing references)
		//IL_0387: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
		Row row = new Row();
		row.go = new GameObject("StandRow", new Type[1] { typeof(RectTransform) });
		RectTransform val = (RectTransform)row.go.transform;
		((Transform)val).SetParent((Transform)(object)canvas, false);
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(1f, 0f);
		val.pivot = val2;
		Vector2 anchorMin = (val.anchorMax = val2);
		val.anchorMin = anchorMin;
		float num = (float)Mathf.Max(3, s.AbilityCount) * 110f;
		val.sizeDelta = new Vector2(num, 165f);
		Color color = Color.Lerp(s.Look.Glow, Color.white, 0.2f);
		row.title = Text((Transform)(object)val, s.CardTitle, 20f, color, Vector2.zero, new Vector2(num / 2f, 147f), new Vector2(num, 30f));
		((TMP_Text)row.title).alignment = (TextAlignmentOptions)516;
		((TMP_Text)row.title).fontStyle = (FontStyles)3;
		row.grades = Text((Transform)(object)val, "", 15f, new Color(0.85f, 0.85f, 0.9f), Vector2.zero, new Vector2(num / 2f, 121f), new Vector2(num, 24f));
		((TMP_Text)row.grades).alignment = (TextAlignmentOptions)516;
		row.tiles = new Tile[s.AbilityCount];
		for (int i = 0; i < s.AbilityCount; i++)
		{
			Tile tile = new Tile();
			float num2 = 55f + (float)i * 110f;
			GameObject val4 = Panel((Transform)(object)val, "Tile", Vector2.zero, new Vector2(num2, 70f), new Vector2(68f, 68f), color);
			((RectTransform)val4.transform).pivot = new Vector2(0.5f, 0.5f);
			tile.border = val4.GetComponent<Image>();
			Panel(val4.transform, "Inner", new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(60f, 60f), new Color(0.06f, 0.04f, 0.12f, 0.9f));
			GameObject val5 = Panel(val4.transform, "Sweep", new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(60f, 60f), new Color(0f, 0f, 0f, 0.65f));
			tile.sweep = val5.GetComponent<Image>();
			tile.sweep.type = (Type)3;
			tile.sweep.fillMethod = (FillMethod)4;
			tile.sweep.fillOrigin = 2;
			tile.sweep.fillClockwise = false;
			tile.key = Text(val4.transform, StandConfig.KeyLabel(i), 30f, Color.white, Mid, Vector2.zero, new Vector2(60f, 60f));
			((TMP_Text)tile.key).fontStyle = (FontStyles)1;
			tile.time = Text(val4.transform, "", 22f, new Color(1f, 0.9f, 0.6f), Mid, Vector2.zero, new Vector2(60f, 60f));
			tile.name = Text((Transform)(object)val, s.AbilityName(i), 15f, new Color(0.9f, 0.9f, 0.95f), Vector2.zero, new Vector2(num2, 14f), new Vector2(104f, 40f));
			((TMP_Text)tile.name).enableAutoSizing = false;
			((TMP_Text)tile.name).enableWordWrapping = true;
			((TMP_Text)tile.name).overflowMode = (TextOverflowModes)1;
			((TMP_Text)tile.name).alignment = (TextAlignmentOptions)258;
			row.tiles[i] = tile;
		}
		return row;
	}

	private void Refresh(Stand s, Row row)
	{
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)s == (Object)null) && !((Object)(object)row.go == (Object)null))
		{
			for (int i = 0; i < row.tiles.Length && i < s.AbilityCount; i++)
			{
				Tile obj = row.tiles[i];
				float num = s.CooldownLeft(i);
				bool flag = num <= 0f;
				obj.sweep.fillAmount = s.CooldownFraction(i);
				((TMP_Text)obj.key).fontSize = (flag ? 30 : 16);
				((TMP_Text)obj.key).rectTransform.anchoredPosition = (Vector2)(flag ? Vector2.zero : new Vector2(-18f, 18f));
				((TMP_Text)obj.time).text = (flag ? "" : Mathf.CeilToInt(num).ToString());
				Color color = ((Graphic)obj.border).color;
				color.a = (flag ? 0.95f : 0.35f);
				((Graphic)obj.border).color = color;
			}
		}
	}

	private static string GradeLine(Player p)
	{
		string text = "";
		for (int i = 0; i < GradeLabels.Length; i++)
		{
			int num = StandStats.Grade(p, StandStats.Titles[i]);
			if (i > 0)
			{
				text += "   ";
			}
			text = text + GradeLabels[i] + " <b><color=" + GradeColors[num] + ">" + StandStats.GradeLetter(num) + "</color></b>";
		}
		return text;
	}

	private static GameObject Panel(Transform parent, string name, Vector2 anchor, Vector2 pos, Vector2 size, Color color)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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_005f: 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_007f: Expected O, but got Unknown
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		RectTransform val2 = (RectTransform)val.transform;
		((Transform)val2).SetParent(parent, false);
		Vector2 anchorMin = (val2.anchorMax = anchor);
		val2.anchorMin = anchorMin;
		val2.pivot = new Vector2(0.5f, 0.5f);
		val2.anchoredPosition = pos;
		val2.sizeDelta = size;
		Image obj = val.AddComponent<Image>();
		obj.sprite = StandSprites.White();
		((Graphic)obj).color = color;
		((Graphic)obj).raycastTarget = false;
		return val;
	}

	private static TextMeshProUGUI Text(Transform parent, string text, float size, Color color, Vector2 anchor, Vector2 pos, Vector2 box)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Text", new Type[1] { typeof(RectTransform) });
		RectTransform val2 = (RectTransform)val.transform;
		((Transform)val2).SetParent(parent, false);
		Vector2 anchorMin = (val2.anchorMax = anchor);
		val2.anchorMin = anchorMin;
		val2.pivot = new Vector2(0.5f, 0.5f);
		val2.anchoredPosition = pos;
		val2.sizeDelta = box;
		TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
		((TMP_Text)obj).text = text;
		((TMP_Text)obj).fontSize = size;
		((Graphic)obj).color = color;
		((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
		((TMP_Text)obj).enableWordWrapping = false;
		((Graphic)obj).raycastTarget = false;
		((TMP_Text)obj).outlineWidth = 0.2f;
		((TMP_Text)obj).outlineColor = new Color32((byte)10, (byte)5, (byte)20, byte.MaxValue);
		return obj;
	}
}
public static class StandStun
{
	private static readonly FieldRef<CharacterData, float> StunTimeRef = AccessTools.FieldRefAccess<CharacterData, float>("stunTime");

	private static readonly MethodInfo StopStun = AccessTools.Method(typeof(StunHandler), "StopStun", (Type[])null, (Type[])null);

	public static void Clear(Player p)
	{
		try
		{
			StunTimeRef.Invoke(p.data) = 0f;
			if ((Object)(object)p.data.stunHandler != (Object)null && StopStun != null)
			{
				StopStun.Invoke(p.data.stunHandler, null);
			}
		}
		catch (Exception ex)
		{
			Debug.Log("[JoJo] could not end the stun: " + ex.Message);
		}
	}
}
public class StandSilence : MonoBehaviour
{
	private Player player;

	private float until;

	private float nextPulse;

	public static bool IsSilenced(Player p)
	{
		StandSilence standSilence = (((Object)(object)p != (Object)null) ? ((Component)p).GetComponent<StandSilence>() : null);
		if ((Object)(object)standSilence != (Object)null)
		{
			return Time.time < standSilence.until;
		}
		return false;
	}

	public static void Apply(Player target, float seconds)
	{
		//IL_0041: 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)
		//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)
		//IL_008f: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		StandSilence standSilence = ((Component)target).GetComponent<StandSilence>();
		if ((Object)(object)standSilence == (Object)null)
		{
			standSilence = ((Component)target).gameObject.AddComponent<StandSilence>();
		}
		standSilence.player = target;
		standSilence.until = Mathf.Max(standSilence.until, Time.time + seconds);
		RingFx.Spawn(((Component)target).transform.position, new Color(0.95f, 0.95f, 1f, 0.9f), 2f, 0.3f, 0.4f);
		PopText.Spawn("STAND DISC STOLEN", ((Component)target).transform.position + Vector3.up * 2.4f, new Color(0.9f, 0.92f, 1f), 6f, 1.2f, Vector3.up * 0.5f);
		Sfx.Play("whoosh", 0.8f, 1.4f);
	}

	private void Update()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null || player.data.dead || Time.time >= until)
		{
			Object.Destroy((Object)(object)this);
		}
		else if (!(Time.time < nextPulse))
		{
			nextPulse = Time.time + 0.5f;
			RingFx.Spawn(((Component)player).transform.position + Vector3.up * 1.6f, new Color(0.9f, 0.9f, 1f, 0.5f), 0.2f, 0.45f, 0.4f, filled: true);
		}
	}
}
public class SoundTrap : MonoBehaviour
{
	private static readonly Dictionary<int, SoundTrap> traps = new Dictionary<int, SoundTrap>();

	private static int counter;

	private Player owner;

	private int id;

	private float until;

	private float radius;

	private bool armed = true;

	private string word;

	private TextMeshPro label;

	public static void Send(Player owner, Vector2 at, float radius, float seconds, string word)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		counter++;
		NetworkingManager.RPC(typeof(SoundTrap), "RPCA_Spawn", new object[7]
		{
			owner.playerID,
			owner.playerID * 1000 + counter % 1000,
			at.x,
			at.y,
			radius,
			seconds,
			word
		});
	}

	[UnboundRPC]
	public static void RPCA_Spawn(int ownerId, int id, float x, float y, float radius, float seconds, string word)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_0029: 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_0103: Unknown result type (might be due to invalid IL or missing references)
		Player val = StandNet.FindPlayer(ownerId);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		GameObject val2 = new GameObject("SoundTrap");
		val2.transform.position = new Vector3(x, y, 0f);
		SoundTrap soundTrap = val2.AddComponent<SoundTrap>();
		soundTrap.owner = val;
		soundTrap.id = id;
		soundTrap.radius = radius;
		soundTrap.word = word;
		soundTrap.until = Time.time + seconds;
		traps[id] = soundTrap;
		try
		{
			soundTrap.label = val2.AddComponent<TextMeshPro>();
			((TMP_Text)soundTrap.label).text = word;
			((TMP_Text)soundTrap.label).fontSize = 5f;
			((TMP_Text)soundTrap.label).fontStyle = (FontStyles)3;
			((TMP_Text)soundTrap.label).alignment = (TextAlignmentOptions)514;
			((TMP_Text)soundTrap.label).enableWordWrapping = false;
			((Graphic)soundTrap.label).color = new Color(1f, 0.6f, 0.75f);
			((TMP_Text)soundTrap.label).outlineWidth = 0.25f;
			((TMP_Text)soundTrap.label).outlineColor = new Color32((byte)40, (byte)10, (byte)30, byte.MaxValue);
			MeshRenderer component = val2.GetComponent<MeshRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				((Renderer)component).sortingOrder = 44;
			}
		}
		catch (Exception ex)
		{
			Debug.Log("[JoJo] no trap label: " + ex.Message);
		}
	}

	[UnboundRPC]
	public static void RPCA_Trigger(int id, int targetId)
	{
		//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_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: 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)
		if (traps.TryGetValue(id, out var value) && !((Object)(object)value == (Object)null))
		{
			Player val = StandNet.FindPlayer(targetId);
			Vector2 val2 = Vector2.op_Implicit(((Component)value).transform.position);
			RingFx.Spawn(Vector2.op_Implicit(val2), new Color(1f, 0.6f, 0.75f, 0.9f), 0.4f, value.radius * 1.6f, 0.4f);
			PopText.Spawn(value.word + "!", Vector2.op_Implicit(val2 + Vector2.up * 1.5f), new Color(1f, 0.6f, 0.75f), 9f, 0.9f, Vector3.up);
			Sfx.Play("boom", 0.6f, 1.6f);
			if ((Object)(object)val != (Object)null && (Object)(object)value.owner != (Object)null && value.owner.data.view.IsMine)
			{
				((Damagable)val.data.healthHandler).CallTakeDamage(Vector2.up * StandStats.Damage(value.owner, 12f), Vector2.op_Implicit(((Component)val).transform.position), (GameObject)null, value.owner, true);
				StandNet.SendPush(val, Vector2.up * 40f, 0.3f);
			}
			Object.Destroy((Object)(object)((Component)value).gameObject);
		}
	}

	private void Update()
	{
		//IL_003b: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)owner == (Object)null || Time.time >= until)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		if ((Object)(object)label != (Object)null)
		{
			((Component)this).transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 6f) * 0.08f);
		}
		if (!armed || !owner.data.view.IsMine)
		{
			return;
		}
		foreach (Player player in PlayerManager.instance.players)
		{
			if (player.teamID != owner.teamID && !player.data.dead && !(Vector2.Distance(Vector2.op_Implicit(((Component)player).transform.position), Vector2.op_Implicit(((Component)this).transform.position)) > radius + ((Component)player).transform.localScale.x * 0.4f))
			{
				armed = false;
				NetworkingManager.RPC(typeof(SoundTrap), "RPCA_Trigger", new object[2] { id, player.playerID });
				break;
			}
		}
	}

	private void OnDestroy()
	{
		if (traps.TryGetValue(id, out var value) && (Object)(object)value == (Object)(object)this)
		{
			traps.Remove(id);
		}
	}
}
public static class StandRegistry
{
	public class Entry
	{
		public string Title;

		public Type StandType;

		public bool Evolved;

		public CardInfo Card;
	}

	public static readonly List<Entry> All = new List<Entry>();

	public static readonly Dictionary<string, string> Evolutions = new Dictionary<string, string>
	{
		{ "Gold Experience", "Gold Experience Requiem" },
		{ "Echoes Act 1", "Echoes Act 2" },
		{ "Echoes Act 2", "Echoes Act 3" },
		{ "Silver Chariot", "Chariot Requiem" },
		{ "Killer Queen", "Killer Queen: Bites the Dust" },
		{ "Whitesnake", "C-Moon" },
		{ "C-Moon", "Made in Heaven" }
	};

	public static readonly Dictionary<string, string> CorpseEvolutions = new Dictionary<string, string>
	{
		{ "The World", "The World Over Heaven" },
		{ "Tusk Act 1", "Tusk Act 2" },
		{ "Tusk Act 2", "Tusk Act 3" },
		{ "Tusk Act 3", "Tusk Act 4" },
		{ "D4C", "D4C Love Train" }
	};

	public static void Add<TCard, TStand>(string title, bool evolved = false) where TCard : StandCard<TStand> where TStand : Stand
	{
		Entry e = new Entry
		{
			Title = title,
			StandType = typeof(TStand),
			Evolved = evolved
		};
		All.Add(e);
		try
		{
			StandConfig.BindStand(title, evolved);
		}
		catch (Exception ex)
		{
			Debug.LogWarning("[JoJo] no on/off setting for " + title + ": " + ex.Message);
		}
		CustomCard.BuildCard<TCard>((Action<CardInfo>)delegate(CardInfo card)
		{
			e.Card = card;
			Plugin.HideFromPicks(card);
		});
	}

	public static Entry Find(string title)
	{
		return All.Find((Entry e) => e.Title == title);
	}

	public static bool IsStandCard(CardInfo card)
	{
		if ((Object)(object)card != (Object)null)
		{
			return Find(card.cardName) != null;
		}
		return false;
	}

	public static Entry StandOf(Player p)
	{
		foreach (Entry item in All)
		{
			if (Stand.HasCard(p, item.Title))
			{
				return item;
			}
		}
		return null;
	}

	public static bool HasAnyStand(Player p)
	{
		return StandOf(p) != null;
	}

	public static Entry Evolvable(Player p)
	{
		return Evolvable(p, Evolutions);
	}

	public static Entry Evolvable(Player p, Dictionary<string, string> chain)
	{
		foreach (Entry item in All)
		{
			if (Stand.HasCard(p, item.Title) && chain.TryGetValue(item.Title, out var value))
			{
				Entry entry = Find(value);
				if (entry != null && (Object)(object)entry.Card != (Object)null && StandConfig.Enabled(value) && !Stand.HasCard(p, value))
				{
					return item;
				}
			}
		}
		return null;
	}

	public static Entry RandomBase(Player p)
	{
		List<Entry> list = All.FindAll((Entry e) => !e.Evolved && (Object)(object)e.Card != (Object)null && StandConfig.Enabled(e.Title) && !Stand.HasCard(p, e.Title));
		float num = 0f;
		foreach (Entry item in list)
		{
			num += Weight(item);
		}
		float num2 = Random.Range(0f, num);
		foreach (Entry item2 in list)
		{
			num2 -= Weight(item2);
			if (num2 <= 0f)
			{
				return item2;
			}
		}
		if (list.Count <= 0)
		{
			return null;
		}
		return list[list.Count - 1];
	}

	public static bool CanAwaken(Player p)
	{
		if (HasAnyStand(p) && !StandConfig.MultipleStands)
		{
			return false;
		}
		return All.Exists((Entry e) => !e.Evolved && (Object)(object)e.Card != (Object)null && StandConfig.Enabled(e.Title) && !Stand.HasCard(p, e.Title));
	}

	private static float Weight(Entry e)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		if ((int)e.Card.rarity != 2)
		{
			return 2f;
		}
		return 1f;
	}
}
public enum HeadStyle
{
	Hair,
	Helmet,
	Ears,
	Curls,
	Pompadour,
	Crest,
	Plume,
	Bird,
	Plain
}
public class StandLook
{
	public string Key;

	public Color Body;

	public Color Glow;

	public Color Accent;

	public Color Detail;

	public Color Eye;

	public HeadStyle Head;
}
public abstract class Stand : MonoBehaviour
{
	protected class Ability
	{
		public string Name;

		public float Cooldown;

		public float ReadyAt;

		public float Duration = 1f;

		public Action<Vector2> Use;

		public Func<bool> CanUse;

		public bool InStoppedTime;
	}

	private struct FistFx
	{
		public SpriteRenderer sr;

		public Vector3 from;

		public Vector3 to;

		public float born;

		public float life;
	}

	public const int FxJab = -1;

	public const int FxBarrage = 0;

	public const int FxPunch = 1;

	public const int FxCast = 2;

	public const int Slots = 4;

	private const float CheckInterval = 0.5f;

	private const float GracePeriod = 2f;

	private const float PunchLength = 0.25f;

	public bool keepWithoutCard;

	protected Player player;

	private float nextBlockMove;

	private float nextCheck;

	private float graceUntil;

	private int standIndex;

	private readonly List<Ability> abilities = new List<Ability>();

	private int lungeFx = -1;

	private float lungeStart = -10f;

	private float nextFist;

	private float nextCry;

	private float nextPunchSound;

	private float nextMenacing;

	protected Vector2 lungeDir = Vector2.right;

	protected Transform root;

	private SpriteRenderer standSr;

	private TextMeshPro cooldownLabel;

	private readonly List<FistFx> fists = new List<FistFx>();

	private float nextTell;

	private const float BarragePulse = 0.25f;

	private const float JabInterval = 0.35f;

	private const float JabReach = 3f;

	private const float JabArc = 50f;

	private const float JabPush = 14f;

	private const float BaseFireInterval = 0.3f;

	private const int MaxJabHits = 6;

	private float nextJab;

	private const float ObjectPushPerDamage = 150f;

	public abstract string CardTitle { get; }

	public abstract StandLook Look { get; }

	public virtual string Cry => "ORA";

	public virtual int BarrageHits => 10;

	public virtual float HitInterval => 0.06f;

	protected virtual float BlockMoveCooldown => 1.2f;

	protected virtual Sprite StrikeSprite => StandSprites.Fist();

	public virtual bool HolstersGun => true;

	protected virtual float JabDamage => 18f;

	protected virtual float BarrageHoldMax => 0f;

	public Player Owner => player;

	public int AbilityCount => Mathf.Min(abilities.Count, 4);

	public string BlockName
	{
		get
		{
			StandRegistry.Entry entry = StandRegistry.Find(CardTitle);
			if (entry != null && (Object)(object)entry.Card != (Object)null && entry.Card.cardStats != null)
			{
				CardInfoStat[] cardStats = entry.Card.cardStats;
				foreach (CardInfoStat val in cardStats)
				{
					if (val != null && val.stat == "Block")
					{
						return val.amount;
					}
				}
			}
			return "Stand attack";
		}
	}

	protected bool IsLocal
	{
		get
		{
			if ((Object)(object)player != (Object)null)
			{
				return player.data.view.IsMine;
			}
			return false;
		}
	}

	protected float DamageStat
	{
		get
		{
			Gun val = (((Object)(object)player.data.weaponHandler != (Object)null) ? player.data.weaponHandler.gun : null);
			return (((Object)(object)val != (Object)null) ? Mathf.Max(0.2f, val.damage) : 1f) * StandStats.DamageMult(player);
		}
	}

	protected float SizeScale => Mathf.Lerp(1f, Mathf.Clamp(((Component)player).transform.localScale.y, 0.7f, 2.5f), 0.6f);

	protected Vector2 Pos => Vector2.op_Implicit(((Component)player).transform.position);

	protected virtual Color CryColor => new Color(1f, 0.85f, 0.35f);

	private float LungeLength
	{
		get
		{
			if (lungeFx != 0)
			{
				if (lungeFx != 2)
				{
					return 0.25f;
				}
				return 0.35f;
			}
			return (float)BarrageHits * HitInterval + 0.1f;
		}
	}

	protected bool Lunging => Time.time - lungeStart < LungeLength;

	protected virtual float IdleAlpha => 0.6f;

	protected virtual float BodyScale => 1f;

	protected abstract void OnBlockMove(Vector2 dir);

	protected abstract void DefineAbilities();

	protected void AddAbility(string name, float cooldown, Action<Vector2> use, Func<bool> canUse = null, bool inStoppedTime = false)
	{
		abilities.Add(new Ability
		{
			Name = name,
			Cooldown = cooldown,
			Use = use,
			CanUse = canUse,
			InStoppedTime = inStoppedTime
		});
	}

	protected virtual void OnFx(int fx, Vector2 dir, Vector2 at)
	{
	}

	protected virtual void WhileBarraging(Vector2 dir)
	{
	}

	public string AbilityName(int i)
	{
		return abilities[i].Name;
	}

	public float CooldownLeft(int i)
	{
		return Mathf.Max(0f, abilities[i].ReadyAt - Time.time);
	}

	public float CooldownFraction(int i)
	{
		return Mathf.Clamp01(CooldownLeft(i) / Mathf.Max(0.01f, abilities[i].Duration));
	}

	protected virtual void Awake()
	{
		player = ((Component)this).GetComponent<Player>();
		graceUntil = Time.time + 2f;
		nextMenacing = Time.time + Random.Range(2f, 5f);
		DefineAbilities();
	}

	protected virtual void Start()
	{
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player != (Object)null && (Object)(object)player.data.block != (Object)null)
		{
			Block block = player.data.block;
			block.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(block.BlockAction, new Action<BlockTriggerType>(OnBlock));
		}
		if ((Object)(object)player != (Object)null && HolstersGun)
		{
			GunHolster.Holster(player);
		}
		if (IsLocal)
		{
			StandHud.ShowHint(this);
		}
		if ((Object)(object)player != (Object)null)
		{
			MenacingFx.Burst(((Component)player).transform.position, 3);
		}
	}

	protected virtual void OnDestroy()
	{
		if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.block != (Object)null)
		{
			Block block = player.data.block;
			block.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(block.BlockAction, new Action<BlockTriggerType>(OnBlock));
		}
		foreach (FistFx fist in fists)
		{
			if ((Object)(object)fist.sr != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)fist.sr).gameObject);
			}
		}
		fists.Clear();
		if ((Object)(object)root != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)root).gameObject);
		}
	}

	public static bool HasCard(Player p, string title)
	{
		List<CardInfo> list = (((Object)(object)p != (Object)null) ? p.data.currentCards : null);
		if (list == null)
		{
			return false;
		}
		foreach (CardInfo item in list)
		{
			if ((Object)(object)item != (Object)null && item.cardName == title)
			{
				return true;
			}
		}
		return false;
	}

	private void OnBlock(BlockTriggerType trigger)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		if ((int)trigger == 0 && !((Object)(object)player == (Object)null) && !player.data.dead && IsLocal && !(Time.time < nextBlockMove) && !StandSilence.IsSilenced(player))
		{
			nextBlockMove = Time.time + BlockMoveCooldown * StandStats.CooldownMult(player);
			OnBlockMove(AimDir());
		}
	}

	protected virtual void Update()
	{
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null)
		{
			Object.Destroy((Object)(object)this);
			return;
		}
		if (Time.time >= nextCheck)
		{
			nextCheck = Time.time + 0.5f;
			if (!keepWithoutCard && Time.time >= graceUntil && !HasCard(player, CardTitle))
			{
				Debug.Log("[JoJo] " + CardTitle + " card gone, removing the Stand");
				Object.Destroy((Object)(object)this);
				return;
			}
			standIndex = Array.IndexOf(((Component)player).GetComponents<Stand>(), this);
		}
		if (!IsLocal || player.data.dead)
		{
			return;
		}
		bool flag = TimeStop.IsFrozen(player);
		bool flag2 = flag || player.data.isStunned;
		for (int i = 0; i < AbilityCount; i++)
		{
			Ability ability = abilities[i];
			if (SlotPressed(i) && (!flag2 || (flag && ability.InStoppedTime)))
			{
				if (StandSilence.IsSilenced(player))
				{
					Tell("Stand disc stolen!");
					continue;
				}
				if (Time.time < ability.ReadyAt)
				{
					Tell(ability.Name + ": " + Mathf.CeilToInt(ability.ReadyAt - Time.time) + "s");
					continue;
				}
				if (ability.CanUse != null && !ability.CanUse())
				{
					Tell(ability.Name + ": no target");
					continue;
				}
				ability.Duration = ability.Cooldown * StandStats.CooldownMult(player);
				ability.ReadyAt = Time.time + ability.Duration;
				ability.Use(AimDir());
			}
		}
	}

	private void Tell(string text)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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 (!(Time.time < nextTell))
		{
			nextTell = Time.time + 0.4f;
			PopText.Spawn(text, Vector2.op_Implicit(Pos + Vector2.up * 2f), new Color(0.8f, 0.8f, 0.85f), 4f, 0.9f, Vector3.up * 0.5f);
		}
	}

	private bool SlotPressed(int slot)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		PlayerActions playerActions = player.data.playerActions;
		if (playerActions != null && ((PlayerActionSet)playerActions).Device != null)
		{
			InputDevice device = ((PlayerActionSet)playerActions).Device;
			return slot switch
			{
				2 => ((OneAxisInputControl)device.DPadRight).WasPressed, 
				1 => ((OneAxisInputControl)device.DPadLeft).WasPressed, 
				0 => ((OneAxisInputControl)device.DPadDown).WasPressed, 
				_ => ((OneAxisInputControl)device.DPadUp).WasPressed, 
			};
		}
		return Input.GetKeyDown(StandConfig.Key(slot));
	}

	private string CooldownText()
	{
		bool flag = false;
		string text = "";
		for (int i = 0; i < AbilityCount; i++)
		{
			float num = CooldownLeft(i);
			if (i > 0)
			{
				text += "  ";
			}
			if (num > 0f)
			{
				flag = true;
				text = text + "<color=#8a86a0>" + StandConfig.KeyLabel(i) + " " + Mathf.CeilToInt(num) + "</color>";
			}
			else
			{
				text += StandConfig.KeyLabel(i);
			}
		}
		if (!flag)
		{
			return null;
		}
		return text;
	}

	protected Vector2 AimDir()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0079: Unknown result type (might be due to invalid IL or missing references)
		Vector2 val = Vector2.op_Implicit(player.data.aimDirection);
		if (IsLocal && (Object)(object)player.data.input != (Object)null)
		{
			Vector2 val2 = Vector2.op_Implicit(player.data.input.aimDirection);
			if (((Vector2)(ref val2)).sqrMagnitude > 0.01f)
			{
				val = Vector2.op_Implicit(player.data.input.aimDirection);
			}
		}
		if (((Vector2)(ref val)).sqrMagnitude < 0.01f)
		{
			val = Vector2.right;
		}
		return ((Vector2)(ref val)).normalized;
	}

	protected float Reach(float r)
	{
		return r * SizeScale * StandStats.RangeMult(player);
	}

	protected IEnumerable<Player> Enemies()
	{
		foreach (Player player in PlayerManager.instance.players)
		{
			if ((Object)(object)player != (Object)(object)this.player && player.teamID != this.player.teamID && !player.data.dead)
			{
				yield return player;
			}
		}
	}

	protected IEnumerable<Player> Allies(bool includeSelf)
	{
		foreach (Player player in PlayerManager.instance.players)
		{
			if (player.teamID == this.player.teamID && !player.data.dead && (includeSelf || (Object)(object)player != (Object)(object)this.player))
			{
				yield return player;
			}
		}
	}

	protected bool InArc(Vector2 dir, Player p, float reach, float arcDegrees)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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)
		Vector2 val = Vector2.op_Implicit(((Component)p).transform.position) - Vector2.op_Implicit(((Component)player).transform.position);
		float num = Reach(reach) + ((Component)p).transform.localScale.x * 0.4f;
		if (((Vector2)(ref val)).magnitude > num)
		{
			return false;
		}
		if (((Vector2)(ref val)).magnitude < 0.8f)
		{
			return true;
		}
		return Vector2.Angle(dir, val) <= arcDegrees;
	}

	protected Player NearestEnemy(float range)
	{
		//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_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)
		Player result = null;
		float num = range * StandStats.RangeMult(player);
		foreach (Player item in Enemies())
		{
			float num2 = Vector2.Distance(Vector2.op_Implicit(((Component)item).transform.position), Vector2.op_Implicit(((Component)player).transform.position));
			if (num2 < num)
			{
				num = num2;
				result = item;
			}
		}
		return result;
	}

	protected void Hit(Player target, Vector2 dir, float damage)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		((Damagable)target.data.healthHandler).CallTakeDamage(dir * StandStats.Damage(player, damage), Vector2.op_Implicit(((Component)target).transform.position), (GameObject)null, player, true);
	}

	protected void Barrage(Vector2 dir, float hitDamage, float finisherDamage, float reach, float arc, Action<Player, bool> onHit = null, float healAllies = 0f)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		StandNet.SendFx(player, 0, dir, Vector2.zero);
		((MonoBehaviour)this).StartCoroutine(BarrageRoutine(dir, hitDamage, finisherDamage, reach, arc, onHit, healAllies));
	}

	private IEnumerator BarrageRoutine(Vector2 dir, float hitDamage, float finisherDamage, float reach, float arc, Action<Player, bool> onHit, float healAllies)
	{
		//IL_000e: 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)
		float start = Time.time;
		float nextPulse = Time.time + 0.25f;
		int left = BarrageHits;
		while (left > 0)
		{
			yield return (object)new WaitForSeconds(HitInterval);
			if ((Object)(object)player == (Object)null || player.data.dead)
			{
				break;
			}
			if (Time.time >= nextPulse && Time.time - start < BarrageHoldMax && BlockHeld())
			{
				nextPulse = Time.time + 0.25f;
				dir = AimDir();
				left = BarrageHits;
				StandNet.SendFx(player, 0, dir, Vector2.zero);
			}
			int num = left - 1;
			left = num;
			bool flag = num == 0;
			Vector2 val = Vector2.op_Implicit(((Component)player).transform.position) + dir * Reach(reach) * 0.6f;
			foreach (Player item in new List<Player>(Enemies()))
			{
				if (InArc(dir, item, reach, arc))
				{
					Hit(item, dir, flag ? finisherDamage : hitDamage);
					if (flag)
					{
						StandNet.SendPush(item, dir * 28f + Vector2.up * 8f, 0.18f);
					}
					else
					{
						StandNet.SendPush(item, dir * 3f + (val - Vector2.op_Implicit(((Component)item).transform.position)) * 4f, HitInterval + 0.02f);
					}
					onHit?.Invoke(item, flag);
				}
			}
			HitObjects(dir, flag ? finisherDamage : hitDamage, reach, arc);
			if (!(healAllies > 0f))
			{
				continue;
			}
			foreach (Player item2 in new List<Player>(Allies(includeSelf: false)))
			{
				if (InArc(dir, item2, reach, arc))
				{
					StandNet.SendHeal(item2, healAllies);
				}
			}
		}
	}

	public void Jab()
	{
		if ((Object)(object)player == (Object)null || player.data.dead || player.data.isStunned || player.data.isSilenced || Time.time < nextJab)
		{
			return;
		}
		if (StandSilence.IsSilenced(player))
		{
			Tell("Stand disc stolen!");
			return;
		}
		Gun val = (((Object)(object)player.data.weaponHandler != (Object)null) ? player.data.weaponHandler.gun : null);
		float num = 1f;
		float reach = 3f;
		float push = 14f;
		float slow = 0f;
		int times = 1;
		if ((Object)(object)val != (Object)null)
		{
			num = Mathf.Clamp(val.attackSpeed / Mathf.Max(0.01f, val.attackSpeedMultiplier) / 0.3f, 0.4f, 3f);
			times = Mathf.Clamp(Mathf.Max(1, val.numberOfProjectiles) * Mathf.Max(1, val.bursts), 1, 6);
			reach *= Mathf.Clamp(Mathf.Sqrt(Mathf.Max(0.01f, val.projectileSpeed)), 0.8f, 1.6f);
			push *= Mathf.Clamp(val.knockback, 0.3f, 3f);
			slow = val.slow;
		}
		nextJab = Time.time + 0.35f * num * StandStats.CooldownMult(player);
		int n = 0;
		Repeat(times, 0.06f, delegate
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			JabHit(AimDir(), (n++ == 0) ? JabDamage : (JabDamage * 0.5f), reach, push, slow);
		});
	}

	private void JabHit(Vector2 dir, float damage, float reach, float push, float slow)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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_0065: 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)
		StandNet.SendFx(player, -1, dir, Vector2.zero);
		foreach (Player item in new List<Player>(Enemies()))
		{
			if (InArc(dir, item, reach, 50f))
			{
				Hit(item, dir, damage);
				StandNet.SendPush(item, dir * push + Vector2.up * push * 0.3f, 0.12f);
				if (slow > 0f)
				{
					StandNet.SendSlow(item, slow);
				}
			}
		}
		HitObjects(dir, damage, reach, 50f);
	}

	private bool BlockHeld()
	{
		if (player.data.isStunned || StandSilence.IsSilenced(player))
		{
			return false;
		}
		PlayerActions playerActions = player.data.playerActions;
		if (playerActions != null && playerActions.Block != null)
		{
			return ((OneAxisInputControl)playerActions.Block).IsPressed;
		}
		return false;
	}

	protected static float Deg(Vector2 d)
	{
		//IL_0000: 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)
		return Mathf.Atan2(d.y, d.x) * 57.29578f;
	}

	protected void Volley(ProjectileKind kind, Vector2 dir, float spread, int count)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: 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_0028: Unknown result type (might be due to invalid IL or missing references)
		StandNet.SendVolley(player, kind, Pos + dir * 0.8f * SizeScale, Deg(dir), spread, count);
	}

	protected void Repeat(int times, float interval, Action action)
	{
		((MonoBehaviour)this).StartCoroutine(RepeatRoutine(times, interval, action));
	}

	private IEnumerator RepeatRoutine(int times, float interval, Action action)
	{
		for (int i = 0; i < times; i++)
		{
			if (i > 0)
			{
				yield return (object)new WaitForSeconds(interval);
			}
			if ((Object)(object)player == (Object)null || player.data.dead)
			{
				break;
			}
			action();
		}
	}

	protected void Lunge(Vector2 dir)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		StandNet.SendFx(player, 2, dir, Pos);
	}

	protected void Shout(string text)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		Shout(text, Pos + Vector2.up * 2.5f);
	}

	protected void Shout(string text, Vector2 at)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		StandNet.SendShout(at, text, Color.Lerp(Look.Glow, Color.white, 0.25f), 7f);
	}

	protected void Ring(Vector2 at, float from, float to, float life, bool filled = false)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		Color glow = Look.Glow;
		glow.a = 0.85f;
		StandNet.SendRing(at, glow, from, to, life, filled);
	}

	protected void Line(Vector2 from, Vector2 to, float thickness = 0.35f)
	{
		//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_0009: Unknown result type (might be due to invalid IL or missing references)
		StandNet.SendLine(from, to, 0, Look.Glow, thickness, 0.5f);
	}

	protected void Resist(float multiplier, float seconds)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		StandNet.SendResist(player, multiplier, seconds, Look.Glow);
	}

	protected List<Player> EnemiesWithin(float range)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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)
		List<Player> list = new List<Player>();
		foreach (Player item in Enemies())
		{
			if (Vector2.Distance(Vector2.op_Implicit(((Component)item).transform.position), Pos) <= Reach(range) + ((Component)item).transform.localScale.x * 0.4f)
			{
				list.Add(item);
			}
		}
		return list;
	}

	protected Func<bool> EnemyWithin(float range)
	{
		return () => (Object)(object)NearestEnemy(range) != (Object)null;
	}

	protected void HealAround(float range, float amount)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		foreach (Player item in new List<Player>(Allies(includeSelf: true)))
		{
			if (Vector2.Distance(Vector2.op_Implicit(((Component)item).transform.position), Pos) <= range)
			{
				StandNet.SendHeal(item, amount);
			}
		}
	}

	protected void Teleport(Vector2 to, int lineSprite = 0)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be du