JARL.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using ClassesManagerReborn;
using ClassesManagerReborn.Util;
using HarmonyLib;
using JARL;
using JARL.Armor;
using JARL.Armor.Bases;
using JARL.Armor.Bases.Builtin;
using JARL.Armor.Builtin;
using JARL.Armor.Utlis;
using JARL.Bases;
using JARL.Extensions;
using JARL.Utils;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using ModdingUtils.Extensions;
using ModdingUtils.Utils;
using ModsPlus;
using Photon.Pun;
using TMPro;
using TabInfo.Utils;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnboundLib.Utils.UI;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.aalund13.rounds.jarl", "Just Another Rounds Library", "2.1.1")]
[BepInProcess("Rounds.exe")]
public class JustAnotherRoundsLibrary : BaseUnityPlugin
{
	internal const string ModInitials = "JARL";

	internal const string ModId = "com.aalund13.rounds.jarl";

	internal const string ModName = "Just Another Rounds Library";

	internal const string Version = "2.1.1";

	internal static List<BaseUnityPlugin> plugins;

	internal static AssetBundle assets = AssetUtils.LoadAssetBundleFromResources("jarl_assets", typeof(JustAnotherRoundsLibrary).Assembly);

	private void Awake()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		assets.LoadAsset<GameObject>("ModCards").GetComponent<CardResgester>().RegisterCards();
		new Harmony("com.aalund13.rounds.jarl").PatchAll();
		ClassesRegistry.Register(CardResgester.ModCards["Armor Piercing"].GetComponent<CardInfo>(), (CardType)32, 4);
	}

	private void Start()
	{
		ConfigHandler.RegesterMenu(((BaseUnityPlugin)this).Config);
		plugins = (List<BaseUnityPlugin>)typeof(Chainloader).GetField("_plugins", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
		GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler _) => GameStart()));
		if (plugins.Exists((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == "com.willuwontu.rounds.tabinfo"))
		{
			TabinfoInterface.SetUpTabinfoInterface();
		}
		ArmorFramework.RegisterArmorType(new DefaultArmor());
		ArmorHandler.DamageProcessingMethodsAfter += ArmorPiercePercent.ApplyArmorPiercePercent;
	}

	private void Update()
	{
		ArmorFramework.ResetEveryPlayerArmorStats(skipArmorHandlerChecking: false);
	}

	private IEnumerator GameStart()
	{
		ArmorFramework.ResetEveryPlayerArmorStats();
		yield break;
	}
}
namespace JARL
{
	internal class CardResgester : MonoBehaviour
	{
		public List<GameObject> Cards;

		public List<GameObject> HiddenCards;

		internal static Dictionary<string, GameObject> ModCards = new Dictionary<string, GameObject>();

		internal void RegisterCards()
		{
			foreach (GameObject card in Cards)
			{
				CustomCard.RegisterUnityCard(card, "JARL", card.GetComponent<CardInfo>().cardName, true, (Action<CardInfo>)null);
				ModCards.Add(card.GetComponent<CardInfo>().cardName, card);
			}
			foreach (GameObject hiddenCard in HiddenCards)
			{
				CustomCard.RegisterUnityCard(hiddenCard, "JARL", hiddenCard.GetComponent<CardInfo>().cardName, false, (Action<CardInfo>)null);
				Cards.instance.AddHiddenCard(hiddenCard.GetComponent<CardInfo>());
				ModCards.Add(hiddenCard.GetComponent<CardInfo>().cardName, hiddenCard);
			}
		}

		internal static List<GameObject> GetCardsFormString(List<string> cardsOfString)
		{
			List<GameObject> list = new List<GameObject>();
			foreach (string item in cardsOfString)
			{
				list.Add(ModCards[item]);
			}
			return list;
		}
	}
	public class ArmorPierceCard : CustomCardUnity
	{
		[Header("Stats: Armor Pierce Percent")]
		public float ArmorPiercePercent;

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			player.data.GetAdditionalData().ArmorPiercePercent = Mathf.Clamp(player.data.GetAdditionalData().ArmorPiercePercent + ArmorPiercePercent, 0f, 1f);
		}

