Decompiled source of AALUND13 Cards Beta v2.1.0
plugins/AALUND13_Classes_Cards.dll
Decompiled 13 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using AALUND13Cards.Armors.Utils; using AALUND13Cards.Classes; using AALUND13Cards.Classes.Armors; using AALUND13Cards.Classes.Cards; using AALUND13Cards.Classes.MonoBehaviours; using AALUND13Cards.Classes.MonoBehaviours.CardsEffects.Reaper; using AALUND13Cards.Classes.MonoBehaviours.CardsEffects.Soulstreak; using AALUND13Cards.Classes.MonoBehaviours.CardsEffects.Soulstreak.Abilities; using AALUND13Cards.Classes.UI; using AALUND13Cards.Classes.Utils; using AALUND13Cards.Core; using AALUND13Cards.Core.Cards; using AALUND13Cards.Core.Cards.Conditions; using AALUND13Cards.Core.Extensions; using AALUND13Cards.Core.Handlers; using AALUND13Cards.Core.MonoBehaviours; using AALUND13Cards.Core.Utils; using BepInEx; using HarmonyLib; using JARL.Armor; using JARL.Armor.Bases; using JARL.Utils; using Microsoft.CodeAnalysis; using ModdingUtils.GameModes; using ModdingUtils.MonoBehaviours; using ModdingUtils.Utils; using ModsPlus; using Photon.Pun; using Sonigon; using SoundImplementation; using TMPro; using TabInfo.Utils; using UnboundLib; using UnboundLib.GameModes; using UnboundLib.Networking; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.UI; [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; } } } namespace AALUND13Cards.Core.Patches { [HarmonyPatch(typeof(Gun))] public class GunPatch { [HarmonyPatch("ApplyProjectileStats")] [HarmonyPrefix] public static void ApplyRailgunStats(Gun __instance, GameObject obj) { //IL_0038: 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) //IL_0048: Unknown result type (might be due to invalid IL or missing references) RailgunStats orCreate = CharacterDataExtensions.GetCustomStatsRegistry(__instance.player.data).GetOrCreate<RailgunStats>(); if (orCreate.IsEnabled) { ProjectileHit component = obj.GetComponent<ProjectileHit>(); MoveTransform component2 = obj.GetComponent<MoveTransform>(); RailgunStats.RailgunChargeStats chargeStats = orCreate.GetChargeStats(orCreate.CurrentCharge); component2.localForce *= chargeStats.ChargeBulletSpeedMultiplier; component.damage *= chargeStats.ChargeDamageMultiplier; } } [HarmonyPatch("DoAttack")] [HarmonyPostfix] public static void UseRailgunCharge(Gun __instance) { RailgunStats orCreate = CharacterDataExtensions.GetCustomStatsRegistry(__instance.player.data).GetOrCreate<RailgunStats>(); if (orCreate.IsEnabled && orCreate.CurrentCharge > 0f) { orCreate.UseCharge(orCreate); } } [HarmonyPatch("ApplyProjectileStats")] [HarmonyPostfix] public static void ApplyReaperStats(Gun __instance, GameObject obj) { ProjectileHit component = obj.GetComponent<ProjectileHit>(); component.percentageDamage += MathUtils.GetEffectivePercentCap(PlayerExtensions.GetSPS(__instance.player), CharacterDataExtensions.GetCustomStatsRegistry(__instance.player.data).GetOrCreate<ReaperStats>().ScalingPercentageDamage, CharacterDataExtensions.GetCustomStatsRegistry(__instance.player.data).GetOrCreate<ReaperStats>().ScalingPercentageDamageCap); component.percentageDamage += MathUtils.GetEffectivePercent(PlayerExtensions.GetSPS(__instance.player), CharacterDataExtensions.GetCustomStatsRegistry(__instance.player.data).GetOrCreate<ReaperStats>().ScalingPercentageDamageUnCap); } } } namespace AALUND13Cards.Core.MonoBehaviours.CardsEffects { public class RailgunMono : MonoBehaviour { [HideInInspector] public RailgunStats RailgunStats; private CustomHealthBar RailgunChargeBar; private Player player; private void Start() { player = ((Component)this).GetComponentInParent<Player>(); RailgunStats = CharacterDataExtensions.GetAdditionalData(player.data).CustomStatsRegistry.GetOrCreate<RailgunStats>(); RailgunStats.IsEnabled = true; RailgunChargeBar = CreateChargeBar(); HealthHandler healthHandler = player.data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(OnRevive)); } public void OnDestroy() { Object.Destroy((Object)(object)((Component)RailgunChargeBar).gameObject); RailgunStats.IsEnabled = false; HealthHandler healthHandler = player.data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Remove(healthHandler.reviveAction, new Action(OnRevive)); } public void Update() { if (RailgunStats.IsEnabled) { RailgunStats.CurrentCharge = Mathf.Min(RailgunStats.CurrentCharge + RailgunStats.ChargeRate * TimeHandler.deltaTime, RailgunStats.MaximumCharge); } RailgunChargeBar.SetValues(RailgunStats.CurrentCharge, RailgunStats.MaximumCharge); } public void OnRevive() { RailgunStats.CurrentCharge = RailgunStats.MaximumCharge; } private CustomHealthBar CreateChargeBar() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0012: 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) GameObject val = new GameObject("Railgun Charge Bar"); CustomHealthBar obj = val.AddComponent<CustomHealthBar>(); obj.SetColor(Color.cyan * 0.8f); ExtensionMethods.AddStatusIndicator(player, val, 0f, true); Object.Destroy((Object)(object)((Component)val.transform.Find("Healthbar(Clone)/Canvas/Image/White")).gameObject); return obj; } } public class RailgunOvercharge : MonoBehaviour { [SerializeField] private SoundEvent soundEmpowerSpawn; private CharacterData data; private ParticleSystem[] parts; private Transform particleTransform; private RailgunMono railgun; private bool isOn; private void Start() { parts = ((Component)this).GetComponentsInChildren<ParticleSystem>(); particleTransform = ((Component)this).transform.GetChild(0); railgun = ((Component)((Component)this).transform.parent).GetComponentInChildren<RailgunMono>(); data = ((Component)this).GetComponentInParent<CharacterData>(); Block block = data.block; block.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(block.BlockAction, new Action<BlockTriggerType>(Block)); HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(ResetOvercharge)); soundEmpowerSpawn.variables.audioMixerGroup = SoundVolumeManager.Instance.audioMixer.FindMatchingGroups("SFX")[0]; } private void OnDestroy() { Block block = data.block; block.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(block.BlockAction, new Action<BlockTriggerType>(Block)); HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Remove(healthHandler.reviveAction, new Action(ResetOvercharge)); railgun.RailgunStats.AllowOvercharge = false; } public void Block(BlockTriggerType trigger) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if ((int)trigger != 3 && (int)trigger != 4 && (int)trigger != 2) { railgun.RailgunStats.AllowOvercharge = true; } } private void ResetOvercharge() { railgun.RailgunStats.AllowOvercharge = false; } private void Update() { //IL_0047: 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) ParticleSystem[] array = parts; foreach (ParticleSystem val in array) { if (railgun.RailgunStats.AllowOvercharge) { ((Component)particleTransform).transform.position = ((Component)data.weaponHandler.gun).transform.position; ((Component)particleTransform).transform.rotation = ((Component)data.weaponHandler.gun).transform.rotation; if (!isOn) { SoundManager.Instance.PlayAtPosition(soundEmpowerSpawn, SoundManager.Instance.GetTransform(), ((Component)this).transform); val.Play(); isOn = true; } } else if (!railgun.RailgunStats.AllowOvercharge && isOn) { val.Stop(); isOn = false; } } } } } namespace AALUND13Cards.Classes { public class ArmorInterface { public static void RegisterArmors() { ArmorFramework.RegisterArmorType<SoulArmor>(); ArmorTypeGetterUtils.RegiterArmorType<ExoArmor>("Exo-Armor"); } } } namespace AALUND13Cards.Classes.Utils { public static class MathUtils { public const float PERCENT_CAP = 0.8f; public const float EXPONENT = 0.75f; public static float GetEffectivePercentCap(float sps, float basePercent, float percentCap = 0.8f) { float num = Mathf.Max(0.0001f, sps); float num2 = Mathf.Min(percentCap, 0.8f); return Mathf.Min(basePercent * Mathf.Pow(1f / num, 0.75f), num2); } public static float GetEffectivePercent(float sps, float basePercent) { float num = Mathf.Max(0.0001f, sps); return basePercent * Mathf.Pow(1f / num, 0.75f); } } public class ReflectionUtils { public static FieldInfo FindNestedField(MethodInfo method, string fieldName) { if (method == null) { throw new ArgumentNullException("method"); } Type declaringType = method.DeclaringType; if (declaringType == null) { return null; } Type[] nestedTypes = declaringType.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic); foreach (Type type in nestedTypes) { if (type.GetCustomAttribute<CompilerGeneratedAttribute>() != null && type.Name.Contains(method.Name)) { FieldInfo fieldInfo = FindNestedFieldRecursive(type, fieldName); if (fieldInfo != null) { return fieldInfo; } } } return null; } private static FieldInfo FindNestedFieldRecursive(Type type, string fieldName) { FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < nestedTypes.Length; i++) { FieldInfo fieldInfo = FindNestedFieldRecursive(nestedTypes[i], fieldName); if (fieldInfo != null) { return fieldInfo; } } return null; } } } namespace AALUND13Cards.Classes.UI { public class SoulstreakSoulsCounter : MonoBehaviour { [Header("Souls Text")] public TMP_Text SoulstreakSoulsText; public bool UseFullText = true; [Header("Single Bar")] public GameObject SingleBarObject; public Image SinglePercentage; [Header("Double Bar")] public GameObject DoubleBarObject; public Image DoubleBarPercentageFirst; public Image DoubleBarPercentageSecond; [Header("Color")] public Color BarNonActiveColor; public Color BarActiveColor; [Header("Animation")] [SerializeField] private float fillSmoothTime = 0.15f; private float firstCurrentFillVelocity; private float firstTargetFillAmount; private float secondCurrentFillVelocity; private float secondTargetFillAmount; [HideInInspector] public SoulstreakMono soulstreakMono; private void Update() { if (!((Object)(object)soulstreakMono == (Object)null)) { UpdateSoulsText(); UpdateArmorUI(); } } private void LateUpdate() { if (!((Object)(object)SingleBarObject == (Object)null) && !((Object)(object)DoubleBarObject == (Object)null)) { SinglePercentage.fillAmount = Mathf.SmoothDamp(SinglePercentage.fillAmount, firstTargetFillAmount, ref firstCurrentFillVelocity, fillSmoothTime); DoubleBarPercentageFirst.fillAmount = Mathf.SmoothDamp(DoubleBarPercentageFirst.fillAmount, firstTargetFillAmount, ref firstCurrentFillVelocity, fillSmoothTime); DoubleBarPercentageSecond.fillAmount = Mathf.SmoothDamp(DoubleBarPercentageSecond.fillAmount, secondTargetFillAmount, ref secondCurrentFillVelocity, fillSmoothTime); } } private void UpdateSoulsText() { if (!((Object)(object)SoulstreakSoulsText == (Object)null)) { uint souls = soulstreakMono.SoulstreakStats.Souls; if (UseFullText) { string arg = ((souls == 1) ? "Soul" : "Souls"); SoulstreakSoulsText.text = $"{arg}: {souls}"; } else { SoulstreakSoulsText.text = souls.ToString(); } } } private void UpdateArmorUI() { if (!((Object)(object)SingleBarObject == (Object)null) && !((Object)(object)DoubleBarObject == (Object)null)) { RenderBars(soulstreakMono.SoulstreakStats.Abilities.ToArray()); } } private void RenderBars(ISoulstreakAbility[] soulstreakAbilities) { //IL_0088: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) int num = 0; List<AbilityBarInfo> list = new List<AbilityBarInfo>(); for (int i = 0; i < soulstreakAbilities.Length; i++) { AbilityBarInfo barInfo = soulstreakAbilities[i].GetBarInfo(); if (barInfo.ShowBar) { list.Add(barInfo); num++; } } if (num > 2) { throw new Exception("More then 2 abilities requested bars, but counter only support TWO bars"); } switch (num) { case 1: SingleBarObject.SetActive(true); DoubleBarObject.SetActive(false); ((Graphic)SinglePercentage).color = (list[0].IsActive ? BarActiveColor : BarNonActiveColor); firstTargetFillAmount = 0.5f + Mathf.Clamp01(list[0].CurrentValue / list[0].MaxValue * 0.5f); break; case 2: SingleBarObject.SetActive(false); DoubleBarObject.SetActive(true); ((Graphic)DoubleBarPercentageFirst).color = (list[0].IsActive ? BarActiveColor : BarNonActiveColor); firstTargetFillAmount = 0.5f + Mathf.Clamp01(list[0].CurrentValue / list[0].MaxValue * 0.25f); ((Graphic)DoubleBarPercentageSecond).color = (list[1].IsActive ? BarActiveColor : BarNonActiveColor); secondTargetFillAmount = 0.5f + Mathf.Clamp01(list[1].CurrentValue / list[1].MaxValue * 0.25f); break; default: SingleBarObject.SetActive(true); DoubleBarObject.SetActive(false); ((Graphic)SinglePercentage).color = BarNonActiveColor; SinglePercentage.fillAmount = 0.5f; break; } } } public class UILoopingMover : MonoBehaviour { [Header("UI Elements")] [SerializeField] private List<RectTransform> uiElements; [Header("Movement")] [SerializeField] private RectTransform moveTarget; [SerializeField] private float moveSpeed = 200f; [SerializeField] private float reachThreshold = 5f; [Header("Teleport")] [SerializeField] private RectTransform teleportTarget; [SerializeField] private Vector2 teleportOffsetMin; [SerializeField] private Vector2 teleportOffsetMax; private void Update() { foreach (RectTransform uiElement in uiElements) { MoveElement(uiElement); } } private void MoveElement(RectTransform element) { //IL_0002: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) element.anchoredPosition = Vector2.MoveTowards(element.anchoredPosition, moveTarget.anchoredPosition, moveSpeed * Time.deltaTime); if (Vector2.Distance(element.anchoredPosition, moveTarget.anchoredPosition) <= reachThreshold) { TeleportElement(element); } } private void TeleportElement(RectTransform element) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(Random.Range(teleportOffsetMin.x, teleportOffsetMax.x), Random.Range(teleportOffsetMin.y, teleportOffsetMax.y)); element.anchoredPosition = teleportTarget.anchoredPosition + val; } private void OnDrawGizmos() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)teleportTarget == (Object)null)) { Gizmos.color = Color.cyan; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(teleportOffsetMin.x, teleportOffsetMin.y, 0f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(teleportOffsetMax.x, teleportOffsetMax.y, 0f); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(teleportOffsetMin.x, teleportOffsetMax.y, 0f); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(teleportOffsetMax.x, teleportOffsetMin.y, 0f); Vector3 val5 = ((Transform)teleportTarget).TransformPoint(val); Vector3 val6 = ((Transform)teleportTarget).TransformPoint(val3); Vector3 val7 = ((Transform)teleportTarget).TransformPoint(val2); Vector3 val8 = ((Transform)teleportTarget).TransformPoint(val4); Gizmos.DrawLine(val5, val6); Gizmos.DrawLine(val6, val7); Gizmos.DrawLine(val7, val8); Gizmos.DrawLine(val8, val5); } } } } namespace AALUND13Cards.Classes.Patches { [HarmonyPatch(typeof(DamageOverTime))] public class DamageOverTimePatch { [HarmonyPatch("TakeDamageOverTime")] [HarmonyPrefix] public static void TakeDamageOverTimePrefix(DamageOverTime __instance, Vector2 damage, Vector2 position, float time, float interval, Color color, SoundEvent soundDamageOverTime, GameObject damagingWeapon, Player damagingPlayer, bool lethal) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //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) if (CharacterDataExtensions.GetCustomStatsRegistry((CharacterData)Traverse.Create((object)__instance).Field("data").GetValue()).GetOrCreate<ClassesStats>().Invulnerable) { damage = Vector2.zero; } } } [HarmonyPatch(typeof(DeathEffect))] public class DeathEffectPatch { [HarmonyPatch("PlayDeath")] [HarmonyPostfix] public static void PlayDeathPostfix(DeathEffect __instance, int playerIDToRevive) { ICustomDeathEffect[] components = ((Component)__instance).GetComponents<ICustomDeathEffect>(); for (int i = 0; i < components.Length; i++) { components[i].OnDeath(__instance, PlayerManager.instance.players.First((Player p) => p.playerID == playerIDToRevive)); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> RespawnPlayerTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator il) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown LoggerUtils.LogInfo("Begin patching the \"RespawnPlayer\" method in the \"DeathEffect\" class", false); List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo method = AccessTools.Method(typeof(DeathEffect), "RespawnPlayer", (Type[])null, (Type[])null); MethodInfo methodInfo = AccessTools.Method(typeof(DeathEffectPatch), "OnRespawn", (Type[])null, (Type[])null); FieldInfo fieldInfo = ReflectionUtils.FindNestedField(method, "playerIDToRevive"); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_I4_0 && list[i + 1].opcode == OpCodes.Ret && list[i - 1].opcode == OpCodes.Callvirt) { CodeInstruction[] array = (CodeInstruction[])(object)new CodeInstruction[4] { new CodeInstruction(OpCodes.Ldloc_1, (object)null), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo), new CodeInstruction(OpCodes.Callvirt, (object)methodInfo) }; list.InsertRange(i, array); LoggerUtils.LogInfo("Patched the \"RespawnPlayer\" method to trigger the our \"OnRespawn\" method", false); i += array.Length; } } return list; } private static void OnRespawn(DeathEffect __instance, int playerIDToRevive) { ICustomDeathRespawnEffect[] components = ((Component)__instance).GetComponents<ICustomDeathRespawnEffect>(); for (int i = 0; i < components.Length; i++) { components[i].OnRespawn(__instance, PlayerManager.instance.players.First((Player p) => p.playerID == playerIDToRevive)); } } } [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] public static void TakeDamagePrefix(HealthHandler __instance, ref Vector2 damage) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002c: 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) if (CharacterDataExtensions.GetCustomStatsRegistry((CharacterData)Traverse.Create((object)__instance).Field("data").GetValue()).GetOrCreate<ClassesStats>().Invulnerable) { damage = Vector2.zero; } } [HarmonyPatch("DoDamage")] [HarmonyPrefix] public static void DoDamage(HealthHandler __instance, ref Vector2 damage) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) CharacterData val = (CharacterData)Traverse.Create((object)__instance).Field("data").GetValue(); if (CharacterDataExtensions.GetCustomStatsRegistry(val).GetOrCreate<ClassesStats>().DamageResistance > 0f) { damage *= Mathf.Clamp01(1f - CharacterDataExtensions.GetCustomStatsRegistry(val).GetOrCreate<ClassesStats>().DamageResistance); } if (CharacterDataExtensions.GetCustomStatsRegistry(val).GetOrCreate<ClassesStats>().Invulnerable) { damage = Vector2.zero; } } } [HarmonyPatch(typeof(ProjectileHit), "Hit")] internal class ProjectileHitPatch { private static bool Prefix(ProjectileHit __instance, HitInfo hit, bool forceCall) { //IL_008f: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00bf: 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) HealthHandler val = null; if (Object.op_Implicit((Object)(object)hit.transform)) { val = ((Component)hit.transform).GetComponent<HealthHandler>(); } if (Object.op_Implicit((Object)(object)val)) { Player component = ((Component)val).GetComponent<Player>(); ExoArmor exoArmor = (ExoArmor)(object)ArmorFramework.ArmorHandlers[component].GetArmorByType<ExoArmor>(); if ((Object)(object)component != (Object)null && ((ArmorBase)exoArmor).IsActive && exoArmor.Reflect(GetBulletDamage(((Component)__instance).GetComponent<ProjectileHit>(), component))) { ((Component)__instance).GetComponent<ProjectileHit>().RemoveOwnPlayerFromPlayersHit(); ((Component)__instance).GetComponent<ProjectileHit>().AddPlayerToHeld(val); MoveTransform component2 = ((Component)__instance).GetComponent<MoveTransform>(); component2.velocity *= -1f; Transform transform = ((Component)__instance).transform; transform.position += ((Component)__instance).GetComponent<MoveTransform>().velocity * TimeHandler.deltaTime; ((Component)__instance).GetComponent<RayCastTrail>().WasBlocked(); if (__instance.destroyOnBlock) { ExtensionMethods.InvokeMethod((object)__instance, "DestroyMe", Array.Empty<object>()); } __instance.sinceReflect = 0f; return false; } } return true; } private static float GetBulletDamage(ProjectileHit projectileHit, Player targetPlayer) { float damage = projectileHit.damage; float percentageDamage = projectileHit.percentageDamage; return damage + targetPlayer.data.maxHealth * percentageDamage; } } } namespace AALUND13Cards.Classes.MonoBehaviours { public interface ICustomDeathEffect { void OnDeath(DeathEffect effect, Player player); } public interface ICustomDeathRespawnEffect { void OnRespawn(DeathEffect effect, Player player); } } namespace AALUND13Cards.Classes.MonoBehaviours.ProjectilesEffects { public class RayHitPercentDamageOverTime : RayHitEffect { [Header("Sounds")] public SoundEvent soundEventDamageOverTime; [Header("Settings")] public float PrecntageDamage = 0.15f; public Color Color = new Color(0.8867924f, 0.598302f, 0f); [Header("Damage Over Time")] public float Time = 5f; public float Interval = 0.5f; public override HasToReturn DoHitEffect(HitInfo hit) { //IL_006a: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)hit.transform)) { CharacterData component = ((Component)hit.transform).GetComponent<CharacterData>(); if (!((Object)(object)component == (Object)null) && !component.dead) { float effectivePercentCap = MathUtils.GetEffectivePercentCap(PlayerExtensions.GetSPS(((Component)this).GetComponentInParent<ProjectileHit>().ownPlayer), PrecntageDamage); float num = component.maxHealth * effectivePercentCap; ((Component)hit.transform).GetComponent<DamageOverTime>().TakeDamageOverTime(Vector2.op_Implicit(num * ((Component)this).transform.forward), Vector2.op_Implicit(((Component)this).transform.position), Time, Interval, Color, soundEventDamageOverTime, ((Component)this).GetComponentInParent<ProjectileHit>().ownWeapon, ((Component)this).GetComponentInParent<ProjectileHit>().ownPlayer, true); return (HasToReturn)1; } return (HasToReturn)1; } return (HasToReturn)1; } } public class RayHitWithering : RayHitEffect { public float PercentageDamagePerSecond = 0.005f; public override HasToReturn DoHitEffect(HitInfo hit) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)hit.transform)) { CharacterData component = ((Component)hit.transform).GetComponent<CharacterData>(); if (!((Object)(object)component == (Object)null) && !component.dead) { float effectivePercentCap = MathUtils.GetEffectivePercentCap(PlayerExtensions.GetSPS(((Component)this).GetComponentInParent<ProjectileHit>().ownPlayer), PercentageDamagePerSecond); ConstantDamageHandler.Instance.AddConstantPrecentageDamage(component.player, ((Component)this).GetComponentInParent<ProjectileHit>().ownPlayer, Color.black, effectivePercentCap); return (HasToReturn)1; } return (HasToReturn)1; } return (HasToReturn)1; } } public class SetProjectileDamage : MonoBehaviour { public float damage; private void Start() { ((Component)this).GetComponentInParent<ProjectileHit>().damage = damage; } } } namespace AALUND13Cards.Classes.MonoBehaviours.DeathEffects { public class GrimFateDeathRespawnEffect : MonoBehaviour, ICustomDeathRespawnEffect { public PercentDamageExplosion PercentDamageExplosion; public GameObject ActivateObjectWhenRespawn; public void OnRespawn(DeathEffect effect, Player player) { if (player.data.view.IsMine) { PercentDamageExplosion.Trigger(player); } ActivateObjectWhenRespawn.SetActive(true); } } } namespace AALUND13Cards.Classes.MonoBehaviours.CardsEffects { public class CooldownTrigger : MonoBehaviour { public UnityEvent Trigger; public float Cooldown = 5f; private float lastTriggerTime; public void TriggerCooldown() { if (Time.time > lastTriggerTime + Cooldown) { lastTriggerTime = Time.time; UnityEvent trigger = Trigger; if (trigger != null) { trigger.Invoke(); } } } } } namespace AALUND13Cards.Classes.MonoBehaviours.CardsEffects.Soulstreak { public class DreadfulBurstEffect : MonoBehaviour, ISoulstreakAbility { private float storedDamage; private int ticks; private Player player; private DamageSpawnObjects damageSpawnObjects; private const int MINIMUM_DRAIN_TICKS = 20; private void Start() { player = ((Component)this).GetComponentInParent<Player>(); damageSpawnObjects = ((Component)this).GetComponent<DamageSpawnObjects>(); DamageEventHandler.Instance.RegisterDamageEvent((object)this, player); CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<SoulStreakStats>().AddAbilityRaw(this); SoulstreakDrain soulstreakDrain = CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<SoulStreakStats>().GetAbility<SoulDrainAbility>() .soulstreakDrain; soulstreakDrain.OnPlayerDamage = (Action<Player, float>)Delegate.Combine(soulstreakDrain.OnPlayerDamage, new Action<Player, float>(OnSoulDrainTick)); } public void OnSoulDrainTick(Player target, float damage) { if (!(CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<SoulStreakStats>().DamageStorage <= (float)ticks)) { storedDamage += damage; ticks++; } } public void OnBlock() { //IL_0010: 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) if (20 <= ticks) { damageSpawnObjects.SpawnDamage(Vector2.up * storedDamage); storedDamage = 0f; ticks = 0; } } public AbilityBarInfo GetBarInfo() { return new AbilityBarInfo(showBar: true, 20 <= ticks, ticks, CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<SoulStreakStats>().DamageStorage); } public void OnUpdate() { } public void OnSoulsAdded(uint addedSouls) { } public void OnSoulsReset(uint remainingSouls) { } public void OnRevive() { } public void OnRemove() { } } public class SoulDrainAbility : SoulstreakAbility<SoulDrainAbility> { public SoulstreakDrain soulstreakDrain; public SoulDrainAbility(SoulstreakDrain soulstreakDrain) { this.soulstreakDrain = soulstreakDrain; } } public class SoulstreakDrain : MonoBehaviour { public const string SOUL_DRAIN_DAMAGE_TRIGGER_KEY = "Soul_Drain_Damage_Trigger"; [Header("Sounds")] public SoundEvent SoundDamage; [Header("Effects")] public GameObject soulDrainEffect; public UnityEvent DamagePlayerTrigger; [Header("Settings")] public float Range = 5f; public float Cooldown = 0.5f; public Action<Player, float> OnPlayerDamage; private SoulStreakStats soulstreakStats; private ChildRPC childRPC; private Player player; private readonly Dictionary<Player, float> timeSinceHits = new Dictionary<Player, float>(); private readonly Dictionary<Player, GameObject> playerEffects = new Dictionary<Player, GameObject>(); private readonly Queue<GameObject> unusedEffects = new Queue<GameObject>(); private void Awake() { player = ((Component)this).GetComponentInParent<Player>(); childRPC = ((Component)this).GetComponentInParent<ChildRPC>(); soulstreakStats = CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<SoulStreakStats>(); childRPC.childRPCsInt.Add("Soul_Drain_Damage_Trigger", TriggerDamageForPlayer); soulstreakStats.AddAbility(new SoulDrainAbility(this)); } private void OnDestroy() { childRPC.childRPCsInt.Remove("Soul_Drain_Damage_Trigger"); } private void Start() { AudioMixerGroup[] array = SoundVolumeManager.Instance.audioMixer.FindMatchingGroups("SFX"); if (array.Length != 0) { SoundDamage.variables.audioMixerGroup = array[0]; } soulDrainEffect.SetActive(true); unusedEffects.Enqueue(soulDrainEffect); } private void Update() { List<Player> enemiesInRange = GetEnemiesInRange(); List<Player> list = playerEffects.Keys.ToList(); foreach (Player item in enemiesInRange) { if ((!timeSinceHits.TryGetValue(item, out var value) || Time.time > value + Cooldown) && player.data.view.IsMine) { childRPC.CallFunction("Soul_Drain_Damage_Trigger", item.playerID); timeSinceHits[item] = Time.time; } list.Remove(item); ShowEffectForPlayer(item); } foreach (Player item2 in list) { HideEffectForPlayer(item2); } } private GameObject GetEffectForPlayer(Player target) { if (playerEffects.TryGetValue(target, out var value)) { return value; } value = ((unusedEffects.Count <= 0) ? Object.Instantiate<GameObject>(soulDrainEffect, ((Component)this).transform) : unusedEffects.Dequeue()); value.GetComponentInChildren<ParticleSystem>().Play(); playerEffects[target] = value; return value; } private void ShowEffectForPlayer(Player target) { //IL_0014: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0057: 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_005f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) GameObject effectForPlayer = GetEffectForPlayer(target); effectForPlayer.transform.position = ((Component)target).transform.position + new Vector3(0f, 0f, 6f); Vector3 val = ((Component)target).transform.position - ((Component)player).transform.position; Vector3 normalized = ((Vector3)(ref val)).normalized; if (normalized != Vector3.zero) { effectForPlayer.transform.rotation = Quaternion.LookRotation(normalized); } } private void HideEffectForPlayer(Player target) { if (playerEffects.TryGetValue(target, out var value)) { value.GetComponentInChildren<ParticleSystem>().Stop(); unusedEffects.Enqueue(value); playerEffects.Remove(target); } } public void TriggerDamageForPlayer(int playerID) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0097: Unknown result type (might be due to invalid IL or missing references) if (soulstreakStats != null) { Player playerWithID = ExtensionMethods.GetPlayerWithID(PlayerManager.instance, playerID); float num = GetDamage(playerWithID) + GetPercentageDamage(playerWithID); float num2 = Mathf.Min(num, playerWithID.data.health); Vector3 val = ((Component)playerWithID).transform.position - ((Component)this).transform.position; Vector2 val2 = Vector2.op_Implicit(((Vector3)(ref val)).normalized); float num3 = Mathf.Max(0f, num2 * soulstreakStats.SoulDrainLifestealMultiply); ((Damagable)playerWithID.data.healthHandler).TakeDamage(val2 * num, Vector2.op_Implicit(((Component)this).transform.position), (GameObject)null, player, true, true); player.data.healthHandler.Heal(num3); SoundManager.Instance.Play(SoundDamage, ((Component)playerWithID).transform); OnPlayerDamage?.Invoke(playerWithID, num); } } private float GetDamage(Player target) { return PlayerExtensions.GetDPS(player) * soulstreakStats.SoulDrainDPSFactor * Cooldown; } private float GetPercentageDamage(Player target) { float num = soulstreakStats.SoulDrainPercentageDPSFactor * Cooldown; return target.data.maxHealth * num; } private List<Player> GetEnemiesInRange() { //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) //IL_0096: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) List<Player> list = new List<Player>(); if (!GameManager.instance.battleOngoing) { return list; } foreach (Player player in PlayerManager.instance.players) { if (player.teamID != this.player.teamID && player.data.isPlaying && !player.data.dead && PlayerManager.instance.CanSeePlayer(Vector2.op_Implicit(((Component)this.player).transform.position), player).canSee && !(Vector2.Distance(Vector2.op_Implicit(((Component)this.player).transform.position), Vector2.op_Implicit(((Component)player).transform.position)) >= Range * ((Component)this).transform.root.localScale.x)) { list.Add(player); } } return list; } } public class SoulstreakEffect : ReversibleEffect, IPickStartHookHandler, IGameStartHookHandler { public override void OnStart() { InterfaceGameModeHooksManager.instance.RegisterHooks((object)this); ((ReversibleEffect)this).SetLivesToEffect(int.MaxValue); base.applyImmediately = false; ApplyStats(); } public void ApplyStats() { SoulStreakStats orCreate = CharacterDataExtensions.GetCustomStatsRegistry(base.data).GetOrCreate<SoulStreakStats>(); uint souls = orCreate.Souls; ((ReversibleEffect)this).ClearModifiers(true); base.characterDataModifier.maxHealth_mult = 1f + (orCreate.MaxHealth - 1f) * (float)souls; base.characterStatModifiersModifier.sizeMultiplier_mult = 1f + (orCreate.PlayerSize - 1f) * (float)souls; base.characterStatModifiersModifier.movementSpeed_mult = 1f + (orCreate.MovementSpeed - 1f) * (float)souls; base.gunStatModifier.attackSpeed_mult = 1f + (orCreate.AttackSpeed - 1f) * (float)souls; base.gunStatModifier.damage_mult = 1f + (orCreate.Damage - 1f) * (float)souls; base.gunStatModifier.projectileSpeed_mult = 1f + (orCreate.BulletSpeed - 1f) * (float)souls; ((ReversibleEffect)this).ApplyModifiers(); } public void OnGameStart() { Object.Destroy((Object)(object)this); } public void OnPickStart() { Object.Destroy((Object)(object)this); } public override void OnOnDestroy() { InterfaceGameModeHooksManager.instance.RemoveHooks((object)this); } } public class SoulstreakMono : MonoBehaviour, IBattleStartHookHandler { public GameObject SoulsCounter; public GameObject SoulsCounterGUI; public SoulStreakStats SoulstreakStats; private CharacterData data; public CharacterData Data => data; public void BlockAbility() { foreach (ISoulstreakAbility ability in SoulstreakStats.Abilities) { ability.OnBlock(); } } public void ResetSouls(float precentage = 0.5f) { if (!GameManager.instance.battleOngoing) { return; } LoggerUtils.LogInfo($"Resetting kill streak of player with ID {data.player.playerID}", false); if ((Object)(object)((Component)data).gameObject.GetComponent<SoulstreakEffect>() != (Object)null) { Object.Destroy((Object)(object)((Component)data).gameObject.GetComponent<SoulstreakEffect>()); } uint souls = (uint)Mathf.RoundToInt((float)SoulstreakStats.Souls / 2f); foreach (ISoulstreakAbility ability in SoulstreakStats.Abilities) { ability.OnSoulsReset(SoulstreakStats.Souls); } SoulstreakStats.Souls = souls; } public void AddSouls(uint kills = 1u) { if (!GameManager.instance.battleOngoing) { return; } LoggerUtils.LogInfo($"Adding {kills} kills for player with ID {data.player.playerID}", false); SoulstreakStats.Souls += kills; ExtensionMethods.GetOrAddComponent<SoulstreakEffect>(((Component)data).gameObject, false).ApplyStats(); foreach (ISoulstreakAbility ability in SoulstreakStats.Abilities) { ability.OnSoulsAdded(kills); } } public void OnBattleStart() { ExtensionMethods.GetOrAddComponent<SoulstreakEffect>(((Component)data).gameObject, false).ApplyStats(); } private void OnRevive() { foreach (ISoulstreakAbility ability in SoulstreakStats.Abilities) { ability.OnRevive(); } } private void Start() { //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) data = ((Component)this).GetComponentInParent<Player>().data; SoulstreakStats = CharacterDataExtensions.GetAdditionalData(data).CustomStatsRegistry.GetOrCreate<SoulStreakStats>(); SoulsCounter = Object.Instantiate<GameObject>(SoulsCounter); SoulsCounter.GetComponent<SoulstreakSoulsCounter>().soulstreakMono = this; if (data.view.IsMine && !((Behaviour)((Component)data).GetComponent<PlayerAPI>()).enabled) { SoulsCounterGUI = Object.Instantiate<GameObject>(SoulsCounterGUI); SoulsCounterGUI.transform.SetParent(((Component)data).transform.parent); SoulsCounterGUI.GetComponent<SoulstreakSoulsCounter>().soulstreakMono = this; } data.SetWobbleObjectChild(SoulsCounter.transform); SoulsCounter.transform.localPosition = Vector2.op_Implicit(new Vector2(0f, 0.3f)); InterfaceGameModeHooksManager.instance.RegisterHooks((object)this); HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(OnRevive)); } private void OnDestroy() { if (data.view.IsMine && !((Behaviour)((Component)data).GetComponent<PlayerAPI>()).enabled) { Object.Destroy((Object)(object)SoulsCounterGUI); } Object.Destroy((Object)(object)SoulsCounter); if ((Object)(object)((Component)data).gameObject.GetComponent<SoulstreakEffect>() != (Object)null) { Object.Destroy((Object)(object)((Component)data).gameObject.GetComponent<SoulstreakEffect>()); } InterfaceGameModeHooksManager.instance.RemoveHooks((object)this); HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Remove(healthHandler.reviveAction, new Action(OnRevive)); } private void Update() { if (!data.isPlaying) { return; } foreach (ISoulstreakAbility ability in SoulstreakStats.Abilities) { ability.OnUpdate(); } } } } namespace AALUND13Cards.Classes.MonoBehaviours.CardsEffects.Soulstreak.Abilities { public class ArmorAbility : SoulstreakAbility<ArmorAbility> { public float AbilityCooldownTime; private bool abilityActive; private ArmorHandler armorHandler; private Player player; public float AbilityCooldown { get; private set; } public ArmorAbility(Player player, float abilityCooldownTime) { AbilityCooldownTime = abilityCooldownTime; AbilityCooldown = 0f; abilityActive = false; armorHandler = ArmorFramework.ArmorHandlers[player]; this.player = player; } public override void OnBlock() { if (!abilityActive && AbilityCooldown == 0f) { ArmorBase armorByType = armorHandler.GetArmorByType<SoulArmor>(); armorByType.MaxArmorValue = player.data.maxHealth * base.SoulstreakStats.SoulArmorPercentage * (float)(base.SoulstreakStats.Souls + 1); armorByType.ArmorRegenerationRate = armorByType.MaxArmorValue * base.SoulstreakStats.SoulArmorPercentageRegenRate; armorByType.CurrentArmorValue = armorByType.MaxArmorValue; abilityActive = true; } } public override void OnRevive() { abilityActive = false; AbilityCooldown = 0f; ArmorBase armorByType = armorHandler.GetArmorByType<SoulArmor>(); armorByType.MaxArmorValue = 0f; armorByType.CurrentArmorValue = 0f; } public override void OnUpdate() { AbilityCooldown = Mathf.Max(AbilityCooldown - TimeHandler.deltaTime, 0f); if (armorHandler.GetArmorByType<SoulArmor>().CurrentArmorValue <= 0f && armorHandler.GetArmorByType<SoulArmor>().MaxArmorValue > 0f) { armorHandler.GetArmorByType<SoulArmor>().MaxArmorValue = 0f; AbilityCooldown = 10f; abilityActive = false; } } public override AbilityBarInfo GetBarInfo() { SoulArmor soulArmor = (SoulArmor)(object)armorHandler.GetArmorByType<SoulArmor>(); float currentValue = 0f; if (!((ArmorBase)soulArmor).IsActive && ((ArmorBase)soulArmor).MaxArmorValue <= 0f && AbilityCooldownTime > 0f) { currentValue = Mathf.Clamp01((AbilityCooldownTime - AbilityCooldown) / AbilityCooldownTime); } else if (((ArmorBase)soulArmor).IsActive && ((ArmorBase)soulArmor).MaxArmorValue > 0f && ((ArmorBase)soulArmor).MaxArmorValue > 0f) { currentValue = Mathf.Clamp01(((ArmorBase)soulArmor).CurrentArmorValue / ((ArmorBase)soulArmor).MaxArmorValue); } return new AbilityBarInfo(showBar: true, ((ArmorBase)soulArmor).IsActive, currentValue, 1f); } } public struct AbilityBarInfo { public bool ShowBar; public bool IsActive; public float CurrentValue; public float MaxValue; public AbilityBarInfo(bool showBar, bool isActive, float currentValue, float maxValue) { ShowBar = showBar; IsActive = isActive; CurrentValue = currentValue; MaxValue = maxValue; } } public interface ISoulstreakAbility { void OnBlock(); void OnRevive(); void OnUpdate(); void OnSoulsAdded(uint addedSouls); void OnSoulsReset(uint remainingSouls); void OnRemove(); AbilityBarInfo GetBarInfo(); } public class SoulstealerResistanceAbiilty : SoulstreakAbility<SoulstealerResistanceAbiilty> { private Player player; private float addedDamageResistance; public SoulstealerResistanceAbiilty(Player player) { this.player = player; } public override void OnSoulsAdded(uint addedSouls) { float damageResistance = CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ClassesStats>().DamageResistance; float num = base.SoulstreakStats.DamageResistancePerKill * (float)addedSouls; float num2 = Mathf.Min(damageResistance + num, 0.75f); float num3 = num2 - damageResistance; addedDamageResistance += num3; CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ClassesStats>().DamageResistance = num2; } public override void OnSoulsReset(uint remainingSouls) { CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ClassesStats>().DamageResistance -= addedDamageResistance; addedDamageResistance = 0f; OnSoulsAdded(remainingSouls); } } public abstract class SoulstreakAbility<TAbility> : ISoulstreakAbility where TAbility : SoulstreakAbility<TAbility> { public SoulStreakStats SoulstreakStats { get; internal set; } public virtual void OnBlock() { } public virtual void OnRevive() { } public virtual void OnUpdate() { } public virtual void OnSoulsAdded(uint addedSouls) { } public virtual void OnSoulsReset(uint removedSouls) { } public virtual void OnRemove() { } public virtual AbilityBarInfo GetBarInfo() { return new AbilityBarInfo(showBar: false, isActive: false, 0f, 0f); } } } namespace AALUND13Cards.Classes.MonoBehaviours.CardsEffects.Reaper { public class BloodlustBehaviour : MonoBehaviour, IOnDoDamageEvent { public const float DEFAULT_MAX_BLOOD = 100f; private CharacterData data; private CustomHealthBar bloodBar; private float decayingPrecentageDamage; private float appliedScaling; public ReaperStats ReaperStats => CharacterDataExtensions.GetCustomStatsRegistry(data).GetOrCreate<ReaperStats>(); public BloodlustStats BloodlustStats => CharacterDataExtensions.GetCustomStatsRegistry(data).GetOrCreate<BloodlustStats>(); public void OnDamage(DamageInfo damage) { //IL_000b: 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_0047: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)data.player != (Object)(object)damage.DamagingPlayer) && !BloodlustStats.DisableDamageGain) { float num = Mathf.Min(((Vector2)(ref damage.Damage)).magnitude, damage.HurtPlayer.data.maxHealth) / damage.HurtPlayer.data.maxHealth; float num2 = 100f * num * BloodlustStats.BloodFillPerDamage; float num3 = num * BloodlustStats.DamageMultiplierFromDamage; decayingPrecentageDamage += num3; ReaperStats.ScalingPercentageDamageUnCap += num3; appliedScaling += num3; if (BloodlustStats.Blood < 0f) { BloodlustStats.Blood = 0f; } BloodlustStats.Blood = Mathf.Min(BloodlustStats.MaxBlood, BloodlustStats.Blood + num2); LoggerUtils.LogInfo($"Gained {num2} blood from damage, now at {BloodlustStats.Blood}/{BloodlustStats.MaxBlood}", false); } } private void OnRevive() { BloodlustStats.Blood = BloodlustStats.StartingBlood; ReaperStats.ScalingPercentageDamageUnCap -= appliedScaling; appliedScaling = 0f; decayingPrecentageDamage = 0f; LoggerUtils.LogInfo($"Reset \"blood\" value to {BloodlustStats.Blood}, and \"decayingPrecentageDamage\" to {decayingPrecentageDamage}", false); } private CustomHealthBar CreateStoredDamageBar() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //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) GameObject val = new GameObject("Blood Bar"); CustomHealthBar obj = val.AddComponent<CustomHealthBar>(); obj.SetColor(new Color(0.66156864f, 0.043137256f, 0.043137256f, 1f) * 0.8f); ExtensionMethods.AddStatusIndicator(data.player, val, 0f, true); Object.Destroy((Object)(object)((Component)val.transform.Find("Healthbar(Clone)/Canvas/Image/White")).gameObject); LoggerUtils.LogInfo("Created a blood bar", false); return obj; } private float DecayValue(float value) { return Mathf.Max(0f, value / (1f + 2f * value * Time.deltaTime)); } private void UpdateBloodState() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_005c: 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) if (BloodlustStats.Blood <= 0f) { float num = data.maxHealth * ((0f - BloodlustStats.Blood) * BloodlustStats.DamageFromNoBlood); data.healthHandler.DoDamage(Vector2.down * num * Time.deltaTime, Vector2.zero, Color.red * 0.6f, (GameObject)null, (Player)null, false, true, true); } else if (BloodlustStats.Blood > 0f && data.health < data.maxHealth) { float num2 = data.maxHealth * BloodlustStats.BloodHealthRegenRate; data.healthHandler.Heal(num2 * Time.deltaTime); } } private void Update() { if ((bool)ExtensionMethods.GetFieldValue((object)data.playerVel, "simulated")) { float num = decayingPrecentageDamage; decayingPrecentageDamage = DecayValue(decayingPrecentageDamage); float num2 = decayingPrecentageDamage - num; ReaperStats.ScalingPercentageDamageUnCap += num2; appliedScaling += num2; if (data.health < data.maxHealth) { BloodlustStats.ToggleBloodDrain("Regen", toggle: true); } else { BloodlustStats.ToggleBloodDrain("Regen", toggle: false); } BloodlustStats.Blood -= BloodlustStats.GetBloodDrain() * Time.deltaTime; UpdateBloodState(); } bloodBar.SetValues(BloodlustStats.Blood, BloodlustStats.MaxBlood); } private void Start() { data = ((Component)this).GetComponentInParent<CharacterData>(); bloodBar = CreateStoredDamageBar(); HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(OnRevive)); DamageEventHandler.Instance.RegisterDamageEventForOtherPlayers((object)this, data.player); } private void OnDestroy() { Object.Destroy((Object)(object)((Component)bloodBar).gameObject); CharacterDataExtensions.GetCustomStatsRegistry(data).GetOrCreate<ReaperStats>().ScalingPercentageDamageUnCap -= appliedScaling; HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Remove(healthHandler.reviveAction, new Action(OnRevive)); DamageEventHandler.Instance.UnregisterDamageEvent((object)this, data.player); } } public class BloodTranscendenceBehaviour : MonoBehaviour { public const string BLOOD_TRANSCENDENCE_KEY = "BloodTranscendence"; public const string BLOOD_TRANSCENDENCE_ACTIVATE_KEY = "BloodTranscendenceActivate"; public const string BLOOD_TRANSCENDENCE_DEACTIVATE_KEY = "BloodTranscendenceDeactivate"; [Header("Effect Objects")] public ParticleSystem Effect; [Header("Settings")] public float SecondsOfInvincibilityAtFullBlood = 5f; public float PrecentageBloodInvincibilityStop = 0.1f; public float CooldownTime = 10f; private CharacterData data; private ChildRPC rpc; private bool hasTrigger; private float lastTriggerTime; public BloodlustStats BloodlustStats => CharacterDataExtensions.GetCustomStatsRegistry(data).GetOrCreate<BloodlustStats>(); public void Trigger() { float num = 100f * PrecentageBloodInvincibilityStop; if (data.view.IsMine && BloodlustStats.Blood > num && !hasTrigger && Time.time > lastTriggerTime + CooldownTime) { rpc.CallFunction("BloodTranscendenceActivate"); } } private void RPCA_Activate() { if (!hasTrigger) { float amount = 100f * (1f - PrecentageBloodInvincibilityStop) / SecondsOfInvincibilityAtFullBlood; BloodlustStats.AddBloodDrain("BloodTranscendence", amount); BloodlustStats.DisableDamageGain = true; ClassesStats.MakeInvulnerable(data.player); Effect.Play(); hasTrigger = true; LoggerUtils.LogInfo("\"BloodTranscendence\" has been activated", false); } } private void RPCA_Deactivate() { if (hasTrigger) { _ = 100f * PrecentageBloodInvincibilityStop / SecondsOfInvincibilityAtFullBlood; BloodlustStats.RemoveBloodDrain("BloodTranscendence"); BloodlustStats.DisableDamageGain = false; ClassesStats.MakeVulnerable(data.player); Effect.Stop(); hasTrigger = false; LoggerUtils.LogInfo("\"BloodTranscendence\" has been deactivated", false); } } private void OnRevive() { if (hasTrigger) { RPCA_Deactivate(); } } private void Update() { float num = 100f * PrecentageBloodInvincibilityStop; if (data.view.IsMine && BloodlustStats.Blood < num && hasTrigger) { rpc.CallFunction("BloodTranscendenceDeactivate"); } } private void Start() { data = ((Component)this).GetComponentInParent<CharacterData>(); rpc = ((Component)this).GetComponentInParent<ChildRPC>(); rpc.childRPCs.Add("BloodTranscendenceActivate", RPCA_Activate); rpc.childRPCs.Add("BloodTranscendenceDeactivate", RPCA_Deactivate); HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(OnRevive)); } private void OnDestroy() { rpc.childRPCs.Remove("BloodTranscendenceActivate"); rpc.childRPCs.Remove("BloodTranscendenceDeactivate"); HealthHandler healthHandler = data.healthHandler; healthHandler.reviveAction = (Action)Delegate.Remove(healthHandler.reviveAction, new Action(OnRevive)); } } [RequireComponent(typeof(AttackLevel))] public class BloodTransfusionBehaviour : MonoBehaviour, IOnDoDamageEvent { [Header("Particles")] public ParticleSystem ParticleSystem; public int ParticlesEmitCount; [Header("Parameters")] public float HealFromDamageMultiplier = 0.25f; public float Radius = 10f; private CharacterData data; private AttackLevel attackLevel; public float CalculateScaledValue(float value, float maxValue, float scalingRange) { float num = value / scalingRange; return Mathf.Clamp((num * (0f - num) * num + 1f) * maxValue, 0f, maxValue); } public void OnDamage(DamageInfo damage) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) float scalingRange = Radius * ((Component)this).transform.localScale.x; float num = ((Vector2)(ref damage.Damage)).magnitude * (HealFromDamageMultiplier * (float)attackLevel.attackLevel); float value = Vector3.Distance(((Component)data).transform.position, ((Component)damage.HurtPlayer).transform.position); float num2 = CalculateScaledValue(value, num, scalingRange); float num3 = num2 / num; int num4 = (int)((float)ParticlesEmitCount * num3); data.healthHandler.Heal(num2); ParticleSystem.Emit(num4); } private void Start() { data = ((Component)this).GetComponentInParent<CharacterData>(); attackLevel = ((Component)this).GetComponent<AttackLevel>(); DamageEventHandler.Instance.RegisterDamageEventForOtherPlayers((object)this, data.player); } private void OnDestroy() { DamageEventHandler.Instance.UnregisterDamageEvent((object)this, data.player); } } public class GrimFateBehaviour : MonoBehaviour, IBattleStartHookHandler { public GameObject GrimFateDeathEffect; private CharacterData data; private bool alreadyTrigger; private void OnDeath() { if (!alreadyTrigger) { GameObject oldDeathEffect = data.healthHandler.deathEffectPhoenix; data.healthHandler.deathEffectPhoenix = GrimFateDeathEffect; ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)AAC_Core.Instance, 1, (Action)delegate { data.healthHandler.deathEffectPhoenix = oldDeathEffect; }); alreadyTrigger = true; } } public void OnBattleStart() { alreadyTrigger = false; } private void Start() { data = ((Component)this).GetComponentInParent<CharacterData>(); DeathActionHandler.Instance.RegisterReviveAction(data.player, (Action)OnDeath); InterfaceGameModeHooksManager.instance.RegisterHooks((object)this); } private void OnDestroy() { DeathActionHandler.Instance.DeregisterReviveAction(data.player, (Action)OnDeath); InterfaceGameModeHooksManager.instance.RemoveHooks((object)this); } } public class PercentDamageExplosion : MonoBehaviour { [Header("Settings")] public float PercentDamage = 0.45f; public float Ranage = 10f; [Header("Scales")] public bool ScaleWithLevel; [Header("Trigger")] public bool TriggerOnAwake; public GameObject PlayerDamageEffect; private AttackLevel attackLevel; private SpawnedAttack spawnedAttack; public float CalculateScaledValue(float value, float maxValue, float scalingRange) { float num = value / scalingRange; return Mathf.Clamp((num * (0f - num) * num + 1f) * maxValue, 0f, maxValue); } public void Trigger(Player player) { //IL_000c: 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) //IL_006d: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) float scalingRange = Ranage * ((Component)this).transform.localScale.x; float num = PercentDamage; if (ScaleWithLevel && (Object)(object)attackLevel != (Object)null) { num *= (float)attackLevel.attackLevel; } foreach (Player enemyPlayer in PlayerStatus.GetEnemyPlayers(player)) { if (PlayerManager.instance.CanSeePlayer(Vector2.op_Implicit(((Component)this).transform.position), enemyPlayer).canSee) { float value = Vector2.Distance(Vector2.op_Implicit(((Component)this).transform.position), Vector2.op_Implicit(((Component)enemyPlayer).transform.position)); float maxValue = enemyPlayer.data.maxHealth * num; float num2 = CalculateScaledValue(value, maxValue, scalingRange); if (num2 > 0f) { Vector3 val = ((Component)enemyPlayer).transform.position - ((Component)this).transform.position; Vector2 val2 = Vector2.op_Implicit(((Vector3)(ref val)).normalized) * num2; ((Damagable)enemyPlayer.data.healthHandler).CallTakeDamage(val2, Vector2.op_Implicit(((Component)this).transform.position), (GameObject)null, player, true); SpawnPlayerDamageEffect(enemyPlayer); } } } } public void Trigger() { if ((Object)(object)spawnedAttack != (Object)null && spawnedAttack.IsMine()) { Trigger(spawnedAttack.spawner); } } private void SpawnPlayerDamageEffect(Player player) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //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_0059: 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_0061: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)PlayerDamageEffect == (Object)null)) { GameObject val = Object.Instantiate<GameObject>(PlayerDamageEffect, ((Component)this).transform); val.transform.position = ((Component)player).transform.position; val.SetActive(true); Vector3 val2 = ((Component)player).transform.position - ((Component)this).transform.position; Vector3 normalized = ((Vector3)(ref val2)).normalized; if (normalized != Vector3.zero) { val.transform.rotation = Quaternion.LookRotation(normalized); } } } private void Start() { spawnedAttack = ((Component)this).GetComponent<SpawnedAttack>(); attackLevel = ((Component)this).GetComponent<AttackLevel>(); if ((Object)(object)PlayerDamageEffect != (Object)null) { PlayerDamageEffect.SetActive(false); } } private void Awake() { if (TriggerOnAwake) { ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)this, 1, (Action)delegate { Trigger(); }); } } private void OnDrawGizmosSelected() { //IL_0000: 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_0021: Unknown result type (might be due to invalid IL or missing references) Gizmos.color = Color.red; Gizmos.DrawWireSphere(((Component)this).transform.position, Ranage * ((Component)this).transform.localScale.x); } } } namespace AALUND13Cards.Classes.MonoBehaviours.CardsEffects.ExoArmor { public class ExoArmorDamageReductionAdder : MonoBehaviour { public float DamageReduction; private ArmorHandler armorHandler; private float addedArmorDamageReduction; private void Awake() { armorHandler = ((Component)this).GetComponentInParent<ArmorHandler>(); float armorDamageReduction = ((AALUND13Cards.Classes.Armors.ExoArmor)(object)armorHandler.GetArmorByType<AALUND13Cards.Classes.Armors.ExoArmor>()).ArmorDamageReduction; if (addedArmorDamageReduction > 0f) { addedArmorDamageReduction = Mathf.Max(Mathf.Min(armorDamageReduction + DamageReduction, 0.8f) - armorDamageReduction, 0f); } else { addedArmorDamageReduction = DamageReduction; } ((AALUND13Cards.Classes.Armors.ExoArmor)(object)armorHandler.GetArmorByType<AALUND13Cards.Classes.Armors.ExoArmor>()).ArmorDamageReduction += addedArmorDamageReduction; } private void OnDestroy() { ((AALUND13Cards.Classes.Armors.ExoArmor)(object)armorHandler.GetArmorByType<AALUND13Cards.Classes.Armors.ExoArmor>()).ArmorDamageReduction -= addedArmorDamageReduction; } } public class ExoArmorReflectChanceAdder : MonoBehaviour { public float ReflectChance; private ArmorHandler armorHandler; private float addedArmorReflectChance; private void Awake() { armorHandler = ((Component)this).GetComponentInParent<ArmorHandler>(); AALUND13Cards.Classes.Armors.ExoArmor exoArmor = (AALUND13Cards.Classes.Armors.ExoArmor)(object)armorHandler.GetArmorByType<AALUND13Cards.Classes.Armors.ExoArmor>(); addedArmorReflectChance = Mathf.Max(Mathf.Min(exoArmor.ReflectChance + ReflectChance, 0.8f) - exoArmor.ReflectChance, 0f); exoArmor.ReflectChance += addedArmorReflectChance; } private void OnDestroy() { ((AALUND13Cards.Classes.Armors.ExoArmor)(object)armorHandler.GetArmorByType<AALUND13Cards.Classes.Armors.ExoArmor>()).ReflectChance -= addedArmorReflectChance; } } public class ExoArmorSpawnDamageEffect : MonoBehaviour { private DamageSpawnObjects damageSpawnObjects; private ArmorHandler armorHandler; private void Awake() { damageSpawnObjects = ((Component)this).GetComponent<DamageSpawnObjects>(); armorHandler = ((Component)this).GetComponentInParent<ArmorHandler>(); AALUND13Cards.Classes.Armors.ExoArmor obj = (AALUND13Cards.Classes.Armors.ExoArmor)(object)armorHandler.GetArmorByType<AALUND13Cards.Classes.Armors.ExoArmor>(); obj.OnArmorDamaged = (Action<float>)Delegate.Combine(obj.OnArmorDamaged, new Action<float>(OnArmorDamaged)); } private void OnDestroy() { AALUND13Cards.Classes.Armors.ExoArmor obj = (AALUND13Cards.Classes.Armors.ExoArmor)(object)armorHandler.GetArmorByType<AALUND13Cards.Classes.Armors.ExoArmor>(); obj.OnArmorDamaged = (Action<float>)Delegate.Remove(obj.OnArmorDamaged, new Action<float>(OnArmorDamaged)); } private void OnArmorDamaged(float damage) { //IL_0006: 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) damageSpawnObjects.SpawnDamage(Vector2.up * damage); } } } namespace AALUND13Cards.Classes.Cards { public class BloodlustStats : ICustomStats { private struct BloodDrain { public float Drain; public bool Enable; public BloodDrain(float drain) : this(drain, toggle: true) { } public BloodDrain(float drain, bool toggle) { Drain = drain; Enable = toggle; } public BloodDrain ToggleDrain(bool toggle) { Enable = toggle; return this; } public static BloodDrain operator +(BloodDrain left, float right) { return new BloodDrain(left.Drain + right, left.Enable); } public static BloodDrain operator -(BloodDrain left, float right) { return new BloodDrain(left.Drain - right, left.Enable); } } public float MaxBlood; public float StartingBlood; public float Blood; public float BloodDrainRate; public float BloodHealthRegenRate; private Dictionary<string, BloodDrain> drainRate = new Dictionary<string, BloodDrain>(); public float BloodFillPerDamage; public float DamageMultiplierFromDamage; public float DamageFromNoBlood; public bool DisableDamageGain; public void ResetStats() { MaxBlood = 0f; StartingBlood = 0f; Blood = 0f; BloodDrainRate = 0f; BloodHealthRegenRate = 0f; drainRate.Clear(); BloodFillPerDamage = 0f; DamageMultiplierFromDamage = 0f; DamageFromNoBlood = 0f; DisableDamageGain = false; } public float GetBloodDrain(string key) { if (drainRate.ContainsKey(key)) { return drainRate[key].Drain; } return 0f; } public float GetBloodDrain() { float num = BloodDrainRate; foreach (BloodDrain item in drainRate.Values.Where((BloodDrain d) => d.Enable)) { num += item.Drain; } return num; } public void RemoveBloodDrain(string key) { if (drainRate.ContainsKey(key)) { drainRate.Remove(key); } } public void RemoveBloodDrain(string key, float amount) { if (drainRate.ContainsKey(key)) { drainRate[key] -= amount; if (drainRate[key].Drain <= 0f) { drainRate.Remove(key); } } } public void AddBloodDrain(string key, float amount) { if (!drainRate.ContainsKey(key)) { drainRate.Add(key, new BloodDrain(amount)); } else { drainRate[key] += amount; } } public void ToggleBloodDrain(string key, bool toggle) { if (drainRate.ContainsKey(key)) { drainRate[key] = drainRate[key].ToggleDrain(toggle); } } } public class ClassesStats : ICustomStats { private static readonly Color DarkenColor = new Color(0.75f, 0.75f, 0.75f, 1f); public float DamageResistance; private bool invulnerable; public bool Invulnerable => invulnerable; public static void MakeInvulnerable(Player player) { //IL_004f: 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_007b: 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) if (!((Object)(object)player == (Object)null) && !CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ClassesStats>().invulnerable) { CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ClassesStats>().invulnerable = true; Image val = ((Component)player).GetComponentInChildren<HealthBar>()?.hp; ((Graphic)val).color = new Color(((Graphic)val).color.r * DarkenColor.r, ((Graphic)val).color.g * DarkenColor.g, ((Graphic)val).color.b * DarkenColor.b, ((Graphic)val).color.a); } } public static void MakeVulnerable(Player player) { //IL_004f: 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_007b: 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) if (!((Object)(object)player == (Object)null) && CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ClassesStats>().invulnerable) { CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ClassesStats>().invulnerable = false; Image val = ((Component)player).GetComponentInChildren<HealthBar>()?.hp; ((Graphic)val).color = new Color(((Graphic)val).color.r / DarkenColor.r, ((Graphic)val).color.g / DarkenColor.g, ((Graphic)val).color.b / DarkenColor.b, ((Graphic)val).color.a); } } public void ResetStats() { DamageResistance = 0f; if (!invulnerable) { return; } foreach (CharacterData item in PlayerManager.instance.players.Select((Player p) => p.data)) { if (CharacterDataExtensions.GetCustomStatsRegistry(item).Get<ClassesStats>() == this) { MakeVulnerable(item.player); } } } } public class RailgunStats : ICustomStats { public struct RailgunChargeStats { public float ChargeDamageMultiplier; public float ChargeBulletSpeedMultiplier; public RailgunChargeStats(float chargeDamageMultiplier, float chargeBulletSpeedMultiplier) { ChargeDamageMultiplier = chargeDamageMultiplier; ChargeBulletSpeedMultiplier = chargeBulletSpeedMultiplier; } } public bool IsEnabled; public bool AllowOvercharge; public float MaximumCharge; public float CurrentCharge; public float ChargeRate; public float FullChargeThreshold = 20f; public float RailgunDamageMultiplier = 1f; public float RailgunBulletSpeedMultiplier = 1f; public float RailgunMinimumChargeDamageMultiplier = 0.25f; public float RailgunMinimumChargeBulletSpeedMultiplier = 0.5f; public RailgunChargeStats GetChargeStats(float charge) { float num = charge; num = (AllowOvercharge ? (num / 2f) : Mathf.Min(num, FullChargeThreshold)); float num2 = num / FullChargeThreshold; float chargeDamageMultiplier = RailgunMinimumChargeDamageMultiplier + (RailgunDamageMultiplier - RailgunMinimumChargeDamageMultiplier) * num2; float chargeBulletSpeedMultiplier = RailgunMinimumChargeBulletSpeedMultiplier + (RailgunBulletSpeedMultiplier - RailgunMinimumChargeBulletSpeedMultiplier) * num2; return new RailgunChargeStats(chargeDamageMultiplier, chargeBulletSpeedMultiplier); } public void UseCharge(RailgunStats stats) { if (AllowOvercharge) { CurrentCharge = 0f; } else { CurrentCharge = Mathf.Max(CurrentCharge - FullChargeThreshold, 0f); } AllowOvercharge = false; } public void ResetStats() { IsEnabled = false; AllowOvercharge = false; MaximumCharge = 0f; CurrentCharge = 0f; ChargeRate = 0f; FullChargeThreshold = 20f; RailgunDamageMultiplier = 1f; RailgunBulletSpeedMultiplier = 1f; RailgunMinimumChargeDamageMultiplier = 0.25f; RailgunMinimumChargeBulletSpeedMultiplier = 0.5f; } } public class ReaperStats : ICustomStats { public float ScalingPercentageDamage; public float ScalingPercentageDamageUnCap; public float ScalingPercentageDamageCap; public void ResetStats() { ScalingPercentageDamage = 0f; ScalingPercentageDamageUnCap = 0f; ScalingPercentageDamageCap = 0f; } } public class SoulStreakStats : ICustomStats { public float MaxHealth = 1f; public float PlayerSize = 1f; public float MovementSpeed = 1f; public float AttackSpeed = 1f; public float Damage = 1f; public float BulletSpeed = 1f; public float SoulArmorPercentage; public float SoulArmorPercentageRegenRate; public float SoulDrainDPSFactor; public float SoulDrainPercentageDPSFactor; public float SoulDrainLifestealMultiply; public float BurstDamageMultiplier; public float DamageStorage; public float DamageResistancePerKill; public Dictionary<Type, ISoulstreakAbility> AbilitiesMap = new Dictionary<Type, ISoulstreakAbility>(); public uint Souls; public ReadOnlyCollection<ISoulstreakAbility> Abilities => AbilitiesMap.Values.ToList().AsReadOnly(); public TAbility AddAbility<TAbility>(TAbility soulstreakAbility) where TAbility : SoulstreakAbility<TAbility> { AddAbilityRaw(soulstreakAbility); soulstreakAbility.SoulstreakStats = this; return soulstreakAbility; } public TAbility AddAbilityRaw<TAbility>(TAbility soulstreakAbility) where TAbility : ISoulstreakAbility { if (AbilitiesMap.TryGetValue(soulstreakAbility.GetType(), out var value) && value is TAbility) { return (TAbility)value; } AbilitiesMap.Add(soulstreakAbility.GetType(), soulstreakAbility); return soulstreakAbility; } public TAbility GetAbility<TAbility>() where TAbility : SoulstreakAbility<TAbility> { if (AbilitiesMap.TryGetValue(typeof(TAbility), out var value)) { return (TAbility)value; } return null; } public void ResetStats() { MaxHealth = 1f; PlayerSize = 1f; MovementSpeed = 1f; AttackSpeed = 1f; Damage = 1f; BulletSpeed = 1f; SoulArmorPercentage = 0f; SoulArmorPercentageRegenRate = 0f; SoulDrainDPSFactor = 0f; SoulDrainPercentageDPSFactor = 0f; SoulDrainLifestealMultiply = 0f; DamageResistancePerKill = 0f; AbilitiesMap.Clear(); } } } namespace AALUND13Cards.Classes.Cards.StatModifers { public class BloodlustStatModifers : CustomStatModifers { [Header("Blood Values")] public float MaxBlood; public float StartingBlood; [Header("Blood Healing/Draining")] public float BloodDrainRate; public float BloodDrainRateWhenRegen; public float BloodHealthRegenRate; [Header("Blood Damage")] public float DamageFromNoBlood; public float BloodFillPerDamage; public float DamageMultiplierFromDamage; public override void Apply(Player player) { BloodlustStats orCreate = CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<BloodlustStats>(); orCreate.MaxBlood = Mathf.Max(orCreate.MaxBlood + MaxBlood, 0f); orCreate.StartingBlood = Mathf.Max(orCreate.StartingBlood + StartingBlood, 0f); orCreate.BloodDrainRate = Mathf.Max(orCreate.BloodDrainRate + BloodDrainRate, 0f); orCreate.BloodHealthRegenRate = Mathf.Max(orCreate.BloodHealthRegenRate + BloodHealthRegenRate, 0f); if (BloodDrainRateWhenRegen > 0f) { orCreate.AddBloodDrain("Regen", BloodDrainRateWhenRegen); } else if (BloodDrainRateWhenRegen < 0f) { orCreate.RemoveBloodDrain("Regen", BloodDrainRateWhenRegen); } orCreate.DamageFromNoBlood = Mathf.Max(orCreate.DamageFromNoBlood + DamageFromNoBlood, 0f); orCreate.BloodFillPerDamage = Mathf.Max(orCreate.BloodFillPerDamage + BloodFillPerDamage, 0f); orCreate.DamageMultiplierFromDamage = Mathf.Max(orCreate.DamageMultiplierFromDamage + DamageMultiplierFromDamage, 0f); } } public class RailgunStatModifers : CustomStatModifers { [Header("Railgun Stats Add")] public float MaximumCharge; public float ChargeRate; [Header("Railgun Stats Multiplier")] public float MaximumChargeMultiplier = 1f; public float ChargeRateMultiplier = 1f; public float RailgunDamageMultiplier = 1f; public float RailgunBulletSpeedMultiplier = 1f; public override void Apply(Player player) { RailgunStats orCreate = CharacterDataExtensions.GetAdditionalData(player.data).CustomStatsRegistry.GetOrCreate<RailgunStats>(); orCreate.MaximumCharge = Mathf.Max(orCreate.MaximumCharge + MaximumCharge, 0f); orCreate.ChargeRate = Mathf.Max(orCreate.ChargeRate + ChargeRate, 0f); orCreate.MaximumCharge *= MaximumChargeMultiplier; orCreate.ChargeRate *= ChargeRateMultiplier; orCreate.RailgunDamageMultiplier += RailgunDamageMultiplier - 1f; orCreate.RailgunBulletSpeedMultiplier += RailgunBulletSpeedMultiplier - 1f; } } public class ReaperStatModifers : CustomStatModifers { [Header("Percentage Damage")] public float ScalingPercentageDamage; public float ScalingPercentageDamageCap; public override void Apply(Player player) { ReaperStats orCreate = CharacterDataExtensions.GetAdditionalData(player.data).CustomStatsRegistry.GetOrCreate<ReaperStats>(); orCreate.ScalingPercentageDamageCap += ScalingPercentageDamageCap; orCreate.ScalingPercentageDamage += ScalingPercentageDamage; } } [Flags] public enum AbilityType { Armor = 1 } public class SoulstreakStatModifers : CustomStatModifers { [Header("Character Stats")] public float MaxHealth; public float PlayerSize; public float MovementSpeed; [Header("Gun Stats")] public float AttackSpeed; public float Damage; public float BulletSpeed; [Header("Soul Armor")] public float SoulArmorPercentage; public float SoulArmorPercentageRegenRate; [Header("Soul Drain")] public float SoulDrainDamageMultiply; public float SoulDrainPercentageDPSFactor; public float SoulDrainLifestealMultiply; [Header("Dreadful Burst")] public float BurstDamageMultiplier; public float DamageStorage; [Header("Damage Resistance Per Kill")] public float DamageResistancePerKill; [Header("Abilities")] public AbilityType AbilityType; public override void Apply(Player player) { SoulStreakStats orCreate = CharacterDataExtensions.GetAdditionalData(player.data).CustomStatsRegistry.GetOrCreate<SoulStreakStats>(); orCreate.MaxHealth += MaxHealth; orCreate.PlayerSize += PlayerSize; orCreate.MovementSpeed += MovementSpeed; orCreate.AttackSpeed += AttackSpeed; orCreate.Damage += Damage; orCreate.BulletSpeed += BulletSpeed; orCreate.SoulArmorPercentage += SoulArmorPercentage; orCreate.SoulArmorPercentageRegenRate += SoulArmorPercentageRegenRate; orCreate.SoulDrainDPSFactor += SoulDrainDamageMultiply; orCreate.SoulDrainPercentageDPSFactor += SoulDrainPercentageDPSFactor; orCreate.SoulDrainLifestealMultiply += SoulDrainLifestealMultiply; orCreate.BurstDamageMultiplier += BurstDamageMultiplier; orCreate.DamageStorage += DamageStorage; if ((AbilityType & AbilityType.Armor) == AbilityType.Armor) { orCreate.AddAbility(new ArmorAbility(player, 10f)); } if (DamageResistancePerKill != 0f) { orCreate.AddAbility(new SoulstealerResistanceAbiilty(player)); orCreate.DamageResistancePerKill += DamageResistancePerKill; } } } } namespace AALUND13Cards.Classes.Cards.Conditions { public class MentPercentageDamageCondition : CardCondition { public override bool IsPlayerAllowedCard(Player player) { return CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ReaperStats>().ScalingPercentageDamage < CharacterDataExtensions.GetCustomStatsRegistry(player.data).GetOrCreate<ReaperStats>().ScalingPercentageDamageCap; } } } namespace AALUND13Cards.Classes.Armors { public class ExoArmor : ArmorBase { private static Dictionary<Player, bool[]> ReflectChances = new Dictionary<Player, bool[]>(); private static Dictionary<Player, int> ReflectIndex = new Dictionary<Player, int>(); public Action<float> OnArmorDamaged; public float ArmorDamageReduction; public float ReflectChance; private float queuedDamage; 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) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return new BarColor(Color.cyan * 0.6f, Color.cyan * 0.45f); } public override DamageArmorInfo OnDamage(float damage, Player DamagingPlayer, ArmorDamagePatchType? armorDamagePatchType) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) queuedDamage += damage; float num = damage * (1f - ArmorDamageReduction); return ((ArmorBase)this).OnDamage(num, DamagingPlayer, armorDamagePatchType); } public override void OnUpdate() { if (queuedDamage > 0f) { OnArmorDamaged?.Invoke(queuedDamage); queuedDamage = 0f; } } public override void OnRespawn() { queuedDamage = 0f; if (PhotonNetwork.IsMasterClient) { bool[] array = new bool[10000]; for (int i = 0; i < 10000; i++) { array[i] = Random.value < ReflectChance; } NetworkingManager.RPC(typeof(ExoArmor), "ArmorReflectOddsRPCA", new object[2] { ((ArmorBase)this).ArmorHandler.Player.playerID, array }); } } public bool Reflect(float bulletDmage) { if (ReflectIndex.TryGetValue(((ArmorBase)this).ArmorHandler.Player, out var value) && value < 10000) { ((ArmorBase)this).DamageArmor(bulletDmage / 2f); ReflectIndex[((ArmorBase)this).ArmorHandler.Player]++; return ReflectChances[((ArmorBase)this).ArmorHandler.Player][value]; } return false; } public ExoArmor() { base.ArmorTags.Add("CanArmorPierce"); } [UnboundRPC] public static void ArmorReflectOddsRPCA(int playerId, bool[] bools) { Player key = PlayerManager.instance.players.Find((Player p) => p.playerID == playerId); _ = (ExoArmor)(object)ArmorFramework.ArmorHandlers[key].GetArmorByType<ExoArmor>(); if (!ReflectChances.ContainsKey(key)) { ReflectChances.Add(key, bools); ReflectIndex.Add(key, 0); } else { ReflectChances[key] = bools; ReflectIndex[key] = 0; } } } public class SoulArmor : 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) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return new BarColor(Color.magenta * 0.6f, Color.magenta * 0.45f); } public SoulArmor() { base.ArmorRegenCooldownSeconds = 5f; } } } namespace AALUND13Cards.ExtraCards { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("AALUND13.Cards.Classes", "AALUND13 Classes Cards", "1.2.0")] [BepInProcess("Rounds.exe")] internal class AAC_Classes : BaseUnityPlugin { [CompilerGenerated] private sealed class <OnGameStart>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnGameStart>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; foreach (Player player in PlayerManager.instance.players) { CharacterDataExtensions.GetAdditionalData(player.data).CustomStatsRegistry.GetOrCreate<SoulStreakStats>().Souls = 0u; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal const string ModId = "AALUND13.Cards.Classes"; internal const string ModName = "AALUND13 Classes Cards"; internal const string Version = "1.2.0"; private static AssetBundle assets; private void Awake() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) assets = AssetsUtils.LoadAssetBundle("aac_classes_assets", typeof(AAC_Classes).Assembly); if ((Object)(object)assets != (Object)null) { new Harmony("AALUND13.Cards.Classes").PatchAll(); } } private void Start() { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown if ((Object)(object)assets == (Object)null) { Unbound.BuildModal("AALUND13 Cards Error", "The mod \"AALUND13 Classes Cards\" assets failled to load, All the cards will be disable in this mod"); throw new NullReferenceException("Failled to load \"AALUND13 Classes Cards\" assets"); } if (AAC_Core.Plugins.Exists((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == "com.willuwontu.rounds.tabinfo")) { TabinfoInterface.Setup(); } if (AAC_Core.Plugins.Exists((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == "AALUND13.Cards.Armors")) { ArmorInterface.RegisterArmors(); } CardResgester cardResgester = assets.LoadAsset<GameObject>("ClassesModCards").GetComponent<CardResgester>(); cardResgester.RegisterCards(); AACMenu.OnMenuRegister = (Action)Delegate.Combine(AACMenu.OnMenuRegister, (Action)delegate { AACMenu.CreateModuleMenuWithReadmeGenerator("AALUND13 Classes Cards", "1.2.0", cardResgester); }); DeathHandler.OnPlayerDeath += new DeathHandlerDelegate(OnPlayerDeath); GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)OnGameStart); } [IteratorStateMachine(typeof(<OnGameStart>d__6))] private IEnumerator OnGameStart(IGameModeHandler gameModeHandler) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnGameStart>d__6(0); } private void OnPlayerDeath(Player player, Dictionary<Player, DamageInfo> playerDamageInfos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<Player, DamageInfo> playerDamageInfo in playerDamageInfos) { if (playerDamageInfo.Value.TimeSinceLastDamage <= 5f && (Object)(object)((Component)playerDamageInfo.Key).GetComponentInChildren<SoulstreakMono>() != (Object)null && !playerDamageInfo.Key.data.dead) { ((Component)playerDamageInfo.Key).GetComponentInChildren<SoulstreakMono>().AddSouls(); if ((Object)(object)((Component)player).GetComponentInChildren<SoulstreakMono>() != (Object)null) { ((Component)playerDamageInfo.Key).GetComponentInChildren<SoulstreakMono>().AddSouls((uint)((float)CharacterDataExtensions.GetAdditionalData(player.data).CustomStatsRegistry.GetOrCreate<SoulStreakStats>().Souls * 0.25f)); } } } ((Component)player).GetComponentInChildren<SoulstreakMono>()?.ResetSouls(); } } internal class TabinfoInterface { public static void Setup() { StatCategory orCreateCategory = TabinfoInterface.GetOrCreateCategory("AA Stats", 6); TabInfoManager.RegisterStat(orCreateCategory, "Scaling Percentage Damage", (Func<Player, bool>)((Player p) => GetReaperStatsFromPlayer(p).ScalingPercentageDamage != 0f), (Func<Player, string>)((Player p) => $"{(Mathf.Min(GetReaperStatsFromPlayer(p).ScalingPercentageDamage, Mathf.Min(GetReaperStatsFromPlayer(p).ScalingPercentageDamageCap, 0.8f)) + GetReaperStatsFromPlayer(p).ScalingPercentageDamageUnCap) * 100f:0}%")); TabInfoManager.RegisterStat(orCreateCategory, "Effective Percentage Damage", (Func<Player, bool>)((Player p) => GetReaperStatsFromPlayer(p).ScalingPercentageDamage != 0f), (Func<Player, string>)((Player p) => $"{(MathUtils.GetEffectivePercentCap(PlayerExtensions.GetSPS(p), GetReaperStatsFromPlayer(p).ScalingPercentageDamage, GetReaperStatsFromPlayer(p).ScalingPercentageDamageCap) + MathUtils.GetEffectivePercent(PlayerExtensions.GetSPS(p), GetReaperStatsFromPlayer(p).ScalingPercentageDamageUnCap)) * 100f:0}%")); StatCategory obj = TabInfoManager.RegisterCategory("Soulstreak Stats", 7); TabInfoManager.RegisterStat(obj, "Max Health Per Kill", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).MaxHealth != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).MaxHealth * 100f:0}%")); TabInfoManager.RegisterStat(obj, "player Size Per Kill", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).PlayerSize != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).PlayerSize * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Movement Speed Per Kill", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).MovementSpeed != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).MovementSpeed * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Attack Speed Pre Kill", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).AttackSpeed != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).AttackSpeed * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Damage Per Kill", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).Damage != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).Damage * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Bullet Speed Per Kill", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).BulletSpeed != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).BulletSpeed * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Soul Armor Percentage", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).SoulArmorPercentage != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).SoulArmorPercentage * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Soul Armor Percentage Regen Rate", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).SoulArmorPercentageRegenRate != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).SoulArmorPercentageRegenRate * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Soul Drain DPS Factor", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).SoulDrainDPSFactor != 0f), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).SoulDrainDPSFactor * 100f:0}%")); TabInfoManager.RegisterStat(obj, "Souls", (Func<Player, bool>)((Player p) => (Object)(object)((Component)p).GetComponentInChildren<SoulstreakMono>() != (Object)null && GetSoulstreakStatsFromPlayer(p).Souls != 0), (Func<Player, string>)((Player p) => $"{GetSoulstreakStatsFromPlayer(p).Souls}")); StatCategory obj2 = TabInfoManager.RegisterCategory("Railgun Stats", 8); TabInfoManager.RegisterStat(obj2, "Charge", (Func<Player, bool>)((Player p) => GetRailgunStatsFromPlayer(p).IsEnabled && GetRailgunStatsFromPlayer(p).MaximumCharge != 0f), (Func<Player, string>)((Player p) => $"{GetRailgunStatsFromPlayer(p).CurrentCharge:0.00}/{GetRailgunStatsFromPlayer(p).MaximumCharge:0.00}")); TabInfoManager.RegisterStat(obj2, "Charge Rate", (Func<Player, bool>)((Player p) => GetRailgunStatsFromPlayer(p).IsEnabled && GetRailgunStatsFromPlayer(p).ChargeRate != 0f), (Func<Player, string>)((Player p) => $"{GetRailgunStatsFromPlayer(p).ChargeRate:0.00}/s")); TabInfoManager.RegisterStat(obj2, "Railgun Da