From acb21b2a28634510f913d70f45c0ec2af11881fd Mon Sep 17 00:00:00 2001 From: Adam Pantel <> Date: Sat, 6 Mar 2021 15:58:01 -0500 Subject: [PATCH] [Un-cards] DeckLimit keyword + Cardboard Carapace --- forge-core/src/main/java/forge/card/CardRules.java | 10 ++++++++++ forge-core/src/main/java/forge/deck/DeckFormat.java | 8 +------- forge-game/src/main/java/forge/game/card/Card.java | 8 +++++--- .../src/main/java/forge/game/keyword/Keyword.java | 1 - forge-gui/res/cardsfolder/c/cardboard_carapace.txt | 8 ++++++++ forge-gui/res/cardsfolder/g/gleemox.txt | 6 ++++++ forge-gui/res/cardsfolder/o/once_more_with_feeling.txt | 10 ++++++++++ forge-gui/res/cardsfolder/s/seven_dwarves.txt | 2 +- forge-gui/res/cardsfolder/v/vazal_the_compleat.txt | 2 +- forge-gui/res/editions/Online Promos.txt | 2 +- 10 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 forge-gui/res/cardsfolder/c/cardboard_carapace.txt create mode 100644 forge-gui/res/cardsfolder/g/gleemox.txt create mode 100644 forge-gui/res/cardsfolder/o/once_more_with_feeling.txt diff --git a/forge-core/src/main/java/forge/card/CardRules.java b/forge-core/src/main/java/forge/card/CardRules.java index 1023b6a13d4..130efe627bc 100644 --- a/forge-core/src/main/java/forge/card/CardRules.java +++ b/forge-core/src/main/java/forge/card/CardRules.java @@ -569,4 +569,14 @@ public final class CardRules implements ICardCharacteristics { public boolean hasKeyword(final String k) { return Iterables.contains(mainPart.getKeywords(), k); } + + public Integer getKeywordMagnitude(final String k) { + for (final String inst : mainPart.getKeywords()) { + final String[] parts = inst.split(":"); + if (parts[0].equals(k) && StringUtils.isNumeric(parts[1])) { + return Integer.valueOf(parts[1]); + } + } + return null; + } } diff --git a/forge-core/src/main/java/forge/deck/DeckFormat.java b/forge-core/src/main/java/forge/deck/DeckFormat.java index 96e4634daaa..17a622f1d18 100644 --- a/forge-core/src/main/java/forge/deck/DeckFormat.java +++ b/forge-core/src/main/java/forge/deck/DeckFormat.java @@ -375,13 +375,7 @@ public enum DeckFormat { public static Integer canHaveSpecificNumberInDeck(final IPaperCard card) { // Ideally, this would be parsed during card parsing and set this value - if (card.getRules().hasKeyword("A deck can have up to seven cards named CARDNAME.")) { - return 7; - } else if (card.getRules().hasKeyword("Megalegendary")) { - return 1; - } - - return null; + return card.getRules().getKeywordMagnitude("DeckLimit"); } public static String getPlaneSectionConformanceProblem(final CardPool planes) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 0b504ba35e1..7d73ce72fa6 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1846,7 +1846,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { s.append(" on it."); } sbLong.append(s).append("\r\n"); - } else if (keyword.startsWith("Protection:")) { + } else if (keyword.startsWith("Protection:") || keyword.startsWith("DeckLimit")) { final String[] k = keyword.split(":"); sbLong.append(k[2]).append("\r\n"); } else if (keyword.startsWith("Creatures can't attack unless their controller pays")) { @@ -1966,8 +1966,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { || keyword.equals("Foretell") // for the ones without cost || keyword.equals("Hideaway") || keyword.equals("Ascend") || keyword.equals("Totem armor") || keyword.equals("Battle cry") - || keyword.equals("Devoid") || keyword.equals("Riot") - || keyword.equals("Megalegendary")){ + || keyword.equals("Devoid") || keyword.equals("Riot")){ sbLong.append(keyword).append(" (").append(inst.getReminderText()).append(")"); } else if (keyword.startsWith("Partner:")) { final String[] k = keyword.split(":"); @@ -2483,6 +2482,9 @@ public class Card extends GameEntity implements Comparable, IHasSVars { sbBefore.append(" You may choose new targets for the copies."); } sbBefore.append(")\r\n"); + } else if (keyword.startsWith("DeckLimit")) { + final String[] k = keyword.split(":"); + sbBefore.append(k[2]).append("\r\n"); } } catch (Exception e) { String msg = "Card:abilityTextInstantSorcery: crash in Keyword parsing"; diff --git a/forge-game/src/main/java/forge/game/keyword/Keyword.java b/forge-game/src/main/java/forge/game/keyword/Keyword.java index 4c449db50a4..e9db55ac11a 100644 --- a/forge-game/src/main/java/forge/game/keyword/Keyword.java +++ b/forge-game/src/main/java/forge/game/keyword/Keyword.java @@ -92,7 +92,6 @@ public enum Keyword { LIFELINK("Lifelink", SimpleKeyword.class, true, "Damage dealt by this creature also causes its controller to gain that much life."), LIVING_WEAPON("Living weapon", SimpleKeyword.class, true, "When this Equipment enters the battlefield, create a 0/0 black Germ creature token, then attach this to it."), MADNESS("Madness", KeywordWithCost.class, false, "If you discard this card, discard it into exile. When you do, cast it for %s or put it into your graveyard."), - MEGALEGENDARY("Megalegendary", SimpleKeyword.class, true, "Your deck can have only one copy of this card."), MELEE("Melee", SimpleKeyword.class, false, "Whenever this creature attacks, it gets +1/+1 until end of turn for each opponent you attacked this combat."), MENTOR("Mentor", SimpleKeyword.class, false, "Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power."), MENACE("Menace", SimpleKeyword.class, true, "This creature can't be blocked except by two or more creatures."), diff --git a/forge-gui/res/cardsfolder/c/cardboard_carapace.txt b/forge-gui/res/cardsfolder/c/cardboard_carapace.txt new file mode 100644 index 00000000000..1b27f7e6496 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/cardboard_carapace.txt @@ -0,0 +1,8 @@ +Name:Cardboard Carapace +ManaCost:5 G +Types:Enchantment Aura +K:Enchant creature +A:SP$ Attach | Cost$ 5 G | ValidTgts$ Creature | AILogic$ Pump +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ X | AddToughness$ X | Description$ For each other card named Cardboard Carapace you have with you outside the game, enchanted creature gets +1/+1. +SVar:X:Count$ValidSideboard Card.namedCardboard Carapace +Oracle:Enchant creature\nFor each other card named Cardboard Carapace you have with you outside the game, enchanted creature gets +1/+1. diff --git a/forge-gui/res/cardsfolder/g/gleemox.txt b/forge-gui/res/cardsfolder/g/gleemox.txt new file mode 100644 index 00000000000..33b7de4847b --- /dev/null +++ b/forge-gui/res/cardsfolder/g/gleemox.txt @@ -0,0 +1,6 @@ +Name:Gleemox +ManaCost:0 +Types:Artifact +K:DeckLimit:0:This card is banned. +A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color. +Oracle:{T}: Add one mana of any color.\nThis card is banned. diff --git a/forge-gui/res/cardsfolder/o/once_more_with_feeling.txt b/forge-gui/res/cardsfolder/o/once_more_with_feeling.txt new file mode 100644 index 00000000000..56b83d811ef --- /dev/null +++ b/forge-gui/res/cardsfolder/o/once_more_with_feeling.txt @@ -0,0 +1,10 @@ +Name:Once More with Feeling +ManaCost:W W W W +Types:Sorcery +K:DeckLimit:1:DCI ruling - A deck can have only one card named Once More with Feeling. +A:SP$ ChangeZoneAll | Cost$ W W W W | ChangeType$ Permanent | Origin$ Battlefield,Graveyard | Destination$ Exile | SubAbility$ DBShuffle | SpellDescription$ Exile all permanents and all cards from all graveyards. Each player shuffles their hand into their library, then draws seven cards. Each player’s life total becomes 10. Exile CARDNAME. +SVar:DBShuffle:DB$ ChangeZoneAll | ChangeType$ Card | Origin$ Hand | Destination$ Library | Shuffle$ True | Random$ True | UseAllOriginZones$ True | SubAbility$ DBDraw | StackDescription$ None +SVar:DBDraw:DB$ Draw | NumCards$ 7 | Defined$ Player | SubAbility$ SetAllLife | StackDescription$ None +SVar:SetAllLife:DB$ SetLife | Defined$ Player | LifeAmount$ 10 | SubAbility$ ExileSelf | StackDescription$ None +SVar:ExileSelf:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | StackDescription$ None +Oracle:Exile all permanents and all cards from all graveyards. Each player shuffles their hand into their library, then draws seven cards. Each player’s life total becomes 10. Exile Once More with Feeling.\nDCI ruling — A deck can have only one card named Once More with Feeling. diff --git a/forge-gui/res/cardsfolder/s/seven_dwarves.txt b/forge-gui/res/cardsfolder/s/seven_dwarves.txt index cfcb179752d..fefa5a16739 100644 --- a/forge-gui/res/cardsfolder/s/seven_dwarves.txt +++ b/forge-gui/res/cardsfolder/s/seven_dwarves.txt @@ -2,7 +2,7 @@ Name:Seven Dwarves ManaCost:1 R Types:Creature Dwarf PT:2/2 -K:A deck can have up to seven cards named CARDNAME. +K:DeckLimit:7:A deck can have up to seven cards named CARDNAME. S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | AddToughness$ X | References$ X | Description$ CARDNAME gets +1/+1 for each other creature named Seven Dwarves you control. SVar:X:Count$Valid Creature.namedSeven Dwarves+Other+YouCtrl SVar:BuffedBy:Creature.namedSeven Dwarves diff --git a/forge-gui/res/cardsfolder/v/vazal_the_compleat.txt b/forge-gui/res/cardsfolder/v/vazal_the_compleat.txt index 3ea1c5101cb..2c2ee2c0b74 100644 --- a/forge-gui/res/cardsfolder/v/vazal_the_compleat.txt +++ b/forge-gui/res/cardsfolder/v/vazal_the_compleat.txt @@ -2,7 +2,7 @@ Name:Vazal, the Compleat ManaCost:3 G G G Types:Legendary Artifact Creature Phyrexian PT:7/7 -K:Megalegendary +K:DeckLimit:1:Megalegendary (Your deck can have only one copy of this card.) K:Vigilance K:Trample S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ Battlefield | GainsAbilitiesOf$ Permanent.Other | Description$ CARDNAME has all activated abilities of each other permanent on the battlefield. diff --git a/forge-gui/res/editions/Online Promos.txt b/forge-gui/res/editions/Online Promos.txt index af515bfbcc0..7fd7b0e94d7 100644 --- a/forge-gui/res/editions/Online Promos.txt +++ b/forge-gui/res/editions/Online Promos.txt @@ -245,4 +245,4 @@ Type=Reprint 238 S Zodiac Snake 239 S Zodiac Tiger 240 S Zuran Orb - +26584 S Gleemox