		public override string GetModName()
		{
			return "JARL";
		}
	}
	internal class ConfigHandler
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__2_0;

			internal void <RegesterMenu>b__2_0()
			{
			}
		}

		public static ConfigEntry<bool> DetailsMode;

		public static ConfigEntry<bool> DebugMode;

		public static void RegesterMenu(ConfigFile config)
		{
			//IL_0019: 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_0024: Expected O, but got Unknown
			object obj = <>c.<>9__2_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
				};
				<>c.<>9__2_0 = val;
				obj = (object)val;
			}
			Unbound.RegisterMenu("Just Another Rounds Library", (UnityAction)obj, (Action<GameObject>)NewGui, (GameObject)null, false);
			DetailsMode = config.Bind<bool>("Just Another Rounds Library", "DetailsMode", false, "Enabled or disabled DetailsMode.");
			DebugMode = config.Bind<bool>("Just Another Rounds Library", "DebugMode", false, "Enabled or disabled Debug Mode");
		}

		public static void addBlank(GameObject menu)
		{
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		public static void NewGui(GameObject menu)
		{
			TextMeshProUGUI val2 = default(TextMeshProUGUI);
			MenuHandler.CreateText("Details Mode | Show extracts details about every armor.", menu, ref val2, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			MenuHandler.CreateToggle(DetailsMode.Value, "Details Mode", menu, (UnityAction<bool>)DetailsModeChanged, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			addBlank(menu);
			MenuHandler.CreateToggle(DebugMode.Value, "<#c41010> Debug Mode", menu, (UnityAction<bool>)DebugModeChanged, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			static void DebugModeChanged(bool val)
			{
				DebugMode.Value = val;
			}
			static void DetailsModeChanged(bool val)
			{
				DetailsMode.Value = val;
			}
		}
	}
	internal class TabinfoInterface
	{
		public static object ArmorsStatsCategory;

		public static void SetUpTabinfoInterface()
		{
			StatCategory obj = TabInfoManager.RegisterCategory("JARL Stats", 0);
			ExtensionMethods.SetFieldValue((object)obj, "priority", (object)(-45));
			ArmorsStatsCategory = TabInfoManager.RegisterCategory("Armor Stats", 0);
			ExtensionMethods.SetFieldValue(ArmorsStatsCategory, "priority", (object)(-44));
			TabInfoManager.RegisterStat(obj, "Total Armor", (Func<Player, bool>)((Player p) => p.data.GetAdditionalData().totalMaxArmor > 0f), (Func<Player, string>)((Player p) => $"{p.data.GetAdditionalData().totalArmor:0.0}/{p.data.GetAdditionalData().totalMaxArmor:0.0}"));
			TabInfoManager.RegisterStat(obj, "Armor Pierce", (Func<Player, bool>)((Player p) => p.data.GetAdditionalData().ArmorPiercePercent > 0f), (Func<Player, string>)((Player p) => $"{p.data.GetAdditionalData().ArmorPiercePercent * 100f:0}%"));
		}

		public static void RegisterArmorTabinfoInterface(ArmorBase registerArmor)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			if (JustAnotherRoundsLibrary.plugins.Exists((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == "com.willuwontu.rounds.tabinfo"))
			{
				Type armorType = registerArmor.GetType();
				TabInfoManager.RegisterStat((StatCategory)ArmorsStatsCategory, $"{registerArmor} Armor", (Func<Player, bool>)((Player p) => ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).MaxArmorValue > 0f), (Func<Player, string>)delegate(Player p)
				{
					ArmorBase armorByType = ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType);
					return (armorByType.CurrentArmorValue <= 0f && !Utility.IsNullOrWhiteSpace(armorByType.DeactivateText)) ? armorByType.DeactivateText : $"{armorByType.CurrentArmorValue:0.0}/{armorByType.MaxArmorValue:0.0}";
				});
				StatCategory obj = TabInfoManager.RegisterCategory($"{registerArmor} Armor Stats", 127);
				TabInfoManager.RegisterStat(obj, $"{registerArmor} Armor Health", (Func<Player, bool>)((Player p) => ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).MaxArmorValue > 0f && ConfigHandler.DetailsMode.Value), (Func<Player, string>)((Player p) => $"{ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).CurrentArmorValue:0.0}/{ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).MaxArmorValue:0.0}"));
				TabInfoManager.RegisterStat(obj, $"{registerArmor} Armor Regeneration Rate", (Func<Player, bool>)((Player p) => ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).MaxArmorValue > 0f && ConfigHandler.DetailsMode.Value), (Func<Player, string>)((Player p) => $"{ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).ArmorRegenerationRate:0.00}"));
				TabInfoManager.RegisterStat(obj, $"{registerArmor} Armor Regen Cooldown ", (Func<Player, bool>)((Player p) => ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).MaxArmorValue > 0f && ConfigHandler.DetailsMode.Value), (Func<Player, string>)((Player p) => $"{ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).ArmorRegenCooldownSeconds:0.00}s"));
				TabInfoManager.RegisterStat(obj, $"{registerArmor} Armor Reactivate Armor Type", (Func<Player, bool>)((Player p) => ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).MaxArmorValue > 0f && ConfigHandler.DetailsMode.Value), (Func<Player, string>)((Player p) => $"{ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).reactivateArmorType}"));
				TabInfoManager.RegisterStat(obj, $"{registerArmor} Armor Reactivate Armor Value", (Func<Player, bool>)((Player p) => ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).MaxArmorValue > 0f && ConfigHandler.DetailsMode.Value), (Func<Player, string>)((Player p) => $"{ArmorFramework.ArmorHandlers[p].GetArmorByType(armorType).reactivateArmorValue}"));
			}
		}
	}
}
namespace JARL.Utils
{
	public struct DamageInfo
	{
		public float DamageAmount;

		public float TimeSinceLastDamage;

		public DamageInfo(float damageAmount, float timeSinceLastDamage)
		{
			DamageAmount = damageAmount;
			TimeSinceLastDamage = timeSinceLastDamage;
		}
	}
	public delegate void DeathHandlerDelegate(Player player, Dictionary<Player, DamageInfo> playerDamageInfo);
	public delegate void DeathHandlerDelegateHost(Player player, Dictionary<Player, DamageInfo> playerDamageInfo);
	public static class DeathHandler
	{
		private static readonly Dictionary<Player, Dictionary<Player, DamageInfo>> damageTrackings = new Dictionary<Player, Dictionary<Player, DamageInfo>>();

