Decompiled source of ThemedMayhemCards v1.0.0
ThemedMayhemCards.dll
Decompiled 3 months 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.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Logging; using ThemedMayhem.Cards; using UnboundLib.Cards; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace ThemedMayhem { internal static class CardDatabase { internal static readonly CardDefinition[] All = new CardDefinition[100] { new CardDefinition(1, "Kinetic", "Railspike", "A brutal slow slug: enormous impact, reduced muzzle velocity.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+60%"), new StatLine(positive: true, "Knockback", "+50%"), new StatLine(positive: false, "Projectile speed", "-25%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.6f), new EffectOp(TargetKind.Gun, "Knockback", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.75f) }, new EffectRule[0]), new CardDefinition(2, "Kinetic", "Pinball Protocol", "Bullets gain three ricochets and accelerate after each bounce, but begin weaker.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Bounces", "+3"), new StatLine(positive: true, "Bounce speed", "+10% each"), new StatLine(positive: false, "Damage", "-20%") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Bounces", OpMode.Add, 3f), new EffectOp(TargetKind.Gun, "BounceSpeed", OpMode.Multiply, 1.1f), new EffectOp(TargetKind.Gun, "BounceDamage", OpMode.Multiply, 0.9f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(3, "Kinetic", "Recoil Reactor", "High-velocity rounds launch enemies—and you—into more chaotic engagements.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Projectile speed", "+45%"), new StatLine(positive: true, "Knockback", "+35%"), new StatLine(positive: false, "Movement speed", "-15%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.45f), new EffectOp(TargetKind.Gun, "Knockback", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(4, "Kinetic", "Scatter Crown", "Fire a five-round fan. Each pellet is much weaker and the weapon cycles slowly.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Projectiles", "+4"), new StatLine(positive: false, "Damage", "-55%"), new StatLine(positive: false, "Attack speed", "-30%") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Projectiles", OpMode.Add, 4f), new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 35f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.45f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 1.3f) }, new EffectRule[0]), new CardDefinition(5, "Kinetic", "Needle Storm", "Three tiny, hyper-fast needles replace each ordinary shot.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Projectiles", "+2"), new StatLine(positive: true, "Projectile speed", "+80%"), new StatLine(positive: false, "Projectile size", "-55%") }, new EffectOp[5] { new EffectOp(TargetKind.Gun, "Projectiles", OpMode.Add, 2f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.8f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 0.45f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 9f) }, new EffectRule[0]), new CardDefinition(6, "Kinetic", "Heavy Orbit", "Your rounds become slow orbiting wrecking balls with one ricochet.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+40%"), new StatLine(positive: true, "Projectile size", "+100%"), new StatLine(positive: true, "Bounces", "+1") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.4f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 2f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.5f), new EffectOp(TargetKind.Gun, "Bounces", OpMode.Add, 1f) }, new EffectRule[0]), new CardDefinition(7, "Kinetic", "Kinetic Battery", "Damage rises by 4% for every card already in your deck.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Damage", "+4% per card"), new StatLine(positive: false, "Reload time", "+15%") }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.MultiplyPerCard, 0.04f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.15f) }, new EffectRule[0]), new CardDefinition(8, "Kinetic", "Ricochet Dividend", "Add a ricochet, then gain 25% damage for every ricochet you already had.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Bounces", "+1"), new StatLine(positive: true, "Damage", "Scales with bounces") }, new EffectOp[1] { new EffectOp(TargetKind.Gun, "Bounces", OpMode.Add, 1f) }, new EffectRule[1] { EffectRule.Convert(new StatRef(TargetKind.Gun, "Bounces", 1f), new StatRef(TargetKind.Gun, "Damage", 1f), 0.25f) }), new CardDefinition(9, "Kinetic", "Zero-Point Kick", "Near-weightless movement and fast rounds at the cost of durability.", (Rarity)2, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Movement speed", "+30%"), new StatLine(positive: true, "Projectile speed", "+30%"), new StatLine(positive: false, "Health", "-20%") }, new EffectOp[4] { new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 0.4f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.3f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.3f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(10, "Kinetic", "Terminal Velocity", "Convert your existing projectile speed into extra damage, then accelerate again.", (Rarity)2, "DestructiveRed", allowMultiple: false, new StatLine[3] { new StatLine(positive: true, "Damage", "Scales with speed"), new StatLine(positive: true, "Projectile speed", "+35%"), new StatLine(positive: false, "Projectile size", "-25%") }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 0.75f) }, new EffectRule[1] { EffectRule.Convert(new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f), new StatRef(TargetKind.Gun, "Damage", 1f), 0.35f) }), new CardDefinition(11, "Temporal", "Split Second", "Fire dramatically faster, but each shot carries less force.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Attack speed", "+54%"), new StatLine(positive: false, "Damage", "-25%") }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.75f) }, new EffectRule[0]), new CardDefinition(12, "Temporal", "Borrowed Time", "Reload almost instantly by sacrificing a chamber and some health.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Reload speed", "+122%"), new StatLine(positive: false, "Ammo", "-1"), new StatLine(positive: false, "Health", "-15%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.45f), new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, -1f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(13, "Temporal", "Stasis Magazine", "A huge magazine of overcharged rounds, fired at a glacial pace.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Ammo", "+5"), new StatLine(positive: true, "Damage", "+20%"), new StatLine(positive: false, "Attack speed", "-41%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 5f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.2f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 1.7f) }, new EffectRule[0]), new CardDefinition(14, "Temporal", "Chrono Shield", "Block returns sooner, but carrying the time field slows you down.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Block cooldown", "-35%"), new StatLine(positive: false, "Movement speed", "-15%") }, new EffectOp[2] { new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(15, "Temporal", "Afterimage", "Become smaller and much faster, but easier to eliminate.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Movement speed", "+35%"), new StatLine(positive: true, "Size", "-20%"), new StatLine(positive: false, "Health", "-20%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 0.8f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(16, "Temporal", "The Long Now", "Trade immediate mobility for a massive reserve of future health.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Health", "+50%"), new StatLine(positive: false, "Movement speed", "-25%"), new StatLine(positive: false, "Reload speed", "-20%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.75f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.25f) }, new EffectRule[0]), new CardDefinition(17, "Temporal", "Time Dilation", "Slow, swollen projectiles hit far harder.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+60%"), new StatLine(positive: true, "Projectile size", "+40%"), new StatLine(positive: false, "Projectile speed", "-55%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.45f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.6f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 1.4f) }, new EffectRule[0]), new CardDefinition(18, "Temporal", "Fast Forward", "Accelerate movement, firing, reloads, and bullets; damage is compressed.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "All speed", "Faster"), new StatLine(positive: false, "Damage", "-30%") }, new EffectOp[5] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.75f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.75f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.7f) }, new EffectRule[0]), new CardDefinition(19, "Temporal", "Second Hand", "Gain another block charge, but both charges recover more slowly.", (Rarity)2, "TechWhite", allowMultiple: false, new StatLine[2] { new StatLine(positive: true, "Extra blocks", "+1"), new StatLine(positive: false, "Block cooldown", "+50%") }, new EffectOp[2] { new EffectOp(TargetKind.Block, "ExtraBlocks", OpMode.Add, 1f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 1.5f) }, new EffectRule[0]), new CardDefinition(20, "Temporal", "Paradox Engine", "Swap your attack interval and reload interval, then stabilize both extremes.", (Rarity)2, "TechWhite", allowMultiple: false, new StatLine[2] { new StatLine(positive: true, "Attack/reload", "Swapped"), new StatLine(positive: true, "Both intervals", "Capped") }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Max, 2.5f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Max, 2.5f) }, new EffectRule[1] { EffectRule.Swap(new StatRef(TargetKind.Gun, "AttackSpeed", 1f), new StatRef(TargetKind.Ammo, "ReloadTime", 1f)) }), new CardDefinition(21, "Elemental", "Ember Core", "Hotter rounds grow stronger and larger, but scorch their owner.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+35%"), new StatLine(positive: true, "Projectile size", "+15%"), new StatLine(positive: false, "Health", "-15%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 1.15f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(22, "Elemental", "Frost Glass", "Cold rounds crawl through the arena while your block crystallizes faster.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+25%"), new StatLine(positive: true, "Block cooldown", "-20%"), new StatLine(positive: false, "Projectile speed", "-45%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.55f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(23, "Elemental", "Storm Cell", "Unstable lightning shots travel fast and fire quickly, but arc unpredictably.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Attack speed", "+25%"), new StatLine(positive: true, "Projectile speed", "+50%"), new StatLine(positive: false, "Accuracy", "-20") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.8f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 20f) }, new EffectRule[0]), new CardDefinition(24, "Elemental", "Stoneheart", "Become an immense, durable anchor.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Health", "+60%"), new StatLine(positive: false, "Movement speed", "-25%"), new StatLine(positive: false, "Size", "+20%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.6f), new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 1.2f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.75f) }, new EffectRule[0]), new CardDefinition(25, "Elemental", "Tidal Chamber", "A deep reservoir grants four rounds, but each reload takes longer.", (Rarity)1, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Ammo", "+4"), new StatLine(positive: false, "Reload time", "+20%"), new StatLine(positive: false, "Damage", "-15%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 4f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.2f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(26, "Elemental", "Solar Flare", "Launch a gigantic miniature sun with extreme damage and extreme downtime.", (Rarity)1, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+80%"), new StatLine(positive: true, "Projectile size", "+80%"), new StatLine(positive: false, "Reload time", "+50%") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.8f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 1.8f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 1.2f) }, new EffectRule[0]), new CardDefinition(27, "Elemental", "Static Bloom", "Every shot branches into three fast sparks.", (Rarity)1, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Projectiles", "+2"), new StatLine(positive: true, "Projectile speed", "+20%"), new StatLine(positive: false, "Damage", "-30%") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Projectiles", OpMode.Add, 2f), new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 15f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.7f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.2f) }, new EffectRule[0]), new CardDefinition(28, "Elemental", "Permafrost", "Heavy ice armour grants health and rapid blocking, but drags you downward.", (Rarity)1, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Health", "+30%"), new StatLine(positive: true, "Block cooldown", "-30%"), new StatLine(positive: false, "Gravity", "+45%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.3f), new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 1.45f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 0.7f) }, new EffectRule[0]), new CardDefinition(29, "Elemental", "Magma Pressure", "Your current magazine size is converted into destructive pressure.", (Rarity)2, "FirepowerYellow", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Damage", "Scales with ammo"), new StatLine(positive: false, "Reload time", "+25%") }, new EffectOp[1] { new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.25f) }, new EffectRule[1] { EffectRule.Convert(new StatRef(TargetKind.Ammo, "MaxAmmo", 3f), new StatRef(TargetKind.Gun, "Damage", 1f), 0.3f) }), new CardDefinition(30, "Elemental", "Aurora Prism", "The weakest of damage, health, movement, reload, and blocking gains a 50% boost.", (Rarity)2, "FirepowerYellow", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Weakest stat", "+50%") }, new EffectOp[0], new EffectRule[1] { EffectRule.Extreme(RuleKind.BoostLowest, new StatRef[5] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Ammo, "ReloadTime", 1f), new StatRef(TargetKind.Block, "BlockCooldown", 1f) }, 1.5f) }), new CardDefinition(31, "Void", "Event Horizon", "A huge, slow projectile drags the fight toward a single catastrophic impact.", (Rarity)0, "EvilPurple", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+100%"), new StatLine(positive: true, "Knockback", "+100%"), new StatLine(positive: false, "Projectile speed", "-65%") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 2f), new EffectOp(TargetKind.Gun, "Knockback", OpMode.Multiply, 2f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 2.5f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.35f) }, new EffectRule[0]), new CardDefinition(32, "Void", "Null Point", "Collapse into a tiny glass cannon.", (Rarity)0, "EvilPurple", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+75%"), new StatLine(positive: true, "Size", "-40%"), new StatLine(positive: false, "Health", "-35%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 0.6f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.75f) }, new EffectRule[0]), new CardDefinition(33, "Void", "Abyssal Magazine", "Carry an impossible reserve of weak rounds.", (Rarity)0, "EvilPurple", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Ammo", "+8"), new StatLine(positive: false, "Damage", "-40%"), new StatLine(positive: false, "Reload time", "+75%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 8f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.6f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.75f) }, new EffectRule[0]), new CardDefinition(34, "Void", "Black Star", "A single dark mass of damage, restrained by slow firing and frail health.", (Rarity)0, "EvilPurple", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+120%"), new StatLine(positive: false, "Attack speed", "-43%"), new StatLine(positive: false, "Health", "-25%") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 2.2f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 1.75f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.75f), new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, -1f) }, new EffectRule[0]), new CardDefinition(35, "Void", "Vacuum Step", "Move through near-zero gravity at terrifying speed.", (Rarity)1, "EvilPurple", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Movement speed", "+70%"), new StatLine(positive: true, "Gravity", "-50%"), new StatLine(positive: false, "Health", "-30%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.7f), new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 0.5f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.7f) }, new EffectRule[0]), new CardDefinition(36, "Void", "Entropy Tax", "All offensive systems improve while every defensive system decays.", (Rarity)1, "EvilPurple", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Offence", "+25%"), new StatLine(positive: false, "Defence", "-20%") }, new EffectOp[5] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.8f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.8f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 1.25f) }, new EffectRule[0]), new CardDefinition(37, "Void", "Unmake", "Reduce your weapon to one microscopic, impossibly fast annihilation round.", (Rarity)1, "EvilPurple", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+90%"), new StatLine(positive: true, "Projectile speed", "+120%"), new StatLine(positive: false, "Ammo", "Set to 1") }, new EffectOp[4] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Set, 1f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.9f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 2.2f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 0.3f) }, new EffectRule[0]), new CardDefinition(38, "Void", "Dark Matter", "Become a colossal reserve of health that can barely move.", (Rarity)1, "EvilPurple", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Health", "+100%"), new StatLine(positive: false, "Movement speed", "-40%"), new StatLine(positive: false, "Size", "+60%") }, new EffectOp[4] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 2f), new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 1.6f), new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.6f) }, new EffectRule[0]), new CardDefinition(39, "Void", "Singularity Dividend", "Every Void card already held grants 12% damage and 5% size.", (Rarity)2, "EvilPurple", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Damage", "+12% per Void card"), new StatLine(positive: false, "Size", "+5% per Void card") }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.MultiplyPerTheme, 0.12f, "Void"), new EffectOp(TargetKind.Character, "Size", OpMode.MultiplyPerTheme, 0.05f, "Void") }, new EffectRule[0]), new CardDefinition(40, "Void", "Red Shift", "Convert existing projectile speed into damage and size, then slow the projectile.", (Rarity)2, "EvilPurple", allowMultiple: false, new StatLine[2] { new StatLine(positive: true, "Damage/size", "Scale with speed"), new StatLine(positive: false, "Projectile speed", "-30%") }, new EffectOp[1] { new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.7f) }, new EffectRule[2] { EffectRule.Convert(new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f), new StatRef(TargetKind.Gun, "Damage", 1f), 0.35f), EffectRule.Convert(new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f), new StatRef(TargetKind.Gun, "ProjectileSize", 1f), 0.2f) }), new CardDefinition(41, "Engineering", "Autoloader", "A compact loader adds ammunition and reload speed at a modest damage cost.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Ammo", "+3"), new StatLine(positive: true, "Reload speed", "+33%"), new StatLine(positive: false, "Damage", "-15%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 3f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.75f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(42, "Engineering", "Burst Compiler", "Compile each trigger pull into a controlled three-round burst.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Projectiles", "+2"), new StatLine(positive: false, "Damage", "-35%"), new StatLine(positive: false, "Attack speed", "-20%") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Projectiles", OpMode.Add, 2f), new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 8f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 1.2f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.65f) }, new EffectRule[0]), new CardDefinition(43, "Engineering", "Overclock", "Run firing systems far beyond specification.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Attack speed", "+82%"), new StatLine(positive: false, "Reload time", "+50%"), new StatLine(positive: false, "Health", "-20%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.55f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(44, "Engineering", "Safety Interlock", "Prioritise defensive cycling over weapon output.", (Rarity)0, "TechWhite", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Block cooldown", "-45%"), new StatLine(positive: false, "Damage", "-20%") }, new EffectOp[2] { new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 0.55f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(45, "Engineering", "Gyroscope", "Stabilise the barrel into a near-perfect line.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Accuracy", "+75%"), new StatLine(positive: true, "Projectile speed", "+25%"), new StatLine(positive: false, "Damage", "-10%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Spread", OpMode.Multiply, 0.25f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.9f) }, new EffectRule[0]), new CardDefinition(46, "Engineering", "Duplex Barrel", "A mechanically linked second barrel fires alongside the first.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Projectiles", "+1"), new StatLine(positive: false, "Damage", "-35%"), new StatLine(positive: false, "Spread", "+3") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Projectiles", OpMode.Add, 1f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 3f) }, new EffectRule[0]), new CardDefinition(47, "Engineering", "Capacitor Bank", "Double your magazine and increase damage, but recharge it slowly.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Ammo", "+100%"), new StatLine(positive: true, "Damage", "+15%"), new StatLine(positive: false, "Reload time", "+40%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Multiply, 2f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.4f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.15f) }, new EffectRule[0]), new CardDefinition(48, "Engineering", "Adaptive Chassis", "The weakest defensive system—health, movement, or block recovery—is reinforced.", (Rarity)1, "TechWhite", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Weakest defence", "+40%") }, new EffectOp[0], new EffectRule[1] { EffectRule.Extreme(RuleKind.BoostLowest, new StatRef[3] { new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Block, "BlockCooldown", 1f) }, 1.4f) }), new CardDefinition(49, "Engineering", "Workshop Warranty", "Enforce safe minimums for health, movement, ammunition, and projectile speed.", (Rarity)2, "TechWhite", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Core stats", "Minimum guaranteed") }, new EffectOp[4] { new EffectOp(TargetKind.Character, "Health", OpMode.Min, 0.8f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Min, 0.8f), new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Min, 3f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Min, 0.75f) }, new EffectRule[0]), new CardDefinition(50, "Engineering", "Recursive Upgrade", "Each Engineering card already held improves damage, health, and reload efficiency.", (Rarity)2, "TechWhite", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+6% per Engineering"), new StatLine(positive: true, "Health", "+4% per Engineering"), new StatLine(positive: true, "Reload", "+3% per Engineering") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Damage", OpMode.MultiplyPerTheme, 0.06f, "Engineering"), new EffectOp(TargetKind.Character, "Health", OpMode.MultiplyPerTheme, 0.04f, "Engineering"), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.MultiplyPerTheme, -0.03f, "Engineering") }, new EffectRule[0]), new CardDefinition(51, "Biology", "Thick Hide", "Dense tissue massively increases health while reducing mobility.", (Rarity)0, "PoisonGreen", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Health", "+55%"), new StatLine(positive: false, "Movement speed", "-15%") }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.55f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(52, "Biology", "Hollow Bones", "Become buoyant and agile, but structurally fragile.", (Rarity)0, "PoisonGreen", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Gravity", "-45%"), new StatLine(positive: true, "Jump", "+35%"), new StatLine(positive: false, "Health", "-20%") }, new EffectOp[3] { new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 0.55f), new EffectOp(TargetKind.Character, "Jump", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(53, "Biology", "Adrenal Gland", "A permanent surge accelerates movement and firing.", (Rarity)0, "PoisonGreen", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Movement speed", "+35%"), new StatLine(positive: true, "Attack speed", "+25%"), new StatLine(positive: false, "Health", "-15%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.8f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(54, "Biology", "Venom Sac", "Denser toxic rounds hit harder and add a reserve shot, but travel slowly.", (Rarity)0, "PoisonGreen", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+25%"), new StatLine(positive: true, "Ammo", "+1"), new StatLine(positive: false, "Projectile speed", "-20%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 1f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(55, "Biology", "Regenerative Tissue", "Grow a larger health reserve while weapon output atrophies.", (Rarity)1, "PoisonGreen", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Health", "+35%"), new StatLine(positive: false, "Damage", "-10%"), new StatLine(positive: false, "Block cooldown", "+15%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.9f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 1.15f) }, new EffectRule[0]), new CardDefinition(56, "Biology", "Compound Eyes", "Gain surgical accuracy and faster rounds at the cost of a larger silhouette.", (Rarity)1, "PoisonGreen", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Accuracy", "+70%"), new StatLine(positive: true, "Projectile speed", "+20%"), new StatLine(positive: false, "Size", "+10%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Spread", OpMode.Multiply, 0.3f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.2f), new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 1.1f) }, new EffectRule[0]), new CardDefinition(57, "Biology", "Muscle Memory", "Damage grows by 3% for every card your body has already adapted to.", (Rarity)1, "PoisonGreen", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Damage", "+3% per card"), new StatLine(positive: true, "Movement speed", "+10%") }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.MultiplyPerCard, 0.03f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.1f) }, new EffectRule[0]), new CardDefinition(58, "Biology", "Parasitic Chamber", "Gain lifesteal by feeding the chamber a portion of your maximum health.", (Rarity)1, "PoisonGreen", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Lifesteal", "+20%"), new StatLine(positive: false, "Health", "-25%"), new StatLine(positive: false, "Damage", "-10%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "LifeSteal", OpMode.Add, 0.2f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.75f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.9f) }, new EffectRule[0]), new CardDefinition(59, "Biology", "Chitin Plating", "Grow armour and a second block charge, becoming slower in exchange.", (Rarity)2, "PoisonGreen", allowMultiple: false, new StatLine[3] { new StatLine(positive: true, "Health", "+30%"), new StatLine(positive: true, "Extra blocks", "+1"), new StatLine(positive: false, "Movement speed", "-20%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.3f), new EffectOp(TargetKind.Block, "ExtraBlocks", OpMode.Add, 1f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.8f) }, new EffectRule[0]), new CardDefinition(60, "Biology", "Apex Mutation", "Your strongest core stat grows by 30%; your weakest grows by 15%.", (Rarity)2, "PoisonGreen", allowMultiple: false, new StatLine[2] { new StatLine(positive: true, "Strongest stat", "+30%"), new StatLine(positive: true, "Weakest stat", "+15%") }, new EffectOp[0], new EffectRule[2] { EffectRule.Extreme(RuleKind.BoostStrongest, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f) }, 1.3f), EffectRule.Extreme(RuleKind.BoostLowest, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f) }, 1.15f) }), new CardDefinition(61, "Trickery", "False Positive", "Receive one of three deterministic fake-outs: power, speed, or bulk—with a matching drawback.", (Rarity)0, "MagicPink", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Effect", "One of three packages") }, new EffectOp[0], new EffectRule[1] { EffectRule.Random(new EffectOp[3][] { new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.45f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.2f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.4f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.85f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.45f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 1.2f) } }) }), new CardDefinition(62, "Trickery", "Loaded Dice", "One offensive stat receives +50%; another is randomly taxed by 20%.", (Rarity)0, "MagicPink", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Random offence", "+50%"), new StatLine(positive: false, "Random offence", "-20%") }, new EffectOp[0], new EffectRule[1] { EffectRule.Random(new EffectOp[3][] { new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.8f) }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 1.2f) }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.67f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.8f) } }) }), new CardDefinition(63, "Trickery", "Smoke Screen", "Shrink yourself and your rounds while hiding extra ammunition in the haze.", (Rarity)0, "MagicPink", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Size", "-30%"), new StatLine(positive: true, "Ammo", "+3"), new StatLine(positive: false, "Projectile size", "-50%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 0.7f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 0.5f), new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 3f) }, new EffectRule[0]), new CardDefinition(64, "Trickery", "Decoy Round", "Flood the arena with five harmless-looking projectiles that are not entirely harmless.", (Rarity)0, "MagicPink", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Projectiles", "+4"), new StatLine(positive: false, "Damage", "-65%"), new StatLine(positive: false, "Spread", "+28") }, new EffectOp[4] { new EffectOp(TargetKind.Gun, "Projectiles", OpMode.Add, 4f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.35f), new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 28f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 0.7f) }, new EffectRule[0]), new CardDefinition(65, "Trickery", "Sleight of Hand", "Hide two extra rounds and reload them quickly, but launch them slowly.", (Rarity)1, "MagicPink", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Ammo", "+2"), new StatLine(positive: true, "Reload speed", "+54%"), new StatLine(positive: false, "Projectile speed", "-25%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 2f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 0.75f) }, new EffectRule[0]), new CardDefinition(66, "Trickery", "Crooked Barrel", "Wildly inaccurate rounds are compensated with frightening damage and speed.", (Rarity)1, "MagicPink", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+50%"), new StatLine(positive: true, "Projectile speed", "+25%"), new StatLine(positive: false, "Spread", "+40") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Spread", OpMode.Add, 40f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.5f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.25f) }, new EffectRule[0]), new CardDefinition(67, "Trickery", "Mirror Match", "Your strongest core stat is copied halfway into your weakest.", (Rarity)1, "MagicPink", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Weakest stat", "Moves toward strongest") }, new EffectOp[0], new EffectRule[1] { EffectRule.Extreme(RuleKind.MirrorExtreme, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f) }, 0.5f) }), new CardDefinition(68, "Trickery", "Misfire Insurance", "Guarantee at least three rounds, 80% base damage, and 70% projectile speed.", (Rarity)1, "MagicPink", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Weapon floors", "Guaranteed") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Min, 3f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Min, 0.8f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Min, 0.7f) }, new EffectRule[0]), new CardDefinition(69, "Trickery", "House Edge", "A seeded gamble chooses one jackpot and one painful liability.", (Rarity)2, "MagicPink", allowMultiple: false, new StatLine[2] { new StatLine(positive: true, "Jackpot", "Random"), new StatLine(positive: false, "Liability", "Random") }, new EffectOp[0], new EffectRule[1] { EffectRule.Random(new EffectOp[4][] { new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.8f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.65f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.8f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.65f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.8f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.55f) }, new EffectOp[2] { new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.45f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.65f) } }) }), new CardDefinition(70, "Trickery", "Vanishing Point", "Become almost impossible to track—and equally easy to kill when caught.", (Rarity)2, "MagicPink", allowMultiple: false, new StatLine[3] { new StatLine(positive: true, "Size", "-50%"), new StatLine(positive: true, "Movement speed", "+45%"), new StatLine(positive: false, "Health", "-35%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 0.5f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.45f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.65f) }, new EffectRule[0]), new CardDefinition(71, "Economy", "Compound Interest", "Your damage portfolio compounds by 5% for every card already owned.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Damage", "+5% per card") }, new EffectOp[1] { new EffectOp(TargetKind.Gun, "Damage", OpMode.MultiplyPerCard, 0.05f) }, new EffectRule[0]), new CardDefinition(72, "Economy", "Bulk Discount", "Gain one round for every three cards in your deck, then accept a slower reload.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Ammo", "+1 per 3 cards"), new StatLine(positive: false, "Reload time", "+20%") }, new EffectOp[2] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.AddPerCardGroup, 1f / 3f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.2f) }, new EffectRule[0]), new CardDefinition(73, "Economy", "Diversified Portfolio", "Gain 6% health for every distinct theme represented in your deck.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Health", "+6% per theme") }, new EffectOp[1] { new EffectOp(TargetKind.Character, "Health", OpMode.MultiplyPerDistinctTheme, 0.06f) }, new EffectRule[0]), new CardDefinition(74, "Economy", "Liquid Assets", "Convert current magazine capacity into reload efficiency.", (Rarity)0, "FirepowerYellow", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Reload speed", "Scales with ammo"), new StatLine(positive: false, "Damage", "-10%") }, new EffectOp[1] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.9f) }, new EffectRule[1] { EffectRule.Convert(new StatRef(TargetKind.Ammo, "MaxAmmo", 3f), new StatRef(TargetKind.Ammo, "ReloadTime", 1f), 0.18f, inverse: true) }), new CardDefinition(75, "Economy", "Hostile Takeover", "Convert your current size into damage, then reduce your size by 15%.", (Rarity)1, "FirepowerYellow", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Damage", "Scales with size"), new StatLine(positive: true, "Size", "-15%") }, new EffectOp[1] { new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 0.85f) }, new EffectRule[1] { EffectRule.Convert(new StatRef(TargetKind.Character, "Size", 1f), new StatRef(TargetKind.Gun, "Damage", 1f), 0.45f) }), new CardDefinition(76, "Economy", "Insurance Policy", "Purchase a second block charge with health and damage premiums.", (Rarity)1, "FirepowerYellow", allowMultiple: false, new StatLine[3] { new StatLine(positive: true, "Extra blocks", "+1"), new StatLine(positive: false, "Health", "-15%"), new StatLine(positive: false, "Damage", "-15%") }, new EffectOp[3] { new EffectOp(TargetKind.Block, "ExtraBlocks", OpMode.Add, 1f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.85f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.85f) }, new EffectRule[0]), new CardDefinition(77, "Economy", "Venture Capital", "Receive huge growth now; lose 2% health for every card already in the deck.", (Rarity)1, "FirepowerYellow", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+75%"), new StatLine(positive: true, "Movement speed", "+20%"), new StatLine(positive: false, "Health", "-2% per card") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.75f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.2f), new EffectOp(TargetKind.Character, "Health", OpMode.MultiplyPerCard, -0.02f) }, new EffectRule[0]), new CardDefinition(78, "Economy", "Cashback", "Every Economy card already held returns ammunition and health.", (Rarity)1, "FirepowerYellow", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Ammo", "+1 per 2 Economy"), new StatLine(positive: true, "Health", "+5% per Economy") }, new EffectOp[2] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.AddPerThemeGroup, 0.5f, "Economy"), new EffectOp(TargetKind.Character, "Health", OpMode.MultiplyPerTheme, 0.05f, "Economy") }, new EffectRule[0]), new CardDefinition(79, "Economy", "Monopoly", "Four Economy cards unlock a dominant package; otherwise this card is a costly dud.", (Rarity)2, "FirepowerYellow", allowMultiple: false, new StatLine[2] { new StatLine(positive: true, "At 4 Economy", "Major bonuses"), new StatLine(positive: false, "Below 4 Economy", "Minor penalty") }, new EffectOp[0], new EffectRule[1] { EffectRule.ThemeThreshold("Economy", 4f, new EffectOp[3] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.4f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.3f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.75f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.9f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.15f) }) }), new CardDefinition(80, "Economy", "Golden Ratio", "Pull damage, health, and movement halfway toward a balanced geometric mean.", (Rarity)2, "FirepowerYellow", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Core build", "Rebalanced") }, new EffectOp[0], new EffectRule[1] { EffectRule.Extreme(RuleKind.Balance, new StatRef[3] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f) }, 0.5f) }), new CardDefinition(81, "Sacrifice", "Blood Price", "Exchange a third of your health for overwhelming damage.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Damage", "+70%"), new StatLine(positive: false, "Health", "-35%") }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.7f) }, new EffectRule[0]), new CardDefinition(82, "Sacrifice", "Empty Chamber", "Reduce the magazine to one devastating round with a fast reload.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+90%"), new StatLine(positive: true, "Reload speed", "+33%"), new StatLine(positive: false, "Ammo", "Set to 1") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Set, 1f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.9f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.75f) }, new EffectRule[0]), new CardDefinition(83, "Sacrifice", "Lead Feet", "Surrender mobility for immense health and downward force.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Health", "+70%"), new StatLine(positive: false, "Movement speed", "-40%"), new StatLine(positive: false, "Gravity", "+30%") }, new EffectOp[3] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 0.6f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.7f), new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 1.3f) }, new EffectRule[0]), new CardDefinition(84, "Sacrifice", "Glass Engine", "Halve your health to accelerate every weapon timing system.", (Rarity)0, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Attack speed", "+67%"), new StatLine(positive: true, "Reload speed", "+67%"), new StatLine(positive: false, "Health", "-50%") }, new EffectOp[4] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.5f), new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.6f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.6f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.5f) }, new EffectRule[0]), new CardDefinition(85, "Sacrifice", "Broken Shield", "Abandon block recovery to empower damage and movement.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+45%"), new StatLine(positive: true, "Movement speed", "+20%"), new StatLine(positive: false, "Block cooldown", "+100%") }, new EffectOp[3] { new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 2f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.45f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.2f) }, new EffectRule[0]), new CardDefinition(86, "Sacrifice", "Small Offering", "Shed mass and health in exchange for speed and weapon power.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+35%"), new StatLine(positive: true, "Movement speed", "+25%"), new StatLine(positive: false, "Health", "-20%") }, new EffectOp[4] { new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.8f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.25f) }, new EffectRule[0]), new CardDefinition(87, "Sacrifice", "Burn the Reserve", "Destroy half your ammunition to improve damage and reload speed.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+40%"), new StatLine(positive: true, "Reload speed", "+43%"), new StatLine(positive: false, "Ammo", "-50%") }, new EffectOp[3] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Multiply, 0.5f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.7f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.4f) }, new EffectRule[0]), new CardDefinition(88, "Sacrifice", "Oath of Silence", "Fire rarely, but make every shot enormous and lethal.", (Rarity)1, "DestructiveRed", allowMultiple: true, new StatLine[3] { new StatLine(positive: true, "Damage", "+85%"), new StatLine(positive: true, "Projectile size", "+70%"), new StatLine(positive: false, "Attack speed", "-50%") }, new EffectOp[3] { new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 2f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.85f), new EffectOp(TargetKind.Gun, "ProjectileSize", OpMode.Multiply, 1.7f) }, new EffectRule[0]), new CardDefinition(89, "Sacrifice", "Martyr's Dividend", "Convert your current health investment into damage, then surrender 30% of it.", (Rarity)2, "DestructiveRed", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Damage", "Scales with health"), new StatLine(positive: false, "Health", "-30%") }, new EffectOp[1] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.7f) }, new EffectRule[1] { EffectRule.Convert(new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Gun, "Damage", 1f), 0.5f) }), new CardDefinition(90, "Sacrifice", "One-Way Door", "Double your strongest offensive stat, but permanently cap health at 70% of base.", (Rarity)2, "DestructiveRed", allowMultiple: false, new StatLine[2] { new StatLine(positive: true, "Strongest offence", "+100%"), new StatLine(positive: false, "Health", "Maximum 70%") }, new EffectOp[1] { new EffectOp(TargetKind.Character, "Health", OpMode.Max, 0.7f) }, new EffectRule[1] { EffectRule.Extreme(RuleKind.BoostStrongest, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f), new StatRef(TargetKind.Gun, "AttackSpeed", 1f), new StatRef(TargetKind.Ammo, "ReloadTime", 1f) }, 2f) }), new CardDefinition(91, "Adaptation", "Weak Link", "Identify the weakest core stat and reinforce it by 45%.", (Rarity)0, "DefensiveBlue", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Weakest stat", "+45%") }, new EffectOp[0], new EffectRule[1] { EffectRule.Extreme(RuleKind.BoostLowest, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f) }, 1.45f) }), new CardDefinition(92, "Adaptation", "Strong Link", "Improve the strongest core stat by 25%, then trim the weakest by 10%.", (Rarity)0, "DefensiveBlue", allowMultiple: true, new StatLine[2] { new StatLine(positive: true, "Strongest stat", "+25%"), new StatLine(positive: false, "Weakest stat", "-10%") }, new EffectOp[0], new EffectRule[2] { EffectRule.Extreme(RuleKind.BoostStrongest, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f) }, 1.25f), EffectRule.Extreme(RuleKind.BoostLowest, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new StatRef(TargetKind.Character, "MoveSpeed", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f) }, 0.9f) }), new CardDefinition(93, "Adaptation", "Equalizer", "Pull damage, projectile speed, attack interval, and reload interval toward one profile.", (Rarity)0, "DefensiveBlue", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Weapon profile", "Normalised") }, new EffectOp[0], new EffectRule[1] { EffectRule.Extreme(RuleKind.Balance, new StatRef[4] { new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Gun, "ProjectileSpeed", 1f), new StatRef(TargetKind.Gun, "AttackSpeed", 1f), new StatRef(TargetKind.Ammo, "ReloadTime", 1f) }, 0.65f) }), new CardDefinition(94, "Adaptation", "Counterweight", "Large bodies gain speed; small bodies gain health and damage.", (Rarity)0, "DefensiveBlue", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Effect", "Depends on size") }, new EffectOp[0], new EffectRule[1] { EffectRule.WhenThreshold(RuleKind.StatThreshold, new StatRef(TargetKind.Character, "Size", 1f), 1f, new EffectOp[2] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 0.8f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.3f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.2f) }) }), new CardDefinition(95, "Adaptation", "Load Balancer", "Large magazines gain damage; small magazines are expanded by three rounds.", (Rarity)1, "DefensiveBlue", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Effect", "Depends on ammo") }, new EffectOp[0], new EffectRule[1] { EffectRule.WhenThreshold(RuleKind.RawThreshold, new StatRef(TargetKind.Ammo, "MaxAmmo", 3f), 5f, new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.15f) }, new EffectOp[2] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 3f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.9f) }) }), new CardDefinition(96, "Adaptation", "Environmental Suit", "High gravity is resisted; low gravity is exploited for speed.", (Rarity)1, "DefensiveBlue", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Effect", "Depends on gravity") }, new EffectOp[0], new EffectRule[1] { EffectRule.WhenThreshold(RuleKind.StatThreshold, new StatRef(TargetKind.Gravity, "Gravity", 1f), 1f, new EffectOp[2] { new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.2f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.25f) }) }), new CardDefinition(97, "Adaptation", "Predator Algorithm", "An offensive build receives defence; a defensive build receives offence.", (Rarity)1, "DefensiveBlue", allowMultiple: true, new StatLine[1] { new StatLine(positive: true, "Build", "Counterbalanced") }, new EffectOp[0], new EffectRule[1] { EffectRule.Compare(new StatRef(TargetKind.Gun, "Damage", 1f), new StatRef(TargetKind.Character, "Health", 1f), new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 0.8f) }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.4f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.2f) }) }), new CardDefinition(98, "Adaptation", "Redundancy", "Gain an extra block if you have none; otherwise convert redundancy into health.", (Rarity)1, "DefensiveBlue", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Extra block or health", "Adaptive") }, new EffectOp[0], new EffectRule[1] { EffectRule.WhenThreshold(RuleKind.RawThreshold, new StatRef(TargetKind.Block, "ExtraBlocks", 0f), 1f, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 0.9f) }, new EffectOp[2] { new EffectOp(TargetKind.Block, "ExtraBlocks", OpMode.Add, 1f), new EffectOp(TargetKind.Block, "BlockCooldown", OpMode.Multiply, 1.1f) }) }), new CardDefinition(99, "Adaptation", "Evolutionary Leap", "Adopt one deterministic mutation from all ten themes.", (Rarity)2, "DefensiveBlue", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Mutation", "One of ten") }, new EffectOp[0], new EffectRule[1] { EffectRule.Random(new EffectOp[10][] { new EffectOp[2] { new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gun, "Knockback", OpMode.Multiply, 1.25f) }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "AttackSpeed", OpMode.Multiply, 0.75f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 1.15f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 1.35f), new EffectOp(TargetKind.Gravity, "Gravity", OpMode.Multiply, 1.15f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Size", OpMode.Multiply, 0.7f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.3f) }, new EffectOp[2] { new EffectOp(TargetKind.Ammo, "MaxAmmo", OpMode.Add, 3f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.Multiply, 0.85f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "LifeSteal", OpMode.Add, 0.15f), new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.85f) }, new EffectOp[2] { new EffectOp(TargetKind.Gun, "Projectiles", OpMode.Add, 2f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 0.7f) }, new EffectOp[1] { new EffectOp(TargetKind.Gun, "Damage", OpMode.MultiplyPerCard, 0.03f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "Health", OpMode.Multiply, 0.65f), new EffectOp(TargetKind.Gun, "Damage", OpMode.Multiply, 1.65f) }, new EffectOp[2] { new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.Multiply, 1.25f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.Multiply, 1.25f) } }) }), new CardDefinition(100, "Adaptation", "Perfect Form", "Every distinct theme represented grants 3% damage, health, movement, projectile speed, and reload efficiency.", (Rarity)2, "DefensiveBlue", allowMultiple: false, new StatLine[1] { new StatLine(positive: true, "Major stats", "+3% per distinct theme") }, new EffectOp[5] { new EffectOp(TargetKind.Gun, "Damage", OpMode.MultiplyPerDistinctTheme, 0.03f), new EffectOp(TargetKind.Character, "Health", OpMode.MultiplyPerDistinctTheme, 0.03f), new EffectOp(TargetKind.Character, "MoveSpeed", OpMode.MultiplyPerDistinctTheme, 0.03f), new EffectOp(TargetKind.Gun, "ProjectileSpeed", OpMode.MultiplyPerDistinctTheme, 0.03f), new EffectOp(TargetKind.Ammo, "ReloadTime", OpMode.MultiplyPerDistinctTheme, -0.03f) }, new EffectRule[0]) }; internal static readonly Dictionary<string, string> ThemeByTitle = BuildThemeLookup(); private static Dictionary<string, string> BuildThemeLookup() { Dictionary<string, string> dictionary = new Dictionary<string, string>(); CardDefinition[] all = All; foreach (CardDefinition cardDefinition in all) { dictionary[cardDefinition.Title] = cardDefinition.Theme; } return dictionary; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("celery.rounds.themedmayhemcards", "Themed Mayhem Cards", "1.0.0")] [BepInProcess("Rounds.exe")] public sealed class ThemedMayhemPlugin : BaseUnityPlugin { public const string ModId = "celery.rounds.themedmayhemcards"; public const string ModName = "Themed Mayhem Cards"; public const string Version = "1.0.0"; internal static ManualLogSource Log { get; private set; } private void Start() { Log = ((BaseUnityPlugin)this).Logger; RegisterCards(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered 100 cards across 10 themes."); } private static void RegisterCards() { CustomCard.BuildCard<Card001_Railspike>(); CustomCard.BuildCard<Card002_PinballProtocol>(); CustomCard.BuildCard<Card003_RecoilReactor>(); CustomCard.BuildCard<Card004_ScatterCrown>(); CustomCard.BuildCard<Card005_NeedleStorm>(); CustomCard.BuildCard<Card006_HeavyOrbit>(); CustomCard.BuildCard<Card007_KineticBattery>(); CustomCard.BuildCard<Card008_RicochetDividend>(); CustomCard.BuildCard<Card009_ZeroPointKick>(); CustomCard.BuildCard<Card010_TerminalVelocity>(); CustomCard.BuildCard<Card011_SplitSecond>(); CustomCard.BuildCard<Card012_BorrowedTime>(); CustomCard.BuildCard<Card013_StasisMagazine>(); CustomCard.BuildCard<Card014_ChronoShield>(); CustomCard.BuildCard<Card015_Afterimage>(); CustomCard.BuildCard<Card016_TheLongNow>(); CustomCard.BuildCard<Card017_TimeDilation>(); CustomCard.BuildCard<Card018_FastForward>(); CustomCard.BuildCard<Card019_SecondHand>(); CustomCard.BuildCard<Card020_ParadoxEngine>(); CustomCard.BuildCard<Card021_EmberCore>(); CustomCard.BuildCard<Card022_FrostGlass>(); CustomCard.BuildCard<Card023_StormCell>(); CustomCard.BuildCard<Card024_Stoneheart>(); CustomCard.BuildCard<Card025_TidalChamber>(); CustomCard.BuildCard<Card026_SolarFlare>(); CustomCard.BuildCard<Card027_StaticBloom>(); CustomCard.BuildCard<Card028_Permafrost>(); CustomCard.BuildCard<Card029_MagmaPressure>(); CustomCard.BuildCard<Card030_AuroraPrism>(); CustomCard.BuildCard<Card031_EventHorizon>(); CustomCard.BuildCard<Card032_NullPoint>(); CustomCard.BuildCard<Card033_AbyssalMagazine>(); CustomCard.BuildCard<Card034_BlackStar>(); CustomCard.BuildCard<Card035_VacuumStep>(); CustomCard.BuildCard<Card036_EntropyTax>(); CustomCard.BuildCard<Card037_Unmake>(); CustomCard.BuildCard<Card038_DarkMatter>(); CustomCard.BuildCard<Card039_SingularityDividend>(); CustomCard.BuildCard<Card040_RedShift>(); CustomCard.BuildCard<Card041_Autoloader>(); CustomCard.BuildCard<Card042_BurstCompiler>(); CustomCard.BuildCard<Card043_Overclock>(); CustomCard.BuildCard<Card044_SafetyInterlock>(); CustomCard.BuildCard<Card045_Gyroscope>(); CustomCard.BuildCard<Card046_DuplexBarrel>(); CustomCard.BuildCard<Card047_CapacitorBank>(); CustomCard.BuildCard<Card048_AdaptiveChassis>(); CustomCard.BuildCard<Card049_WorkshopWarranty>(); CustomCard.BuildCard<Card050_RecursiveUpgrade>(); CustomCard.BuildCard<Card051_ThickHide>(); CustomCard.BuildCard<Card052_HollowBones>(); CustomCard.BuildCard<Card053_AdrenalGland>(); CustomCard.BuildCard<Card054_VenomSac>(); CustomCard.BuildCard<Card055_RegenerativeTissue>(); CustomCard.BuildCard<Card056_CompoundEyes>(); CustomCard.BuildCard<Card057_MuscleMemory>(); CustomCard.BuildCard<Card058_ParasiticChamber>(); CustomCard.BuildCard<Card059_ChitinPlating>(); CustomCard.BuildCard<Card060_ApexMutation>(); CustomCard.BuildCard<Card061_FalsePositive>(); CustomCard.BuildCard<Card062_LoadedDice>(); CustomCard.BuildCard<Card063_SmokeScreen>(); CustomCard.BuildCard<Card064_DecoyRound>(); CustomCard.BuildCard<Card065_SleightofHand>(); CustomCard.BuildCard<Card066_CrookedBarrel>(); CustomCard.BuildCard<Card067_MirrorMatch>(); CustomCard.BuildCard<Card068_MisfireInsurance>(); CustomCard.BuildCard<Card069_HouseEdge>(); CustomCard.BuildCard<Card070_VanishingPoint>(); CustomCard.BuildCard<Card071_CompoundInterest>(); CustomCard.BuildCard<Card072_BulkDiscount>(); CustomCard.BuildCard<Card073_DiversifiedPortfolio>(); CustomCard.BuildCard<Card074_LiquidAssets>(); CustomCard.BuildCard<Card075_HostileTakeover>(); CustomCard.BuildCard<Card076_InsurancePolicy>(); CustomCard.BuildCard<Card077_VentureCapital>(); CustomCard.BuildCard<Card078_Cashback>(); CustomCard.BuildCard<Card079_Monopoly>(); CustomCard.BuildCard<Card080_GoldenRatio>(); CustomCard.BuildCard<Card081_BloodPrice>(); CustomCard.BuildCard<Card082_EmptyChamber>(); CustomCard.BuildCard<Card083_LeadFeet>(); CustomCard.BuildCard<Card084_GlassEngine>(); CustomCard.BuildCard<Card085_BrokenShield>(); CustomCard.BuildCard<Card086_SmallOffering>(); CustomCard.BuildCard<Card087_BurntheReserve>(); CustomCard.BuildCard<Card088_OathofSilence>(); CustomCard.BuildCard<Card089_MartyrsDividend>(); CustomCard.BuildCard<Card090_OneWayDoor>(); CustomCard.BuildCard<Card091_WeakLink>(); CustomCard.BuildCard<Card092_StrongLink>(); CustomCard.BuildCard<Card093_Equalizer>(); CustomCard.BuildCard<Card094_Counterweight>(); CustomCard.BuildCard<Card095_LoadBalancer>(); CustomCard.BuildCard<Card096_EnvironmentalSuit>(); CustomCard.BuildCard<Card097_PredatorAlgorithm>(); CustomCard.BuildCard<Card098_Redundancy>(); CustomCard.BuildCard<Card099_EvolutionaryLeap>(); CustomCard.BuildCard<Card100_PerfectForm>(); } } internal static class EffectEngine { private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly HashSet<string> MissingLogged = new HashSet<string>(); private static readonly Dictionary<string, string[]> Aliases = new Dictionary<string, string[]> { { "Damage", new string[1] { "damage" } }, { "AttackSpeed", new string[1] { "attackSpeed" } }, { "ProjectileSpeed", new string[1] { "projectileSpeed" } }, { "Projectiles", new string[1] { "numberOfProjectiles" } }, { "Spread", new string[1] { "spread" } }, { "Knockback", new string[1] { "knockback" } }, { "ProjectileSize", new string[1] { "projectileSize" } }, { "Bounces", new string[1] { "reflects" } }, { "BounceSpeed", new string[1] { "speedMOnBounce" } }, { "BounceDamage", new string[1] { "dmgMOnBounce" } }, { "MaxAmmo", new string[1] { "maxAmmo" } }, { "ReloadTime", new string[1] { "reloadTime" } }, { "Health", new string[1] { "health" } }, { "MoveSpeed", new string[1] { "movementSpeed" } }, { "Jump", new string[1] { "jump" } }, { "Size", new string[1] { "sizeMultiplier" } }, { "LifeSteal", new string[2] { "lifeSteal", "lifesteal" } }, { "Gravity", new string[1] { "gravityForce" } }, { "BlockCooldown", new string[1] { "cooldown" } }, { "ExtraBlocks", new string[1] { "additionalBlocks" } } }; internal static void Apply(CardDefinition definition, CardContext context) { EffectOp[] operations = definition.Operations; for (int i = 0; i < operations.Length; i++) { ApplyOperation(operations[i], context); } EffectRule[] rules = definition.Rules; for (int i = 0; i < rules.Length; i++) { ApplyRule(rules[i], definition, context); } } private static void ApplyOperation(EffectOp op, CardContext context) { object target = context.Resolve(op.Target); if (TryRead(target, op.Member, out var value)) { int num = CountCards(context); int num2 = CountTheme(context, op.Theme); int num3 = CountDistinctThemes(context); float value2 = value; switch (op.Mode) { case OpMode.Multiply: value2 = value * op.Value; break; case OpMode.Add: value2 = value + op.Value; break; case OpMode.Set: value2 = op.Value; break; case OpMode.Min: value2 = Math.Max(value, op.Value); break; case OpMode.Max: value2 = Math.Min(value, op.Value); break; case OpMode.MultiplyPerCard: value2 = value * Math.Max(0.05f, 1f + op.Value * (float)num); break; case OpMode.AddPerCard: value2 = value + op.Value * (float)num; break; case OpMode.AddPerCardGroup: value2 = value + (float)Math.Floor((float)num * op.Value); break; case OpMode.MultiplyPerTheme: value2 = value * Math.Max(0.05f, 1f + op.Value * (float)num2); break; case OpMode.AddPerThemeGroup: value2 = value + (float)Math.Floor((float)num2 * op.Value); break; case OpMode.MultiplyPerDistinctTheme: value2 = value * Math.Max(0.05f, 1f + op.Value * (float)num3); break; } WriteClamped(target, op.Member, value2); } } private static void ApplyRule(EffectRule rule, CardDefinition definition, CardContext context) { switch (rule.Kind) { case RuleKind.Convert: case RuleKind.ConvertInverse: { if (TryReadRef(context, rule.A, out var value3) && TryReadRef(context, rule.B, out var value4)) { float val = ((rule.A.Baseline == 0f) ? value3 : (value3 / rule.A.Baseline)); val = Math.Max(0f, val); float num3 = 1f + val * rule.Value; if (rule.Kind == RuleKind.ConvertInverse) { num3 = 1f / Math.Max(0.1f, num3); } WriteRef(context, rule.B, value4 * num3); } break; } case RuleKind.Swap: { if (TryReadRef(context, rule.A, out var value6) && TryReadRef(context, rule.B, out var value7)) { float num4 = ((rule.A.Baseline == 0f) ? value6 : (value6 / rule.A.Baseline)); float num5 = ((rule.B.Baseline == 0f) ? value7 : (value7 / rule.B.Baseline)); WriteRef(context, rule.A, rule.A.Baseline * num5); WriteRef(context, rule.B, rule.B.Baseline * num4); } break; } case RuleKind.BoostLowest: case RuleKind.BoostStrongest: ApplyExtreme(rule, context, rule.Kind == RuleKind.BoostStrongest); break; case RuleKind.MirrorExtreme: ApplyMirror(rule, context); break; case RuleKind.Balance: ApplyBalance(rule, context); break; case RuleKind.RandomPackage: if (rule.Packages != null && rule.Packages.Length != 0) { int num6 = Math.Abs(definition.Id * 7919 + CountCards(context) * 31 + GetPlayerId(context.Player) * 101) % rule.Packages.Length; ApplyPackage(rule.Packages[num6], context); } break; case RuleKind.ThemeThreshold: ApplyPackage(((float)CountTheme(context, rule.Theme) >= rule.Threshold) ? rule.TrueOps : rule.FalseOps, context); break; case RuleKind.StatThreshold: { if (TryReadRef(context, rule.A, out var value8)) { value8 = ((rule.A.Baseline == 0f) ? value8 : (value8 / rule.A.Baseline)); ApplyPackage((value8 >= rule.Threshold) ? rule.TrueOps : rule.FalseOps, context); } break; } case RuleKind.RawThreshold: { if (TryReadRef(context, rule.A, out var value5)) { ApplyPackage((value5 >= rule.Threshold) ? rule.TrueOps : rule.FalseOps, context); } break; } case RuleKind.Compare: { if (TryReadRef(context, rule.A, out var value) && TryReadRef(context, rule.B, out var value2)) { float num = ((rule.A.Baseline == 0f) ? value : (value / rule.A.Baseline)); float num2 = ((rule.B.Baseline == 0f) ? value2 : (value2 / rule.B.Baseline)); ApplyPackage((num >= num2) ? rule.TrueOps : rule.FalseOps, context); } break; } } } private static void ApplyExtreme(EffectRule rule, CardContext context, bool strongest) { if (rule.Stats == null || rule.Stats.Length == 0) { return; } StatRef statRef = null; float num = (strongest ? float.MinValue : float.MaxValue); StatRef[] stats = rule.Stats; foreach (StatRef statRef2 in stats) { if (TryReadRef(context, statRef2, out var value)) { float num2 = ((statRef2.Baseline == 0f) ? value : (value / statRef2.Baseline)); if (statRef2.Member == "AttackSpeed" || statRef2.Member == "ReloadTime" || statRef2.Member == "BlockCooldown") { num2 = 1f / Math.Max(0.05f, num2); } if ((strongest && num2 > num) || (!strongest && num2 < num)) { statRef = statRef2; num = num2; } } } if (statRef != null && TryReadRef(context, statRef, out var value2)) { float num3 = rule.Value; if (statRef.Member == "AttackSpeed" || statRef.Member == "ReloadTime" || statRef.Member == "BlockCooldown") { num3 = 1f / Math.Max(0.05f, num3); } WriteRef(context, statRef, value2 * num3); } } private static void ApplyMirror(EffectRule rule, CardContext context) { if (rule.Stats == null || rule.Stats.Length < 2) { return; } StatRef statRef = null; StatRef statRef2 = null; float num = float.MaxValue; float num2 = float.MinValue; StatRef[] stats = rule.Stats; foreach (StatRef statRef3 in stats) { if (TryReadRef(context, statRef3, out var value)) { float num3 = ((statRef3.Baseline == 0f) ? value : (value / statRef3.Baseline)); if (num3 < num) { num = num3; statRef = statRef3; } if (num3 > num2) { num2 = num3; statRef2 = statRef3; } } } if (statRef != null && statRef2 != null) { float num4 = num + (num2 - num) * Mathf.Clamp01(rule.Value); WriteRef(context, statRef, statRef.Baseline * num4); } } private static void ApplyBalance(EffectRule rule, CardContext context) { if (rule.Stats == null || rule.Stats.Length == 0) { return; } List<Tuple<StatRef, float>> list = new List<Tuple<StatRef, float>>(); double num = 0.0; StatRef[] stats = rule.Stats; foreach (StatRef statRef in stats) { if (TryReadRef(context, statRef, out var value)) { float num2 = Math.Max(0.05f, (statRef.Baseline == 0f) ? value : (value / statRef.Baseline)); list.Add(Tuple.Create(statRef, num2)); num += Math.Log(num2); } } if (list.Count == 0) { return; } float num3 = (float)Math.Exp(num / (double)list.Count); float num4 = Mathf.Clamp01(rule.Value); foreach (Tuple<StatRef, float> item in list) { float num5 = Mathf.Lerp(item.Item2, num3, num4); WriteRef(context, item.Item1, item.Item1.Baseline * num5); } } private static void ApplyPackage(EffectOp[] package, CardContext context) { if (package != null) { for (int i = 0; i < package.Length; i++) { ApplyOperation(package[i], context); } } } private static int CountCards(CardContext context) { object obj = ReadObject(context.Data, "currentCards"); if (obj is ICollection collection) { return collection.Count; } int num = 0; if (obj is IEnumerable enumerable) { foreach (object item in enumerable) { _ = item; num++; } } return num; } private static int CountTheme(CardContext context, string theme) { if (string.IsNullOrEmpty(theme)) { return 0; } object obj = ReadObject(context.Data, "currentCards"); int num = 0; if (obj is IEnumerable enumerable) { foreach (object item in enumerable) { string text = ReadObject(item, "cardName") as string; if (text == null) { text = ReadObject(item, "name") as string; } if (text != null && CardDatabase.ThemeByTitle.TryGetValue(text, out var value) && value == theme) { num++; } } } return num; } private static int CountDistinctThemes(CardContext context) { HashSet<string> hashSet = new HashSet<string>(); if (ReadObject(context.Data, "currentCards") is IEnumerable enumerable) { foreach (object item in enumerable) { string text = ReadObject(item, "cardName") as string; if (text == null) { text = ReadObject(item, "name") as string; } if (text != null && CardDatabase.ThemeByTitle.TryGetValue(text, out var value)) { hashSet.Add(value); } } } return hashSet.Count; } private static int GetPlayerId(Player player) { object obj = ReadObject(player, "playerID"); if (obj is int) { return (int)obj; } if (player != null) { return ((Object)player).GetInstanceID(); } return 0; } private static bool TryReadRef(CardContext context, StatRef stat, out float value) { return TryRead(context.Resolve(stat.Target), stat.Member, out value); } private static void WriteRef(CardContext context, StatRef stat, float value) { WriteClamped(context.Resolve(stat.Target), stat.Member, value); } private static bool TryRead(object target, string member, out float value) { value = 0f; if (target == null) { return false; } MemberInfo memberInfo = FindMember(target.GetType(), member); if (memberInfo == null) { LogMissing(target.GetType(), member); return false; } object value2 = ((memberInfo is FieldInfo fieldInfo) ? fieldInfo.GetValue(target) : ((PropertyInfo)memberInfo).GetValue(target, null)); try { value = Convert.ToSingle(value2); return true; } catch { return false; } } private static void WriteClamped(object target, string member, float value) { if (target == null) { return; } MemberInfo memberInfo = FindMember(target.GetType(), member); if (memberInfo == null) { LogMissing(target.GetType(), member); return; } switch (member) { case "Projectiles": case "MaxAmmo": value = Math.Max(1f, value); break; case "Bounces": case "ExtraBlocks": case "LifeSteal": case "Spread": value = Math.Max(0f, value); break; default: value = Math.Max(0.05f, value); break; } Type type = ((memberInfo is FieldInfo fieldInfo) ? fieldInfo.FieldType : ((PropertyInfo)memberInfo).PropertyType); object value2; if (type == typeof(int)) { value2 = (int)Math.Round(value); } else if (type == typeof(float)) { value2 = value; } else if (type == typeof(double)) { value2 = (double)value; } else { if (!(type == typeof(long))) { return; } value2 = (long)Math.Round(value); } if (memberInfo is FieldInfo fieldInfo2) { fieldInfo2.SetValue(target, value2); return; } PropertyInfo propertyInfo = (PropertyInfo)memberInfo; if (propertyInfo.CanWrite) { propertyInfo.SetValue(target, value2, null); } } private static MemberInfo FindMember(Type type, string logicalName) { if (!Aliases.TryGetValue(logicalName, out var value)) { value = new string[1] { logicalName }; } Type type2 = type; while (type2 != null) { string[] array = value; foreach (string name in array) { FieldInfo field = type2.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } PropertyInfo property = type2.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property; } } type2 = type2.BaseType; } return null; } private static object ReadObject(object target, string member) { if (target == null) { return null; } Type type = target.GetType(); while (type != null) { FieldInfo field = type.GetField(member, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(target); } PropertyInfo property = type.GetProperty(member, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanRead) { return property.GetValue(target, null); } type = type.BaseType; } return null; } private static void LogMissing(Type type, string member) { string text = type.FullName + "." + member; if (MissingLogged.Add(text) && ThemedMayhemPlugin.Log != null) { ThemedMayhemPlugin.Log.LogWarning((object)("Could not find stat field for " + text + "; that modifier was skipped.")); } } } internal enum TargetKind { Gun, Ammo, Character, Gravity, Block } internal enum OpMode { Multiply, Add, Set, Min, Max, MultiplyPerCard, AddPerCard, AddPerCardGroup, MultiplyPerTheme, AddPerThemeGroup, MultiplyPerDistinctTheme } internal enum RuleKind { Convert, ConvertInverse, Swap, BoostLowest, BoostStrongest, MirrorExtreme, Balance, RandomPackage, ThemeThreshold, StatThreshold, RawThreshold, Compare } internal sealed class StatLine { internal readonly bool Positive; internal readonly string Stat; internal readonly string Amount; internal StatLine(bool positive, string stat, string amount) { Positive = positive; Stat = stat; Amount = amount; } } internal sealed class EffectOp { internal readonly TargetKind Target; internal readonly string Member; internal readonly OpMode Mode; internal readonly float Value; internal readonly string Theme; internal EffectOp(TargetKind target, string member, OpMode mode, float value, string theme = null) { Target = target; Member = member; Mode = mode; Value = value; Theme = theme; } } internal sealed class StatRef { internal readonly TargetKind Target; internal readonly string Member; internal readonly float Baseline; internal StatRef(TargetKind target, string member, float baseline) { Target = target; Member = member; Baseline = baseline; } } internal sealed class EffectRule { internal readonly RuleKind Kind; internal StatRef A; internal StatRef B; internal StatRef[] Stats; internal float Value; internal float Threshold; internal string Theme; internal EffectOp[] TrueOps; internal EffectOp[] FalseOps; internal EffectOp[][] Packages; private EffectRule(RuleKind kind) { Kind = kind; } internal static EffectRule Convert(StatRef source, StatRef target, float value, bool inverse = false) { return new EffectRule(inverse ? RuleKind.ConvertInverse : RuleKind.Convert) { A = source, B = target, Value = value }; } internal static EffectRule Swap(StatRef a, StatRef b) { return new EffectRule(RuleKind.Swap) { A = a, B = b }; } internal static EffectRule Extreme(RuleKind kind, StatRef[] stats, float value) { return new EffectRule(kind) { Stats = stats, Value = value }; } internal static EffectRule Random(EffectOp[][] packages) { return new EffectRule(RuleKind.RandomPackage) { Packages = packages }; } internal static EffectRule WhenThreshold(RuleKind kind, StatRef stat, float threshold, EffectOp[] trueOps, EffectOp[] falseOps) { return new EffectRule(kind) { A = stat, Threshold = threshold, TrueOps = trueOps, FalseOps = falseOps }; } internal static EffectRule ThemeThreshold(string theme, float threshold, EffectOp[] trueOps, EffectOp[] falseOps) { return new EffectRule(RuleKind.ThemeThreshold) { Theme = theme, Threshold = threshold, TrueOps = trueOps, FalseOps = falseOps }; } internal static EffectRule Compare(StatRef a, StatRef b, EffectOp[] trueOps, EffectOp[] falseOps) { return new EffectRule(RuleKind.Compare) { A = a, B = b, TrueOps = trueOps, FalseOps = falseOps }; } } internal sealed class CardDefinition { internal readonly int Id; internal readonly string Theme; internal readonly string Title; internal readonly string Description; internal readonly Rarity Rarity; internal readonly string ThemeColor; internal readonly bool AllowMultiple; internal readonly StatLine[] Stats; internal readonly EffectOp[] Operations; internal readonly EffectRule[] Rules; internal CardDefinition(int id, string theme, string title, string description, Rarity rarity, string themeColor, bool allowMultiple, StatLine[] stats, EffectOp[] operations, EffectRule[] rules) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Id = id; Theme = theme; Title = title; Description = description; Rarity = rarity; ThemeColor = themeColor; AllowMultiple = allowMultiple; Stats = stats ?? new StatLine[0]; Operations = operations ?? new EffectOp[0]; Rules = rules ?? new EffectRule[0]; } } internal sealed class CardContext { internal readonly Player Player; internal readonly Gun Gun; internal readonly GunAmmo Ammo; internal readonly CharacterData Data; internal readonly HealthHandler Health; internal readonly Gravity Gravity; internal readonly Block Block; internal readonly CharacterStatModifiers Character; internal CardContext(Player player, Gun gun, GunAmmo ammo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers character) { Player = player; Gun = gun; Ammo = ammo; Data = data; Health = health; Gravity = gravity; Block = block; Character = character; } internal object Resolve(TargetKind target) { return target switch { TargetKind.Gun => Gun, TargetKind.Ammo => Ammo, TargetKind.Character => Character, TargetKind.Gravity => Gravity, TargetKind.Block => Block, _ => null, }; } } } namespace ThemedMayhem.Cards { public sealed class Card001_Railspike : ThemedCardBase { protected override int DefinitionIndex => 0; } public sealed class Card002_PinballProtocol : ThemedCardBase { protected override int DefinitionIndex => 1; } public sealed class Card003_RecoilReactor : ThemedCardBase { protected override int DefinitionIndex => 2; } public sealed class Card004_ScatterCrown : ThemedCardBase { protected override int DefinitionIndex => 3; } public sealed class Card005_NeedleStorm : ThemedCardBase { protected override int DefinitionIndex => 4; } public sealed class Card006_HeavyOrbit : ThemedCardBase { protected override int DefinitionIndex => 5; } public sealed class Card007_KineticBattery : ThemedCardBase { protected override int DefinitionIndex => 6; } public sealed class Card008_RicochetDividend : ThemedCardBase { protected override int DefinitionIndex => 7; } public sealed class Card009_ZeroPointKick : ThemedCardBase { protected override int DefinitionIndex => 8; } public sealed class Card010_TerminalVelocity : ThemedCardBase { protected override int DefinitionIndex => 9; } public sealed class Card011_SplitSecond : ThemedCardBase { protected override int DefinitionIndex => 10; } public sealed class Card012_BorrowedTime : ThemedCardBase { protected override int DefinitionIndex => 11; } public sealed class Card013_StasisMagazine : ThemedCardBase { protected override int DefinitionIndex => 12; } public sealed class Card014_ChronoShield : ThemedCardBase { protected override int DefinitionIndex => 13; } public sealed class Card015_Afterimage : ThemedCardBase { protected override int DefinitionIndex => 14; } public sealed class Card016_TheLongNow : ThemedCardBase { protected override int DefinitionIndex => 15; } public sealed class Card017_TimeDilation : ThemedCardBase { protected override int DefinitionIndex => 16; } public sealed class Card018_FastForward : ThemedCardBase { protected override int DefinitionIndex => 17; } public sealed class Card019_SecondHand : ThemedCardBase { protected override int DefinitionIndex => 18; } public sealed class Card020_ParadoxEngine : ThemedCardBase { protected override int DefinitionIndex => 19; } public sealed class Card021_EmberCore : ThemedCardBase { protected override int DefinitionIndex => 20; } public sealed class Card022_FrostGlass : ThemedCardBase { protected override int DefinitionIndex => 21; } public sealed class Card023_StormCell : ThemedCardBase { protected override int DefinitionIndex => 22; } public sealed class Card024_Stoneheart : ThemedCardBase { protected override int DefinitionIndex => 23; } public sealed class Card025_TidalChamber : ThemedCardBase { protected override int DefinitionIndex => 24; } public sealed class Card026_SolarFlare : ThemedCardBase { protected override int DefinitionIndex => 25; } public sealed class Card027_StaticBloom : ThemedCardBase { protected override int DefinitionIndex => 26; } public sealed class Card028_Permafrost : ThemedCardBase { protected override int DefinitionIndex => 27; } public sealed class Card029_MagmaPressure : ThemedCardBase { protected override int DefinitionIndex => 28; } public sealed class Card030_AuroraPrism : ThemedCardBase { protected override int DefinitionIndex => 29; } public sealed class Card031_EventHorizon : ThemedCardBase { protected override int DefinitionIndex => 30; } public sealed class Card032_NullPoint : ThemedCardBase { protected override int DefinitionIndex => 31; } public sealed class Card033_AbyssalMagazine : ThemedCardBase { protected override int DefinitionIndex => 32; } public sealed class Card034_BlackStar : ThemedCardBase { protected override int DefinitionIndex => 33; } public sealed class Card035_VacuumStep : ThemedCardBase { protected override int DefinitionIndex => 34; } public sealed class Card036_EntropyTax : ThemedCardBase { protected override int DefinitionIndex => 35; } public sealed class Card037_Unmake : ThemedCardBase { protected override int DefinitionIndex => 36; } public sealed class Card038_DarkMatter : ThemedCardBase { protected override int DefinitionIndex => 37; } public sealed class Card039_SingularityDividend : ThemedCardBase { protected override int DefinitionIndex => 38; } public sealed class Card040_RedShift : ThemedCardBase { protected override int DefinitionIndex => 39; } public sealed class Card041_Autoloader : ThemedCardBase { protected override int DefinitionIndex => 40; } public sealed class Card042_BurstCompiler : ThemedCardBase { protected override int DefinitionIndex => 41; } public sealed class Card043_Overclock : ThemedCardBase { protected override int DefinitionIndex => 42; } public sealed class Card044_SafetyInterlock : ThemedCardBase { protected override int DefinitionIndex => 43; } public sealed class Card045_Gyroscope : ThemedCardBase { protected override int DefinitionIndex => 44; } public sealed class Card046_DuplexBarrel : ThemedCardBase { protected override int DefinitionIndex => 45; } public sealed class Card047_CapacitorBank : ThemedCardBase { protected override int DefinitionIndex => 46; } public sealed class Card048_AdaptiveChassis : ThemedCardBase { protected override int DefinitionIndex => 47; } public sealed class Card049_WorkshopWarranty : ThemedCardBase { protected override int DefinitionIndex => 48; } public sealed class Card050_RecursiveUpgrade : ThemedCardBase { protected override int DefinitionIndex => 49; } public sealed class Card051_ThickHide : ThemedCardBase { protected override int DefinitionIndex => 50; } public sealed class Card052_HollowBones : ThemedCardBase { protected override int DefinitionIndex => 51; } public sealed class Card053_AdrenalGland : ThemedCardBase { protected override int DefinitionIndex => 52; } public sealed class Card054_VenomSac : ThemedCardBase { protected override int DefinitionIndex => 53; } public sealed class Card055_RegenerativeTissue : ThemedCardBase { protected override int DefinitionIndex => 54; } public sealed class Card056_CompoundEyes : ThemedCardBase { protected override int DefinitionIndex => 55; } public sealed class Card057_MuscleMemory : ThemedCardBase { protected override int DefinitionIndex => 56; } public sealed class Card058_ParasiticChamber : ThemedCardBase { protected override int DefinitionIndex => 57; } public sealed class Card059_ChitinPlating : ThemedCardBase { protected override int DefinitionIndex => 58; } public sealed class Card060_ApexMutation : ThemedCardBase { protected override int DefinitionIndex => 59; } public sealed class Card061_FalsePositive : ThemedCardBase { protected override int DefinitionIndex => 60; } public sealed class Card062_LoadedDice : ThemedCardBase { protected override int DefinitionIndex => 61; } public sealed class Card063_SmokeScreen : ThemedCardBase { protected override int DefinitionIndex => 62; } public sealed class Card064_DecoyRound : ThemedCardBase { protected override int DefinitionIndex => 63; } public sealed class Card065_SleightofHand : ThemedCardBase { protected override int DefinitionIndex => 64; } public sealed class Card066_CrookedBarrel : ThemedCardBase { protected override int DefinitionIndex => 65; } public sealed class Card067_MirrorMatch : ThemedCardBase { protected override int DefinitionIndex => 66; } public sealed class Card068_MisfireInsurance : ThemedCardBase { protected override int DefinitionIndex => 67; } public sealed class Card069_HouseEdge : ThemedCardBase { protected override int DefinitionIndex => 68; } public sealed class Card070_VanishingPoint : ThemedCardBase { protected override int DefinitionIndex => 69; } public sealed class Card071_CompoundInterest : ThemedCardBase { protected override int DefinitionIndex => 70; } public sealed class Card072_BulkDiscount : ThemedCardBase { protected override int DefinitionIndex => 71; } public sealed class Card073_DiversifiedPortfolio : ThemedCardBase { protected override int DefinitionIndex => 72; } public sealed class Card074_LiquidAssets : ThemedCardBase { protected override int DefinitionIndex => 73; } public sealed class Card075_HostileTakeover : ThemedCardBase { protected override int DefinitionIndex => 74; } public sealed class Card076_InsurancePolicy : ThemedCardBase { protected override int DefinitionIndex => 75; } public sealed class Card077_VentureCapital : ThemedCardBase { protected override int DefinitionIndex => 76; } public sealed class Card078_Cashback : ThemedCardBase { protected override int DefinitionIndex => 77; } public sealed class Card079_Monopoly : ThemedCardBase { protected override int DefinitionIndex => 78; } public sealed class Card080_GoldenRatio : ThemedCardBase { protected override int DefinitionIndex => 79; } public sealed class Card081_BloodPrice : ThemedCardBase { protected override int DefinitionIndex => 80; } public sealed class Card082_EmptyChamber : ThemedCardBase { protected override int DefinitionIndex => 81; } public sealed class Card083_LeadFeet : ThemedCardBase { protected override int DefinitionIndex => 82; } public sealed class Card084_GlassEngine : ThemedCardBase { protected override int DefinitionIndex => 83; } public sealed class Card085_BrokenShield : ThemedCardBase { protected override int DefinitionIndex => 84; } public sealed class Card086_SmallOffering : ThemedCardBas