using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using UnboundLib; using UnboundLib.Cards; using UnboundLib.GameModes; using UnityEngine; using VeryBalancedRoundsMod.Cards; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VeryBalancedRoundsMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0+a1b07123181f770a5c072640b21e4b6f03dff04d")] [assembly: AssemblyProduct("VeryBalancedRoundsMod")] [assembly: AssemblyTitle("VeryBalancedRoundsMod")] [assembly: AssemblyVersion("0.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VeryBalancedRoundsMod { internal class InevitableRamp : MonoBehaviour { internal const float GrowthPerSecond = 0.02f; private CharacterData data; private bool wasPlaying; private float elapsed; private void Awake() { data = ((Component)this).GetComponent(); if ((Object)(object)data == (Object)null) { data = ((Component)this).GetComponentInParent(); } } private void Update() { if (!((Object)(object)data == (Object)null)) { bool flag = data.isPlaying && !data.dead; if (flag && !wasPlaying) { elapsed = 0f; } if (flag) { elapsed += Time.deltaTime; } wasPlaying = flag; } } internal void ResetRamp() { elapsed = 0f; } internal float GetMultiplier(int stacks) { return (stacks <= 0) ? 1f : Mathf.Pow(1.02f, elapsed * (float)stacks); } } internal class MahoragaAdaptation : MonoBehaviour { internal const float ReductionPerHit = 0.1f; private readonly Dictionary hitsByAttacker = new Dictionary(); internal float GetMultiplier(Player attacker, int stacks) { if ((Object)(object)attacker == (Object)null || stacks <= 0) { return 1f; } if (!hitsByAttacker.TryGetValue(attacker.playerID, out var value) || value <= 0) { return 1f; } return Mathf.Pow(0.9f, (float)(value * stacks)); } internal void RegisterHit(Player attacker) { if (!((Object)(object)attacker == (Object)null)) { hitsByAttacker.TryGetValue(attacker.playerID, out var value); hitsByAttacker[attacker.playerID] = value + 1; } } internal void ResetAdaptation() { hitsByAttacker.Clear(); } } internal static class CardNames { public const string GlassCannon = "Glass Cannon"; public const string McDonalds = "McDonalds"; public const string Gremlin = "Gremlin"; public const string BirdKiller = "Bird Killer"; public const string Inevitable = "Inevitable"; public const string BlockHater = "Ihateblockbuild"; public const string BlockLover = "Iloveblockbuild"; public const string Mahoraga = "Eight Handled Sword Divine General Mahoraga"; public const string TitanKiller = "Titan Killer"; public const string GlasserCannon = "Glasser Cannon"; public const string Balanced = "Balanced"; } internal static class CardTools { internal static int CountCards(Player player, string cardName) { if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null) { return 0; } List currentCards = player.data.currentCards; if (currentCards == null) { return 0; } int num = 0; for (int i = 0; i < currentCards.Count; i++) { if ((Object)(object)currentCards[i] != (Object)null && currentCards[i].cardName == cardName) { num++; } } return num; } internal static bool HasCard(Player player, string cardName) { return CountCards(player, cardName) > 0; } internal static bool IsHostile(Player attacker, Player victim) { return (Object)(object)attacker != (Object)null && (Object)(object)victim != (Object)null && attacker.playerID != victim.playerID; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("Rounds.exe")] [BepInPlugin("com.pengu.rounds.verybalancedroundsmod", "Very Balanced Rounds Mod", "0.2.0")] public class VeryBalancedPlugin : BaseUnityPlugin { private const string UnboundGuid = "com.willis.rounds.unbound"; public const string ModId = "com.pengu.rounds.verybalancedroundsmod"; public const string ModName = "Very Balanced Rounds Mod"; public const string Version = "0.2.0"; public const string ModInitials = "VB"; internal static VeryBalancedPlugin Instance { get; private set; } private void Awake() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) Instance = this; new Harmony("com.pengu.rounds.verybalancedroundsmod").PatchAll(); } private void Start() { RegisterCards(); GameModeManager.AddHook("PointStart", (Func)ResetPerPointState); Unbound.RegisterCredits("Very Balanced Rounds Mod", new string[1] { "Pengu" }, "GitHub", "https://github.com/"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Very Balanced Rounds Mod v0.2.0 loaded."); } internal static void RegisterCards() { CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); } private static IEnumerator ResetPerPointState(IGameModeHandler gameModeHandler) { InevitableRamp[] ramps = Object.FindObjectsOfType(); for (int i = 0; i < ramps.Length; i++) { ramps[i].ResetRamp(); } MahoragaAdaptation[] adaptations = Object.FindObjectsOfType(); for (int j = 0; j < adaptations.Length; j++) { adaptations[j].ResetAdaptation(); } yield break; } } } namespace VeryBalancedRoundsMod.Patches { [HarmonyPatch(typeof(Block), "blocked")] internal static class Block_Blocked_Patch { internal const float LeakFraction = 0.1f; private static void Postfix(Block __instance, GameObject projectile) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)projectile == (Object)null) { return; } ProjectileHit component = projectile.GetComponent(); if ((Object)(object)component == (Object)null) { return; } Player ownPlayer = component.ownPlayer; if ((Object)(object)ownPlayer == (Object)null) { return; } int num = CardTools.CountCards(ownPlayer, "Ihateblockbuild"); if (num <= 0) { return; } CharacterData component2 = ((Component)__instance).GetComponent(); if ((Object)(object)component2 == (Object)null || (Object)(object)component2.healthHandler == (Object)null || !CardTools.IsHostile(ownPlayer, component2.player)) { return; } float num2 = component.damage * 0.1f * (float)num; if (!(num2 <= 0f)) { Vector2 val = Vector2.op_Implicit(((Component)component2.player).transform.position); Vector2 val2 = val - Vector2.op_Implicit(projectile.transform.position); if (val2 == Vector2.zero) { val2 = Vector2.up; } ((Damagable)component2.healthHandler).TakeDamage(((Vector2)(ref val2)).normalized * num2, val, (GameObject)null, ownPlayer, true, true); } } } [HarmonyPatch(typeof(Block), "DoBlockAtPosition")] internal static class Block_DoBlockAtPosition_Patch { private static bool reentering; private static void Postfix(Block __instance, BlockTriggerType triggerType) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (reentering) { return; } CharacterData component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.player == (Object)null) { return; } int num = CardTools.CountCards(component.player, "Iloveblockbuild"); if (num <= 0) { return; } reentering = true; try { for (int i = 0; i < num; i++) { if (__instance.BlockAction != null) { __instance.BlockAction(triggerType); } } } finally { reentering = false; } } } [HarmonyPatch(typeof(HealthHandler), "DoDamage")] internal static class HealthHandler_DoDamage_Patch { private const int NoRespawnOverride = -1; private static void Prefix(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer, out int __state) { //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) __state = -1; CharacterData component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null) { return; } Player player = component.player; if (!CardTools.IsHostile(damagingPlayer, player)) { return; } int num = CardTools.CountCards(damagingPlayer, "Inevitable"); if (num > 0) { InevitableRamp component2 = ((Component)damagingPlayer).GetComponent(); if ((Object)(object)component2 != (Object)null) { damage *= component2.GetMultiplier(num); } } int num2 = CardTools.CountCards(player, "Eight Handled Sword Divine General Mahoraga"); if (num2 > 0) { MahoragaAdaptation component3 = ((Component)player).GetComponent(); if ((Object)(object)component3 != (Object)null) { damage *= component3.GetMultiplier(damagingPlayer, num2); component3.RegisterHit(damagingPlayer); } } if (CardTools.HasCard(damagingPlayer, "Bird Killer") && (Object)(object)component.stats != (Object)null && component.stats.remainingRespawns > 0) { __state = component.stats.remainingRespawns; component.stats.remainingRespawns = 0; } } private static void Postfix(HealthHandler __instance, int __state) { if (__state != -1) { CharacterData component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.stats != (Object)null) { component.stats.remainingRespawns = __state; } } } } } namespace VeryBalancedRoundsMod.Cards { public class BalancedCard : VeryBalancedCard { private const float BaseBulletDamage = 55f; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { float num = gun.damage * 55f; float num2 = (data.maxHealth + num) / 2f; if (!(num2 <= 0f)) { data.maxHealth = num2; if (data.health > data.maxHealth) { data.health = data.maxHealth; } gun.damage = num2 / 55f; } } protected override string GetTitle() { return "Balanced"; } protected override string GetDescription() { return "Health and damage meet in the middle. Nobody asked for this."; } protected override Rarity GetRarity() { return (Rarity)1; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)7; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { VeryBalancedCard.Stat("Health and damage", "averaged", positive: true, (SimpleAmount)0) }; } } public class BirdKillerCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = false; } protected override string GetTitle() { return "Bird Killer"; } protected override string GetDescription() { return "Kills made by your bullets stay dead. No rising from the ashes."; } protected override Rarity GetRarity() { return (Rarity)1; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)4; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { VeryBalancedCard.Stat("Your kills", "block Phoenix", positive: true, (SimpleAmount)0) }; } } public class BlockHaterCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = true; } protected override string GetTitle() { return "Ihateblockbuild"; } protected override string GetDescription() { return "Blocking your bullets is not free."; } protected override Rarity GetRarity() { return (Rarity)1; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)3; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { VeryBalancedCard.Stat("Blocked bullets", "deal 10% damage", positive: true, (SimpleAmount)1) }; } } public class BlockLoverCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = false; } protected override string GetTitle() { return "Iloveblockbuild"; } protected override string GetDescription() { return "Everything your block does, it does twice."; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)2; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { VeryBalancedCard.Stat("On block effects", "trigger twice", positive: true, (SimpleAmount)3) }; } } public class GlassCannonCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = false; gun.damage = 2f; statModifiers.health = 0.5f; } protected override string GetTitle() { return "Glass Cannon"; } protected override string GetDescription() { return "Hits like a truck. Folds like a napkin."; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)0; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { VeryBalancedCard.Stat("Damage", "+100%", positive: true, (SimpleAmount)3), VeryBalancedCard.Stat("Health", "-50%", positive: false, (SimpleAmount)7) }; } } public class GlasserCannonCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = false; gun.damage = 3f; statModifiers.health = 0.25f; } protected override string GetTitle() { return "Glasser Cannon"; } protected override string GetDescription() { return "The cannon got bigger. The glass got glassier."; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)0; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { VeryBalancedCard.Stat("Damage", "+200%", positive: true, (SimpleAmount)4), VeryBalancedCard.Stat("Health", "-75%", positive: false, (SimpleAmount)7) }; } } public class GremlinCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = true; statModifiers.sizeMultiplier = 0.7f; statModifiers.movementSpeed = 1.5f; } protected override string GetTitle() { return "Gremlin"; } protected override string GetDescription() { return "Small. Quick. Deeply annoying."; } protected override Rarity GetRarity() { return (Rarity)0; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)5; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { VeryBalancedCard.Stat("Movement speed", "+50%", positive: true, (SimpleAmount)3), VeryBalancedCard.Stat("Size", "-30%", positive: true, (SimpleAmount)9) }; } } public class InevitableCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if ((Object)(object)((Component)player).GetComponent() == (Object)null) { ((Component)player).gameObject.AddComponent(); } } protected override string GetTitle() { return "Inevitable"; } protected override string GetDescription() { return "Every second you are still standing, you hit harder."; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)0; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { VeryBalancedCard.Stat("Damage", "+2% per second", positive: true, (SimpleAmount)3), VeryBalancedCard.Stat("Resets", "every point", positive: false, (SimpleAmount)0) }; } } public class MahoragaCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if ((Object)(object)((Component)player).GetComponent() == (Object)null) { ((Component)player).gameObject.AddComponent(); } } protected override string GetTitle() { return "Eight Handled Sword Divine General Mahoraga"; } protected override string GetDescription() { return "It adapts. Every hit teaches you the shape of their attack."; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)8; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { VeryBalancedCard.Stat("Damage taken", "-10% per hit", positive: true, (SimpleAmount)6), VeryBalancedCard.Stat("Tracked", "per attacker", positive: true, (SimpleAmount)0) }; } } public class McDonaldsCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = true; statModifiers.health = 2f; statModifiers.movementSpeed = 0.5f; } protected override string GetTitle() { return "McDonalds"; } protected override string GetDescription() { return "You are what you eat. Twice as much of it."; } protected override Rarity GetRarity() { return (Rarity)0; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)2; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { VeryBalancedCard.Stat("Health", "+100%", positive: true, (SimpleAmount)3), VeryBalancedCard.Stat("Movement speed", "-50%", positive: false, (SimpleAmount)7) }; } } public class TitanKillerCard : VeryBalancedCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers) { cardInfo.allowMultiple = true; gun.percentageDamage = 0.05f; } protected override string GetTitle() { return "Titan Killer"; } protected override string GetDescription() { return "The bigger they are, the harder they get shot."; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)1; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { VeryBalancedCard.Stat("Bonus damage", "+5% of enemy max health", positive: true, (SimpleAmount)2) }; } } public abstract class VeryBalancedCard : CustomCard { public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } protected override GameObject GetCardArt() { return null; } public override string GetModName() { return "VB"; } protected static CardInfoStat Stat(string name, string amount, bool positive, SimpleAmount simple = (SimpleAmount)0) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown return new CardInfoStat { stat = name, amount = amount, positive = positive, simepleAmount = simple }; } } }