		public static event DeathHandlerDelegate OnPlayerDeath;

		public static event DeathHandlerDelegateHost OnPlayerDeathHost;

		internal static void PlayerDamaged(Player player, Player damagingPlayer, float damageAmount)
		{
			if (!((Object)(object)damagingPlayer == (Object)null) && !(damageAmount <= 0f))
			{
				if (!damageTrackings.ContainsKey(player))
				{
					damageTrackings.Add(player, new Dictionary<Player, DamageInfo>());
				}
				if (!damageTrackings[player].ContainsKey(damagingPlayer))
				{
					damageTrackings[player].Add(damagingPlayer, new DamageInfo(damageAmount, Time.time));
				}
				else
				{
					damageTrackings[player][damagingPlayer] = new DamageInfo(damageTrackings[player][damagingPlayer].DamageAmount + damageAmount, Time.time);
				}
			}
		}

		internal static void PlayerDeath(Player player)
		{
			if (!damageTrackings.ContainsKey(player))
			{
				damageTrackings.Add(player, new Dictionary<Player, DamageInfo>());
			}
			if (PhotonNetwork.IsMasterClient || PhotonNetwork.OfflineMode)
			{
				DeathHandler.OnPlayerDeathHost?.Invoke(player, GetPlayerDamage(player));
				int[] array = damageTrackings[player].Keys.Select((Player p) => p.playerID).ToArray();
				float[] array2 = damageTrackings[player].Values.Select((DamageInfo d) => Time.time - d.TimeSinceLastDamage).ToArray();
				float[] array3 = damageTrackings[player].Values.Select((DamageInfo d) => d.DamageAmount).ToArray();
				NetworkingManager.RPC(typeof(DeathHandler), "RPCA_PlayerDeath", new object[4] { player.playerID, array, array2, array3 });
				damageTrackings.Remove(player);
			}
		}

		[UnboundRPC]
		private static void RPCA_PlayerDeath(int playerID, int[] playerIDs, float[] timeSinceLastDamage, float[] damageAmounts)
		{
			Dictionary<Player, DamageInfo> dictionary = new Dictionary<Player, DamageInfo>();
			int i;
			for (i = 0; i < playerIDs.Length; i++)
			{
				dictionary.Add(PlayerManager.instance.players.Find((Player p) => p.playerID == playerIDs[i]), new DamageInfo(damageAmounts[i], timeSinceLastDamage[i]));
			}
			Player player = PlayerManager.instance.players.Find((Player p) => p.playerID == playerID);
			DeathHandler.OnPlayerDeath?.Invoke(player, dictionary);
		}

		private static Dictionary<Player, DamageInfo> GetPlayerDamage(Player player)
		{
			if (damageTrackings.ContainsKey(player))
			{
				return damageTrackings[player].Select((KeyValuePair<Player, DamageInfo> pair) => new KeyValuePair<Player, DamageInfo>(pair.Key, new DamageInfo(pair.Value.DamageAmount, Time.time - pair.Value.TimeSinceLastDamage))).ToDictionary((KeyValuePair<Player, DamageInfo> pair) => pair.Key, (KeyValuePair<Player, DamageInfo> pair) => pair.Value);
			}
			return new Dictionary<Player, DamageInfo>();
		}
	}
	internal static class LoggingUtils
	{
		public static void LogInfo(string message)
		{
			if (ConfigHandler.DebugMode.Value)
			{
				Debug.Log((object)message);
			}
		}

		public static void LogWarn(string message)
		{
			if (ConfigHandler.DebugMode.Value)
			{
				Debug.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			if (ConfigHandler.DebugMode.Value)
			{
				Debug.LogError((object)message);
			}
		}
	}
}
namespace JARL.Patches
{
	[HarmonyPatch(typeof(CharacterStatModifiers))]
	public class CharacterStatModifiersPatch
	{
		[HarmonyPatch("ResetStats")]
		[HarmonyPrefix]
		public static void ResetStats(CharacterStatModifiers __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			CharacterDataExtensions.GetAdditionalData((CharacterData)Traverse.Create((object)__instance).Field("data").GetValue()).ArmorPiercePercent = 0f;
			ArmorFramework.ResetEveryPlayerArmorStats();
		}
	}
	[HarmonyPatch(typeof(DamageOverTime))]
	public class DamageOverTimePatch
	{
		[HarmonyPatch("TakeDamageOverTime")]
		[HarmonyPrefix]
		private static void TakeDamageOverTimePrefix(DamageOverTime __instance, ref Vector2 damage, Player damagingPlayer)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			CharacterData val = (CharacterData)Traverse.Create((object)__instance).Field("data").GetValue();
			if (val.GetAdditionalData().totalArmor > 0f)
			{
				((Component)val.player).GetComponent<ArmorHandler>().ProcessDamage(ref damage, damagingPlayer, val.player, ArmorDamagePatchType.TakeDamageOverTime);
			}
		}
	}
	[HarmonyPatch(typeof(HealthHandler))]
	public class HealthHandlerPatch
	{
		[HarmonyPatch("TakeDamage", new Type[]
		{
			typeof(Vector2),
			typeof(Vector2),
			typeof(Color),
			typeof(GameObject),
			typeof(Player),
			typeof(bool),
			typeof(bool)
		})]
		[HarmonyPrefix]
		private static void TakeDamage(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			CharacterData val = (CharacterData)Traverse.Create((object)__instance).Field("data").GetValue();
			if (val.GetAdditionalData().totalArmor > 0f)
			{
				((Component)val.player).GetComponent<ArmorHandler>().ProcessDamage(ref damage, damagingPlayer, val.player, ArmorDamagePatchType.TakeDamage);
			}
		}

