diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java index 7607398cd73..e5bfcd5100f 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java @@ -347,6 +347,9 @@ public final class AbilityFactory { if (mapParams.containsKey("TargetsWithDifferentControllers")) { abTgt.setDifferentControllers(true); } + if (mapParams.containsKey("TargetsWithDifferentCMC")) { + abTgt.setDifferentCMC(true); + } if (mapParams.containsKey("DividedAsYouChoose")) { abTgt.calculateStillToDivide(mapParams.get("DividedAsYouChoose"), null, null); abTgt.setDividedAsYouChoose(true); diff --git a/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java b/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java index 84cf024fd13..0173a998029 100644 --- a/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java +++ b/forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java @@ -62,6 +62,7 @@ public class TargetRestrictions { private boolean uniqueTargets = false; private boolean singleZone = false; private boolean differentControllers = false; + private boolean differentCMC = false; private boolean sameController = false; private boolean withoutSameCreatureType = false; private boolean withSameCreatureType = false; @@ -105,6 +106,7 @@ public class TargetRestrictions { this.uniqueTargets = target.isUniqueTargets(); this.singleZone = target.isSingleZone(); this.differentControllers = target.isDifferentControllers(); + this.differentCMC = target.isDifferentCMC(); this.sameController = target.isSameController(); this.withoutSameCreatureType = target.isWithoutSameCreatureType(); this.withSameCreatureType = target.isWithSameCreatureType(); @@ -675,6 +677,19 @@ public class TargetRestrictions { this.randomTarget = random; } + /** + * @return the differentCMC + */ + public boolean isDifferentCMC() { + return differentCMC; + } + + /** + * @param different the differentCMC to set + */ + public void setDifferentCMC(boolean different) { + this.differentCMC = different; + } /** * @return the differentControllers */ diff --git a/forge-gui/res/cardsfolder/upcoming/ZNR/agadeems_awakening_agadeem_the_undercrypt.txt b/forge-gui/res/cardsfolder/upcoming/ZNR/agadeems_awakening_agadeem_the_undercrypt.txt new file mode 100644 index 00000000000..41acc5cc7d9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ZNR/agadeems_awakening_agadeem_the_undercrypt.txt @@ -0,0 +1,19 @@ +Name:Agadeem's Awakening +ManaCost:X B B B +Types:Sorcery +A:SP$ ChangeZone | Cost$ X B B B | Origin$ Graveyard | Destination$ Battlefield | TargetMin$ 0 | TargetMax$ Y | ValidTgts$ Creature.YouOwn+cmcLEX | TgtPrompt$ Select any number of target creature cards in your graveyard with different converted mana costs X or less | TargetsWithDifferentCMC$ True | References$ X,Y | StackDescription$ {p:You} returns {c:Targeted} from the graveyard to the battlefield. | SpellDescription$ Return from your graveyard to the battlefield any number of target creature cards that each have a different converted mana cost X or less. +SVar:X:Count$xPaid +SVar:Y:Count$ValidGraveyard Creature.YouOwn +AlternateMode:Modal +DeckHas:Ability$Graveyard +Oracle:Return from your graveyard to the battlefield any number of target creature cards that each have a different converted mana cost X or less. + +ALTERNATE + +Name:Agadeem, the Undercrypt +ManaCost:no cost +Types:Land +K:ETBReplacement:Other:DBTap +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | UnlessAI$ Shockland | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. +A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}. +Oracle:As Agadeem, the Undercrypt enters the battlefield, you may pay 3 life. If you don’t, it enters the battlefield tapped.\n{T}: Add {B}. diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java index 5de5545d36e..4609a4a2981 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java @@ -189,7 +189,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { } } - // If all cards must have different controllers + // If all cards must have same controllers if (tgt.isSameController()) { final List targetedControllers = new ArrayList<>(); for (final GameObject o : targetDepth.keySet()) { @@ -219,6 +219,21 @@ public final class InputSelectTargets extends InputSyncronizedBase { } } + // If all cards must have different CMC + if (tgt.isDifferentCMC()) { + final List targetedCMCs = new ArrayList<>(); + for (final GameObject o : targetDepth.keySet()) { + if (o instanceof Card) { + final Integer cmc = ((Card) o).getCMC(); + targetedCMCs.add(cmc); + } + } + if (targetedCMCs.contains(card.getCMC())) { + showMessage(sa.getHostCard() + " - Cannot target this card (must have different CMC)"); + return false; + } + } + if (!choices.contains(card)) { showMessage(sa.getHostCard() + " - The selected card is not a valid choice to be targeted."); return false;