		[HarmonyPatch("DoDamage")]
		[HarmonyPrefix]
		public static void DoDamage(HealthHandler __instance, ref Vector2 damage, Vector2 position, Color blinkColor, GameObject damagingWeapon, Player damagingPlayer, bool healthRemoval, bool lethal, bool ignoreBlock)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			CharacterData val = (CharacterData)Traverse.Create((object)__instance).Field("data").GetValue();
			if (val.GetAdditionalData().totalArmor > 0f)
			{
				((Component)val.player).GetComponent<ArmorHandler>().ProcessDamage(ref damage, damagingPlayer, val.player, ArmorDamagePatchType.DoDamage);
			}
			DeathHandler.PlayerDamaged(val.player, damagingPlayer, ((Vector2)(ref damage)).magnitude);
		}

		[HarmonyPatch("Revive")]
		[HarmonyPostfix]
		public static void Revive(CharacterData ___data)
		{
			if (Object.op_Implicit((Object)(object)((Component)___data).GetComponent<ArmorHandler>()))
			{
				((Component)___data).GetComponent<ArmorHandler>().OnRespawn();
			}
		}

		[HarmonyPatch("RPCA_Die")]
		[HarmonyPrefix]
		public static void RPCA_Die(Player ___player)
		{
			if (!___player.data.dead)
			{
				DeathHandler.PlayerDeath(___player);
			}
		}

		[HarmonyPatch("RPCA_Die_Phoenix")]
		[HarmonyPrefix]
		public static void RPCA_Die_Phoenix(Player ___player)
		{
			if (!___player.data.dead)
			{
				DeathHandler.PlayerDeath(___player);
			}
		}
	}
}
namespace JARL.Extensions
{
	public class JARLCharacterDataAdditionalData
	{
		public float totalArmor;

		public float totalMaxArmor;

		public float ArmorPiercePercent;

		public JARLCharacterDataAdditionalData()
		{
			totalArmor = 0f;
			totalMaxArmor = 0f;
			ArmorPiercePercent = 0f;
		}
	}
	public static class CharacterDataExtensions
	{
		public static readonly ConditionalWeakTable<CharacterData, JARLCharacterDataAdditionalData> data = new ConditionalWeakTable<CharacterData, JARLCharacterDataAdditionalData>();

		public static JARLCharacterDataAdditionalData GetAdditionalData(this CharacterData block)
		{
			return data.GetOrCreateValue(block);
		}

		public static void AddData(this CharacterData block, JARLCharacterDataAdditionalData value)
		{
			try
			{
				data.Add(block, value);
			}
			catch (Exception)
			{
			}
		}
	}
}
namespace JARL.Cards
{
	public class DefaultArmorCard : CustomCardUnity
	{
		[Header("Armor: Max Armor Amd Regen")]
		public float MaxArmorValue;

		public float RegenerationRate;

		public float RegenCooldownSeconds;

		[Header("Armor: Armor Reactivate")]
		public ArmorReactivateType ArmorReactivateType;

		public float ReactivateArmorValue;

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			ArmorFramework.ArmorHandlers[player].AddArmor(typeof(DefaultArmor), MaxArmorValue, RegenerationRate, RegenCooldownSeconds, ArmorReactivateType, ReactivateArmorValue);
		}

		public override string GetModName()
		{
			return "JARL";
		}
	}
}
namespace JARL.Bases
{
	public abstract class CustomCardUnity : CustomCard
	{
		private class SetLocalPos : MonoBehaviour
		{
			private readonly Vector3 localpos = new Vector3(-50f, -50f, 0f);

			private void Update()
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				if (!(((Component)this).gameObject.transform.localPosition == localpos))
				{
					((Component)this).gameObject.transform.localPosition = localpos;
					Object.Destroy((Object)(object)this, 1f);
				}
			}
		}

		[Header("Class Value")]
		public bool AutomatedlyCreateClass = true;

		public string OverrideClassName = "";

		[Header("Card Info")]
		public bool CanBeReassigned = true;

		public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
		{
			CardInfoExtension.GetAdditionalData(cardInfo).canBeReassigned = CanBeReassigned;
		}

		private void Start()
		{
			CreateModText();
			CreateClassText();
		}

		protected override GameObject GetCardArt()
		{
			return base.cardInfo.cardArt;
		}

		protected override string GetDescription()
		{
			return base.cardInfo.cardDestription;
		}

		protected override Rarity GetRarity()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return base.cardInfo.rarity;
		}

		protected override CardInfoStat[] GetStats()
		{
			return base.cardInfo.cardStats;
		}

		protected override CardThemeColorType GetTheme()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return base.cardInfo.colorTheme;
		}

		protected override string GetTitle()
		{
			return base.cardInfo.cardName;
		}

		private void CreateModText()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0094: 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)
			GameObject val = new GameObject("ModNameText");
			RectTransform val2 = ((IEnumerable<RectTransform>)((Component)this).gameObject.GetComponentsInChildren<RectTransform>()).FirstOrDefault((Func<RectTransform, bool>)((RectTransform obj) => ((Object)((Component)obj).gameObject).name == "EdgePart (2)"));
			if ((Object)(object)val2 != (Object)null)
			{
				GameObject gameObject = ((Component)val2).gameObject;
				val.gameObject.transform.SetParent(gameObject.transform);
			}
			TextMeshProUGUI val3 = val.gameObject.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val3).text = ExtensionMethods.Sanitize(((CustomCard)this).GetModName(), (string[])null);
			val.transform.localEulerAngles = new Vector3(0f, 0f, 135f);
			val.transform.localScale = Vector3.one;
			val.AddComponent<SetLocalPos>();
			((TMP_Text)val3).alignment = (TextAlignmentOptions)1026;
			((TMP_Text)val3).alpha = 0.1f;
			((TMP_Text)val3).fontSize = 54f;
		}

		private void CreateClassText()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			if (AutomatedlyCreateClass)
			{
				ClassesRegistry.GetClassInfos((CardType)2, false).ToList();
				ClassObject val = ClassesRegistry.Get(base.cardInfo.sourceCard);
				if (val != null && (int)val.type != 32)
				{
					val.RequiredClassesTree.FirstOrDefault()?.FirstOrDefault();
					string className = GetClassName(val);
					((Component)this).gameObject.AddComponent<ClassNameMono>().className = className;
				}
			}
		}

		private string GetClassName(ClassObject classObject)
		{
			CardInfo val = classObject.RequiredClassesTree.FirstOrDefault()?.FirstOrDefault();
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<CustomCardUnity>() != (Object)null)
			{
				if (!Utility.IsNullOrWhiteSpace(((Component)val).GetComponent<CustomCardUnity>().OverrideClassName))
				{
					return ((Component)val).GetComponent<CustomCardUnity>().OverrideClassName;
				}
				return val.cardName;
			}
			if ((Object)(object)val != (Object)null)
			{
				return val.cardName;
			}
			return "Class";
		}

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
		}
	}
}
namespace JARL.Armor
{
	[Flags]
	public enum ArmorDamagePatchType
	{
		DoDamage = 1,
		TakeDamage = 2,
		TakeDamageOverTime = 4
	}
	public enum ArmorReactivateType
	{
		Percent,
		Second
	}
	public struct DamageArmorInfo
	{
		public float Damage;

		public float Armor;

		public DamageArmorInfo(float damage, float armor)
		{
			Damage = damage;
			Armor = armor;
		}
	}
	public struct ArmorProcessingResult
	{
		public float Damage;

		public float Armor;

		public bool SkipArmorDamageProcess;

		public ArmorProcessingResult(float damage, float armor, bool skipArmorDamageProcess)
		{
			Damage = damage;
			Armor = armor;
			SkipArmorDamageProcess = skipArmorDamageProcess;
		}
	}
	public struct BarColor
	{
		public Color ActivedBarColor;

		public Color DeactivatedBarColor;

		public BarColor(Color activedBarColor, Color deactivatedBarColor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			ActivedBarColor = activedBarColor;
			DeactivatedBarColor = deactivatedBarColor;
		}
	}
	public class ArmorFramework
	{
		public static readonly List<ArmorBase> RegisteredArmorTypes = new List<ArmorBase>();

		public static readonly Dictionary<Player, ArmorHandler> ArmorHandlers = new Dictionary<Player, ArmorHandler>();

		public static void RegisterArmorType(ArmorBase armorType)
		{
			LoggingUtils.LogInfo("Registering ArmorType: '" + armorType.GetType().Name + "'");
			if (RegisteredArmorTypes.Contains(armorType))
			{
				LoggingUtils.LogWarn("ArmorType '" + armorType.GetType().Name + "' already exists");
				return;
			}
			int num = ((RegisteredArmorTypes.Count > 0) ? RegisteredArmorTypes.Max((ArmorBase a) => a.Priority) : 0);
			armorType.Priority = num + 1;
			RegisteredArmorTypes.Add(armorType);
			RegisterArmorTabinfoInterface(armorType);
			LoggingUtils.LogInfo("Successfully registered ArmorType: '" + armorType.GetType().Name + "'");
		}

		public static void ResetEveryPlayerArmorStats(bool skipArmorHandlerChecking = true)
		{
			for (int i = 0; i < PlayerManager.instance.players.Count; i++)
			{
				Player val = PlayerManager.instance.players[i];
				if (skipArmorHandlerChecking || (Object)(object)((Component)val).GetComponent<ArmorHandler>() == (Object)null)
				{
					LoggingUtils.LogInfo($"Reseting player id '{val.playerID}' armor stats");
					ExtensionMethods.GetOrAddComponent<ArmorHandler>(((Component)val).gameObject, false).ResetArmorStats();
				}
			}
		}

		internal static void RegisterArmorTabinfoInterface(ArmorBase armor)
		{
			if (JustAnotherRoundsLibrary.plugins.Exists((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == "com.willuwontu.rounds.tabinfo"))
			{
				TabinfoInterface.RegisterArmorTabinfoInterface(armor);
			}
		}
	}
	public delegate DamageArmorInfo ProcessDamageDelegate(ArmorBase armor, Player damagingPlayer, Player hurtPlayer, float remainingDamage, float originalDamage);
	public delegate ArmorProcessingResult ProcessDamageBeforeDelegate(ArmorBase armor, Player damagingPlayer, Player hurtPlayer, float remainingDamage, float originalDamage);
	public class ArmorHandler : MonoBehaviour
	{
		private readonly Dictionary<ArmorBase, GameObject> armorHealthBars = new Dictionary<ArmorBase, GameObject>();

		private int activeArmorsCount;

		public List<ArmorBase> Armors { get; private set; } = new List<ArmorBase>();


		public List<ArmorBase> ActiveArmors => Armors.FindAll((ArmorBase armor) => armor.MaxArmorValue > 0f);

		public Player Player { get; internal set; }

		public static event ProcessDamageBeforeDelegate DamageProcessingMethodsBefore;

		public static event ProcessDamageDelegate DamageProcessingMethodsAfter;

		public void ResetArmorStats()
		{
			Armors.Clear();
			foreach (ArmorBase registeredArmorType in ArmorFramework.RegisteredArmorTypes)
			{
				LoggingUtils.LogInfo("Resetting stats for ArmorType: " + registeredArmorType.GetType().Name + ".");
				ArmorBase armorBase = (ArmorBase)Activator.CreateInstance(registeredArmorType.GetType());
				armorBase.ArmorHandler = this;
				Armors.Add(armorBase);
			}
			Armors = Armors.OrderByDescending((ArmorBase armor) => armor.Priority).ToList();
		}

		public ArmorBase GetArmorByType(Type type)
		{
			return Armors.Find((ArmorBase armor) => armor.GetType() == type);
		}

		public void AddArmor(Type armorType, float maxArmorValue, float regenerationRate, float regenCooldownSeconds, ArmorReactivateType reactivateArmorType, float reactivateArmorValue)
		{
			if (PhotonNetwork.OfflineMode || PhotonNetwork.IsMasterClient)
			{
				LoggingUtils.LogInfo("Calling method 'RPCA_AddArmor' on all clients");
				Player.data.view.RPC("RPCA_AddArmor", (RpcTarget)0, new object[6] { armorType.AssemblyQualifiedName, maxArmorValue, regenerationRate, regenCooldownSeconds, reactivateArmorType, reactivateArmorValue });
			}
		}

		private void Update()
		{
			float num = 0f;
			float num2 = 0f;
			if (!Player.data.isPlaying)
			{
				return;
			}
			if (ActiveArmors.Count != activeArmorsCount)
			{
				ResetArmorHealthBar();
				activeArmorsCount = ActiveArmors.Count;
			}
			foreach (ArmorBase armor in Armors)
			{
				if (armor.MaxArmorValue > 0f)
				{
					if (armor.IsActive)
					{
						num += armor.CurrentArmorValue;
					}
					num2 += armor.MaxArmorValue;
					Player.data.GetAdditionalData().totalArmor = num;
					Player.data.GetAdditionalData().totalMaxArmor = num2;
					armor.OnUpdate();
					armor.RegenerationArmor();
					TryReactivateArmor(armor);
				}
			}
			UpdateArmorHealthBar();
		}

		private void Awake()
		{
			Player = ((Component)this).GetComponent<Player>();
			if (!ArmorFramework.ArmorHandlers.ContainsKey(Player))
			{
				ArmorFramework.ArmorHandlers.Add(Player, this);
			}
		}

		private void OnDestroy()
		{
			ArmorFramework.ArmorHandlers.Remove(Player);
		}

		internal void ProcessDamage(ref Vector2 damageVector, Player damagingPlayer, Player hurtPlayer, ArmorDamagePatchType armorDamagePatch)
		{
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			LoggingUtils.LogInfo("Proocessing Damage");
			float num = ((Vector2)(ref damageVector)).magnitude;
			foreach (ArmorBase item in Armors.Where((ArmorBase armor) => armor.ArmorDamagePatch.HasFlag(armorDamagePatch)).ToArray().Reverse())
			{
				LoggingUtils.LogInfo("Proocessing damage for '" + item.GetType().Name + "'");
				if (num <= 0f)
				{
					break;
				}
				if (!item.IsActive || item.MaxArmorValue == 0f)
				{
					continue;
				}
				LoggingUtils.LogInfo("Runing all 'DamageProcessingMethodsBefore' method for '" + item.GetType().Name + "'");
				try
				{
					ArmorProcessingResult? armorProcessingResult = ArmorHandler.DamageProcessingMethodsBefore?.Invoke(item, damagingPlayer, hurtPlayer, num, ((Vector2)(ref damageVector)).magnitude);
					if (armorProcessingResult.HasValue)
					{
						num = armorProcessingResult.Value.Damage;
						item.CurrentArmorValue = armorProcessingResult.Value.Armor;
						if (armorProcessingResult.Value.SkipArmorDamageProcess)
						{
							continue;
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)$"An error occurred while executing the '{ex.TargetSite.Name}' event: {ex}");
					break;
				}
				LoggingUtils.LogInfo("Runing 'OnArmorDamage' method for '" + item.GetType().Name + "'");
				try
				{
					DamageArmorInfo damageArmorInfo = item.OnDamage(num, damagingPlayer, armorDamagePatch);
					num = damageArmorInfo.Damage;
					item.CurrentArmorValue = damageArmorInfo.Armor;
					if (damageArmorInfo.Armor <= 0f)
					{
						item.IsActive = false;
					}
					item.LastStateChangeTime = Time.time;
				}
				catch (Exception ex2)
				{
					Debug.LogError((object)("An error occurred while executing the 'OnArmorDamage' method of '" + item.GetType().Name + "': " + ex2.Message));
					break;
				}
				LoggingUtils.LogInfo("Runing all 'DamageProcessingMethodsAfter' method for '" + item.GetType().Name + "'");
				try
				{
					DamageArmorInfo? damageArmorInfo2 = ArmorHandler.DamageProcessingMethodsAfter?.Invoke(item, damagingPlayer, hurtPlayer, num, ((Vector2)(ref damageVector)).magnitude);
					if (damageArmorInfo2.HasValue)
					{
						num = damageArmorInfo2.Value.Damage;
						item.CurrentArmorValue = damageArmorInfo2.Value.Armor;
					}
				}
				catch (Exception ex3)
				{
					Debug.LogError((object)$"An error occurred while executing the '{ex3.TargetSite.Name}' event: {ex3}");
					break;
				}
			}
			Vector2 val = ((Vector2)(ref damageVector)).normalized * num;
			damageVector = val;
		}

		internal void OnRespawn()
		{
			foreach (ArmorBase armor in Armors)
			{
				if (armor.RegenerateFullyAfterRevive)
				{
					LoggingUtils.LogInfo("Regenerating ArmorType '" + armor.GetType().Name + "' fully");
					armor.CurrentArmorValue = armor.MaxArmorValue;
				}
				armor.OnRespawn();
			}
		}

		private void TryReactivateArmor(ArmorBase armor)
		{
			bool num = !armor.IsActive && !armor.Disable;
			bool flag = armor.reactivateArmorType == ArmorReactivateType.Second && Time.time >= armor.LastStateChangeTime + armor.reactivateArmorValue;
			bool flag2 = armor.reactivateArmorType == ArmorReactivateType.Percent && armor.CurrentArmorValue / armor.MaxArmorValue > armor.reactivateArmorValue;
			if (num && (flag || flag2))
			{
				LoggingUtils.LogInfo("Armor '" + armor.GetType().Name + "' passed all reactivation checks. Reactivating...");
				armor.IsActive = true;
				armor.OnReactivate();
			}
		}

		private void UpdateArmorHealthBar()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<ArmorBase, GameObject> armorHealthBar in armorHealthBars)
			{
				CustomHealthBar component = armorHealthBar.Value.GetComponent<CustomHealthBar>();
				component.SetValues(armorHealthBar.Key.CurrentArmorValue, armorHealthBar.Key.MaxArmorValue);
				if (armorHealthBar.Key.IsActive)
				{
					Color activedBarColor = armorHealthBar.Key.GetBarColor().ActivedBarColor;
					activedBarColor.a = 1f;
					component.SetColor(activedBarColor);
				}
				else
				{
					Color deactivatedBarColor = armorHealthBar.Key.GetBarColor().DeactivatedBarColor;
					deactivatedBarColor.a = 1f;
					component.SetColor(deactivatedBarColor);
				}
			}
		}

		private void ResetArmorHealthBar()
		{
			LoggingUtils.LogInfo("Reseting all armor health bars");
			DestroyAllArmorHealthBar();
			foreach (ArmorBase item in ActiveArmors.OrderBy((ArmorBase armors) => armors.Priority).ToList())
			{
				AddArmorHealthBar(item);
			}
		}

		private void AddArmorHealthBar(ArmorBase armor)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			GameObject val = new GameObject(armor.GetType().Name + " Armor Health Bar");
			val.transform.SetParent(((Component)((Component)Player).GetComponentInChildren<PlayerWobblePosition>()).transform);
			val.AddComponent<CustomHealthBar>();
			ExtensionMethods.AddStatusIndicator(Player, val, 0f, true);
			armorHealthBars.Add(armor, val);
			LoggingUtils.LogInfo("Added " + ((Object)val).name);
		}

		private void DestroyAllArmorHealthBar()
		{
			LoggingUtils.LogInfo("Destroying all armor health bars");
			foreach (KeyValuePair<ArmorBase, GameObject> armorHealthBar in armorHealthBars)
			{
				LoggingUtils.LogInfo("Destroy " + ((Object)armorHealthBar.Value).name);
				Object.Destroy((Object)(object)armorHealthBar.Value);
			}
			armorHealthBars.Clear();
		}

		[PunRPC]
		private void RPCA_AddArmor(string armorType, float maxArmorValue, float regenerationRate, float regenCooldownSeconds, ArmorReactivateType reactivateArmorType, float reactivateArmorValue)
		{
			ArmorBase armorByType = GetArmorByType(Type.GetType(armorType));
			if (armorByType == null)
			{
				LoggingUtils.LogError("Failed to add armor. Armor type '" + armorType + "' not found.");
				return;
			}
			LoggingUtils.LogInfo($"Adding armor '{armorType}' with max value {maxArmorValue}, regeneration rate {regenerationRate}, and reactivation value {reactivateArmorValue}");
			armorByType.MaxArmorValue += Mathf.Max(maxArmorValue, 0f);
			armorByType.ArmorRegenerationRate += Mathf.Max(regenerationRate, 0f);
			if (armorByType.ArmorRegenCooldownSeconds < regenCooldownSeconds)
			{
				armorByType.ArmorRegenCooldownSeconds = regenCooldownSeconds;
			}
			armorByType.reactivateArmorType = reactivateArmorType;
			armorByType.reactivateArmorValue = reactivateArmorValue;
		}
	}
}
namespace JARL.Armor.Utlis
{
	public static class ArmorUtils
	{
		public static DamageArmorInfo ApplyDamage(float armor, float damage)
		{
			float armor2 = Mathf.Max(0f, armor - damage);
			float damage2 = Mathf.Max(0f, damage - armor);
			return new DamageArmorInfo(damage2, armor2);
		}

		public static ArmorBase GetRegisteredArmorByType(Type type)
		{
			return ArmorFramework.RegisteredArmorTypes.Find((ArmorBase armor) => armor.GetType() == type);
		}
	}
}
namespace JARL.Armor.Builtin
{
	public class DefaultArmor : ArmorBase
	{
		public override BarColor GetBarColor()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return new BarColor(Color.cyan * 0.6f, Color.cyan * 0.45f);
		}

		public DefaultArmor()
		{
			ArmorTags.Add("CanArmorPierce");
			reactivateArmorType = ArmorReactivateType.Second;
		}
	}
}
namespace JARL.Armor.Bases
{
	public abstract class ArmorBase
	{
		public ArmorDamagePatchType ArmorDamagePatch = ArmorDamagePatchType.TakeDamage | ArmorDamagePatchType.TakeDamageOverTime;

		public List<string> ArmorTags = new List<string>();

		public float MaxArmorValue;

		public float CurrentArmorValue;

		public float ArmorRegenerationRate;

		public float ArmorRegenCooldownSeconds;

		public ArmorReactivateType? reactivateArmorType = ArmorReactivateType.Percent;

		public float reactivateArmorValue;

		public string DeactivateText = "";

		public bool disable;

		public bool RegenerateFullyAfterRevive = true;

		public int Priority;

		public bool IsActive { get; internal set; }

		public bool Disable
		{
			get
			{
				return disable;
			}
			set
			{
				disable = value;
				if (value)
				{
					IsActive = false;
					return;
				}
				LastStateChangeTime = Time.time;
				IsActive = true;
			}
		}

		public float LastStateChangeTime { get; internal set; }

		public ArmorHandler ArmorHandler { get; internal set; }

		public abstract BarColor GetBarColor();

		public bool HasArmorTag(string armorTag)
		{
			return ArmorTags.Contains(armorTag);
		}

		public float HealArmor(float healValue)
		{
			CurrentArmorValue = Mathf.Clamp(CurrentArmorValue + healValue, 0f, MaxArmorValue);
			return CurrentArmorValue;
		}

		public float DamageArmor(float damageValue)
		{
			CurrentArmorValue = OnDamage(damageValue, null, null).Armor;
			if (CurrentArmorValue <= 0f)
			{
				IsActive = false;
			}
			LastStateChangeTime = Time.time;
			return CurrentArmorValue;
		}

		internal void RegenerationArmor()
		{
			if (Time.time > LastStateChangeTime + ArmorRegenCooldownSeconds && !Disable)
			{
				float healValue = ArmorRegenerationRate * Time.deltaTime;
				HealArmor(healValue);
			}
		}

		public virtual DamageArmorInfo OnDamage(float damage, Player DamagingPlayer, ArmorDamagePatchType? armorDamagePatchType)
		{
			return ArmorUtils.ApplyDamage(CurrentArmorValue, damage);
		}

		public virtual void OnUpdate()
		{
		}

		public virtual void OnRespawn()
		{
		}

		public virtual void OnReactivate()
		{
		}

		public override string ToString()
		{
			return GetType().Name.Replace("Armor", "");
		}
	}
}
namespace JARL.Armor.Bases.Builtin
{
	internal class ArmorPiercePercent
	{
		public static DamageArmorInfo ApplyArmorPiercePercent(ArmorBase armor, Player damageingPlayer, Player hurtPlayer, float remaindingDamage, float Damage)
		{
			if (armor.ArmorTags.Contains("CanArmorPierce"))
			{
				float num = damageingPlayer?.data.GetAdditionalData().ArmorPiercePercent ?? 0f;
				return new DamageArmorInfo(Math.Min(remaindingDamage + Damage * num, Damage), armor.CurrentArmorValue);
			}
			return new DamageArmorInfo(remaindingDamage, armor.CurrentArmorValue);
		}
	}
}