pdAllowed = new HashMap<>();
public Oathbreaker() {
- super();
- setName("Oathbreaker");
+ super("Oathbreaker");
// banned = vintage + oathbreaker's list: https://oathbreakermtg.org/banned-list/
banned.add("Ad Nauseam");
@@ -31,21 +31,14 @@ public class Oathbreaker extends Vintage {
banned.add("Biorhythm");
banned.add("Black Lotus");
banned.add("Channel");
- banned.add("Chaos Orb");
- banned.add("Cleanse");
- banned.add("Crusade");
banned.add("Dark Ritual");
banned.add("Doomsday");
banned.add("Emrakul, the Aeons Torn");
banned.add("Expropriate");
- banned.add("Falling Star");
banned.add("Fastbond");
banned.add("Gifts Ungiven");
banned.add("Griselbrand");
banned.add("High Tide");
- banned.add("Imprison");
- banned.add("Invoke Prejudice");
- banned.add("Jihad");
banned.add("Jeweled Lotus");
banned.add("Library of Alexandria");
banned.add("Limited Resources");
@@ -61,12 +54,9 @@ public class Oathbreaker extends Vintage {
banned.add("Natural Order");
banned.add("Painter's Servant");
banned.add("Panoptic Mirror");
- banned.add("Pradesh Gypsies");
banned.add("Primal Surge");
banned.add("Saheeli, the Gifted");
- banned.add("Shahrazad");
banned.add("Sol Ring");
- banned.add("Stone-Throwing Devils");
banned.add("Sundering Titan");
banned.add("Sylvan Primordial");
banned.add("Time Vault");
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394.java
index 66d06ee8287..de9f72c486c 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394.java
@@ -1,20 +1,16 @@
-
package mage.deck;
-import mage.cards.ExpansionSet;
-import mage.cards.Sets;
import mage.cards.decks.Constructed;
-import mage.constants.SetType;
/**
* This class validates a deck for the Old School 93/94 format.
- *
+ *
* This was originally made to follow the deck construction rules found at the
* Old School Mtg blog found at:
* http://oldschool-mtg.blogspot.com/p/banrestriction.html
- *
+ *
* There is no mana burn in this version of old school.
- *
+ *
* If there are any questions or corrections, feel free to contact me.
*
* @author Marthinwurer (at gmail.com)
@@ -33,31 +29,6 @@ public class OldSchool9394 extends Constructed {
setCodes.add(mage.sets.Legends.getInstance().getCode());
setCodes.add(mage.sets.TheDark.getInstance().getCode());
- // ante cards and conspiracies banned, with specifically mentioned ones called out.
- banned.add("Advantageous Proclamation");
- banned.add("Amulet of Quoz");
- banned.add("Backup Plan");
- banned.add("Brago's Favor");
- banned.add("Bronze Tablet"); ///
- banned.add("Contract from Below"); ///
- banned.add("Darkpact"); ///
- banned.add("Demonic Attorney"); ///
- banned.add("Double Stroke");
- banned.add("Immediate Action");
- banned.add("Iterative Analysis");
- banned.add("Jeweled Bird"); ///
- banned.add("Muzzio's Preparations");
- banned.add("Power Play");
- banned.add("Rebirth"); ///
- banned.add("Secret Summoning");
- banned.add("Secrets of Paradise");
- banned.add("Sentinel Dispatch");
- banned.add("Shahrazad");
- banned.add("Tempest Efreet"); ///
- banned.add("Timmerian Fiends");
- banned.add("Unexpected Potential");
- banned.add("Worldknit");
-
restricted.add("Ancestral Recall");
restricted.add("Balance");
restricted.add("Black Lotus");
@@ -82,6 +53,5 @@ public class OldSchool9394 extends Constructed {
restricted.add("Time Walk");
restricted.add("Timetwister");
restricted.add("Wheel of Fortune");
-
}
}
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394CFB.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394CFB.java
index a9f38181ac9..4a2d0cb1f07 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394CFB.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394CFB.java
@@ -29,30 +29,6 @@ public class OldSchool9394CFB extends Constructed {
setCodes.add(mage.sets.TheDark.getInstance().getCode());
setCodes.add(mage.sets.FallenEmpires.getInstance().getCode());
- // ante cards and conspiracies banned, with specifically mentioned ones called out.
- banned.add("Advantageous Proclamation");
- banned.add("Amulet of Quoz");
- banned.add("Backup Plan");
- banned.add("Brago's Favor");
- banned.add("Bronze Tablet"); ///
- banned.add("Contract from Below"); ///
- banned.add("Darkpact"); ///
- banned.add("Demonic Attorney"); ///
- banned.add("Double Stroke");
- banned.add("Immediate Action");
- banned.add("Iterative Analysis");
- banned.add("Jeweled Bird"); ///
- banned.add("Muzzio's Preparations");
- banned.add("Power Play");
- banned.add("Rebirth"); ///
- banned.add("Secret Summoning");
- banned.add("Secrets of Paradise");
- banned.add("Sentinel Dispatch");
- banned.add("Tempest Efreet"); ///
- banned.add("Timmerian Fiends");
- banned.add("Unexpected Potential");
- banned.add("Worldknit");
-
//Let Media Inserts Arena and Sewers of Estark being only cards playable
banned.add("Acquire");
banned.add("Aeronaut Tinkerer");
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EC.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EC.java
index 49a5cf564a7..73e70d2b912 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EC.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EC.java
@@ -29,31 +29,6 @@ public class OldSchool9394EC extends Constructed {
setCodes.add(mage.sets.TheDark.getInstance().getCode());
setCodes.add(mage.sets.FallenEmpires.getInstance().getCode());
- // ante cards and conspiracies banned, with specifically mentioned ones called out.
- banned.add("Advantageous Proclamation");
- banned.add("Amulet of Quoz");
- banned.add("Backup Plan");
- banned.add("Brago's Favor");
- banned.add("Bronze Tablet"); ///
- banned.add("Contract from Below"); ///
- banned.add("Darkpact"); ///
- banned.add("Demonic Attorney"); ///
- banned.add("Double Stroke");
- banned.add("Immediate Action");
- banned.add("Iterative Analysis");
- banned.add("Jeweled Bird"); ///
- banned.add("Muzzio's Preparations");
- banned.add("Power Play");
- banned.add("Rebirth"); ///
- banned.add("Secret Summoning");
- banned.add("Secrets of Paradise");
- banned.add("Sentinel Dispatch");
- banned.add("Shahrazad");
- banned.add("Tempest Efreet"); ///
- banned.add("Timmerian Fiends");
- banned.add("Unexpected Potential");
- banned.add("Worldknit");
-
//Let Media Inserts Arena and Sewers of Estark being only cards playable
banned.add("Acquire");
banned.add("Aeronaut Tinkerer");
@@ -262,5 +237,4 @@ public class OldSchool9394EC extends Constructed {
restricted.add("Timetwister");
restricted.add("Wheel of Fortune");
}
-
}
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EG.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EG.java
index 3ce11e196af..753ef772b85 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EG.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394EG.java
@@ -1,29 +1,25 @@
-
package mage.deck;
-import mage.cards.ExpansionSet;
-import mage.cards.Sets;
import mage.cards.decks.Constructed;
-import mage.constants.SetType;
/**
* This class validates a deck for the Old School 93/94 format, specifically the
* EudoGames Rules.
- *
+ *
* This was originally made to follow the deck construction rules found at the
* Old School Mtg blog found at:
* http://oldschool-mtg.blogspot.com/p/banrestriction.html
- *
+ *
* There is no mana burn in this version of old school.
*
* @author jmharmon
*/
public class OldSchool9394EG extends Constructed {
-
+
public OldSchool9394EG() {
super("Constructed - Old School 93/94 - EudoGames Rules");
-
- // use the set instances to make sure that we get the correct set codes
+
+ // use the set instances to make sure that we get the correct set codes
setCodes.add(mage.sets.LimitedEditionAlpha.getInstance().getCode());
setCodes.add(mage.sets.LimitedEditionBeta.getInstance().getCode());
setCodes.add(mage.sets.UnlimitedEdition.getInstance().getCode());
@@ -34,32 +30,7 @@ public class OldSchool9394EG extends Constructed {
setCodes.add(mage.sets.RevisedEdition.getInstance().getCode());
setCodes.add(mage.sets.FallenEmpires.getInstance().getCode());
setCodes.add(mage.sets.Chronicles.getInstance().getCode());
-
- // ante cards and conspiracies banned, with specifically mentioned ones called out.
- banned.add("Advantageous Proclamation");
- banned.add("Amulet of Quoz");
- banned.add("Backup Plan");
- banned.add("Brago's Favor");
- banned.add("Bronze Tablet"); ///
- banned.add("Contract from Below"); ///
- banned.add("Darkpact"); ///
- banned.add("Demonic Attorney"); ///
- banned.add("Double Stroke");
- banned.add("Immediate Action");
- banned.add("Iterative Analysis");
- banned.add("Jeweled Bird"); ///
- banned.add("Muzzio's Preparations");
- banned.add("Power Play");
- banned.add("Rebirth"); ///
- banned.add("Secret Summoning");
- banned.add("Secrets of Paradise");
- banned.add("Sentinel Dispatch");
- banned.add("Shahrazad");
- banned.add("Tempest Efreet"); ///
- banned.add("Timmerian Fiends");
- banned.add("Unexpected Potential");
- banned.add("Worldknit");
-
+
restricted.add("Ancestral Recall");
restricted.add("Balance");
restricted.add("Black Lotus");
@@ -88,5 +59,4 @@ public class OldSchool9394EG extends Constructed {
restricted.add("Timetwister");
restricted.add("Wheel of Fortune");
}
-
}
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394Italian.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394Italian.java
index c5e97d44b19..c160a13cdf2 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394Italian.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/OldSchool9394Italian.java
@@ -1,28 +1,25 @@
package mage.deck;
-import mage.cards.ExpansionSet;
-import mage.cards.Sets;
import mage.cards.decks.Constructed;
-import mage.constants.SetType;
/**
* This class validates a deck for the Old School 93/94 format, specifically for
* the Italian Rules.
- *
+ *
* This was originally made to follow the deck construction rules found at the
* Old School Mtg blog found at:
* http://oldschool-mtg.blogspot.com/p/banrestriction.html
- *
+ *
* There is no mana burn in this version of old school
*
* @author jmharmon
*/
-public class OldSchool9394Italian extends Constructed{
-
+public class OldSchool9394Italian extends Constructed {
+
public OldSchool9394Italian() {
super("Constructed - Old School 93/94 - Italian Rules");
-
+
// use the set instances to make sure that we get the correct set codes
setCodes.add(mage.sets.LimitedEditionAlpha.getInstance().getCode());
setCodes.add(mage.sets.LimitedEditionBeta.getInstance().getCode());
@@ -32,32 +29,7 @@ public class OldSchool9394Italian extends Constructed{
setCodes.add(mage.sets.Legends.getInstance().getCode());
setCodes.add(mage.sets.TheDark.getInstance().getCode());
setCodes.add(mage.sets.RevisedEdition.getInstance().getCode());
-
- // ante cards and conspiracies banned, with specifically mentioned ones called out.
- banned.add("Advantageous Proclamation");
- banned.add("Amulet of Quoz");
- banned.add("Backup Plan");
- banned.add("Brago's Favor");
- banned.add("Bronze Tablet"); ///
- banned.add("Contract from Below"); ///
- banned.add("Darkpact"); ///
- banned.add("Demonic Attorney"); ///
- banned.add("Double Stroke");
- banned.add("Immediate Action");
- banned.add("Iterative Analysis");
- banned.add("Jeweled Bird"); ///
- banned.add("Muzzio's Preparations");
- banned.add("Power Play");
- banned.add("Rebirth"); ///
- banned.add("Secret Summoning");
- banned.add("Secrets of Paradise");
- banned.add("Sentinel Dispatch");
- banned.add("Shahrazad");
- banned.add("Tempest Efreet"); ///
- banned.add("Timmerian Fiends");
- banned.add("Unexpected Potential");
- banned.add("Worldknit");
-
+
restricted.add("Ancestral Recall");
restricted.add("Balance");
restricted.add("Black Lotus");
@@ -82,6 +54,5 @@ public class OldSchool9394Italian extends Constructed{
restricted.add("Time Walk");
restricted.add("Timetwister");
restricted.add("Wheel of Fortune");
-
}
}
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pauper.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pauper.java
index 0b44ef683e8..af5dc6536da 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pauper.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pauper.java
@@ -29,10 +29,11 @@ public class Pauper extends Constructed {
banned.add("Cloudpost");
banned.add("Cranial Plating");
banned.add("Daze");
+ banned.add("Disciple of the Vault");
banned.add("Empty the Warrens");
- banned.add("Expedition Map");
banned.add("Fall from Favor");
banned.add("Frantic Search");
+ banned.add("Galvanic Relay");
banned.add("Gitaxian Probe");
banned.add("Grapeshot");
banned.add("Gush");
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java
index 0e5289d4c75..49f01d483fb 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java
@@ -1,33 +1,22 @@
package mage.deck;
-import mage.abilities.Ability;
-import mage.abilities.common.CanBeYourCommanderAbility;
-import mage.abilities.keyword.CompanionAbility;
-import mage.abilities.keyword.PartnerAbility;
-import mage.abilities.keyword.PartnerWithAbility;
-import mage.cards.Card;
import mage.cards.ExpansionSet;
import mage.cards.Sets;
-import mage.cards.decks.Constructed;
-import mage.cards.decks.Deck;
import mage.cards.decks.DeckValidatorErrorType;
import mage.cards.decks.PennyDreadfulLegalityUtil;
-import mage.constants.CardType;
-import mage.filter.FilterMana;
-import mage.util.ManaUtil;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
/**
* @author spjspj
*/
-public class PennyDreadfulCommander extends Constructed {
+public class PennyDreadfulCommander extends AbstractCommander {
- protected List bannedCommander = new ArrayList<>();
private static final Map pdAllowed = new HashMap<>();
public PennyDreadfulCommander() {
- super("Penny Dreadful Commander", "Penny");
+ super("Penny Dreadful Commander");
for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType().isEternalLegal()) {
setCodes.add(set.getCode());
@@ -36,168 +25,17 @@ public class PennyDreadfulCommander extends Constructed {
}
@Override
- public int getDeckMinSize() {
- return 98;
- }
-
- @Override
- public int getSideboardMinSize() {
- return 1;
- }
-
- @Override
- public boolean validate(Deck deck) {
- boolean valid = true;
- errorsList.clear();
- FilterMana colorIdentity = new FilterMana();
- Set commanders = new HashSet<>();
- Card companion = null;
-
- if (deck.getSideboard().size() == 1) {
- commanders.add(deck.getSideboard().iterator().next());
- } else if (deck.getSideboard().size() == 2) {
- Iterator iter = deck.getSideboard().iterator();
- Card card1 = iter.next();
- Card card2 = iter.next();
- if (card1.getAbilities().stream().anyMatch(ability -> ability instanceof CompanionAbility)) {
- companion = card1;
- commanders.add(card2);
- } else if (card2.getAbilities().stream().anyMatch(ability -> ability instanceof CompanionAbility)) {
- companion = card2;
- commanders.add(card1);
- } else {
- commanders.add(card1);
- commanders.add(card2);
- }
- } else if (deck.getSideboard().size() == 3) {
- Iterator iter = deck.getSideboard().iterator();
- Card card1 = iter.next();
- Card card2 = iter.next();
- Card card3 = iter.next();
- if (card1.getAbilities().stream().anyMatch(ability -> ability instanceof CompanionAbility)) {
- companion = card1;
- commanders.add(card2);
- commanders.add(card3);
- } else if (card2.getAbilities().stream().anyMatch(ability -> ability instanceof CompanionAbility)) {
- companion = card2;
- commanders.add(card1);
- commanders.add(card3);
- } else if (card3.getAbilities().stream().anyMatch(ability -> ability instanceof CompanionAbility)) {
- companion = card3;
- commanders.add(card1);
- commanders.add(card2);
- } else {
- addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
- valid = false;
- }
- } else {
- addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
- valid = false;
- }
-
- if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
- addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
- valid = false;
- } else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
- addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
- valid = false;
- }
-
- Map counts = new HashMap<>();
- countCards(counts, deck.getCards());
- countCards(counts, deck.getSideboard());
- valid = checkCounts(1, counts) && valid;
-
+ protected boolean checkBanned(Map counts) {
if (pdAllowed.isEmpty()) {
pdAllowed.putAll(PennyDreadfulLegalityUtil.getLegalCardList());
}
-
+ boolean valid = true;
for (String wantedCard : counts.keySet()) {
if (!(pdAllowed.containsKey(wantedCard))) {
addError(DeckValidatorErrorType.BANNED, wantedCard, "Banned", true);
valid = false;
}
}
-
- Set commanderNames = new HashSet<>();
- for (Card commander : commanders) {
- commanderNames.add(commander.getName());
- }
- for (Card commander : commanders) {
- if (bannedCommander.contains(commander.getName())) {
- addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander banned (" + commander.getName() + ')', true);
- valid = false;
- }
- if ((!commander.hasCardTypeForDeckbuilding(CardType.CREATURE) || !commander.isLegendary())
- && !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance())) {
- addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander invalid (" + commander.getName() + ')', true);
- valid = false;
- }
- if (commanders.size() == 2) {
- if (!commander.getAbilities().contains(PartnerAbility.getInstance())) {
- boolean partnersWith = commander.getAbilities()
- .stream()
- .filter(PartnerWithAbility.class::isInstance)
- .map(PartnerWithAbility.class::cast)
- .map(PartnerWithAbility::getPartnerName)
- .anyMatch(commanderNames::contains);
- if (!partnersWith) {
- addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander without Partner (" + commander.getName() + ')', true);
- valid = false;
- }
- }
- }
- ManaUtil.collectColorIdentity(colorIdentity, commander.getColorIdentity());
- }
-
- // no needs in cards check on wrong commanders
- if (!valid) {
- return false;
- }
-
- for (Card card : deck.getCards()) {
- if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
- addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true);
- valid = false;
- }
- }
- for (Card card : deck.getSideboard()) {
- if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
- addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true);
- valid = false;
- }
- }
- for (Card card : deck.getCards()) {
- if (!isSetAllowed(card.getExpansionSetCode())) {
- if (!legalSets(card)) {
- addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true);
- valid = false;
- }
- }
- }
- for (Card card : deck.getSideboard()) {
- if (!isSetAllowed(card.getExpansionSetCode())) {
- if (!legalSets(card)) {
- addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true);
- valid = false;
- }
- }
- }
- // Check for companion legality
- if (companion != null) {
- Set cards = new HashSet<>(deck.getCards());
- cards.addAll(commanders);
- for (Ability ability : companion.getAbilities()) {
- if (ability instanceof CompanionAbility) {
- CompanionAbility companionAbility = (CompanionAbility) ability;
- if (!companionAbility.isLegal(cards, getDeckMinSize())) {
- addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Commander Companion (deck invalid for companion)", true);
- valid = false;
- }
- break;
- }
- }
- }
return valid;
}
}
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pioneer.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pioneer.java
index 77f3a4ced81..6daef5f9051 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pioneer.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Pioneer.java
@@ -34,6 +34,7 @@ public class Pioneer extends Constructed {
banned.add("Inverter of Truth");
banned.add("Kethis, the Hidden Hand");
banned.add("Leyline of Abundance");
+ banned.add("Lurrus of the Dream-Den");
banned.add("Nexus of Fate");
banned.add("Oko, Thief of Crowns");
banned.add("Once Upon a Time");
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Premodern.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Premodern.java
index a73be72a95d..f15a06d9e7b 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Premodern.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Premodern.java
@@ -3,7 +3,6 @@ package mage.deck;
import mage.cards.decks.Constructed;
/**
- *
* @author jmharmon
*/
@@ -44,10 +43,8 @@ public class Premodern extends Constructed {
setCodes.add(mage.sets.Scourge.getInstance().getCode());
// Ban List
- banned.add("Amulet of Quoz");
banned.add("Balance");
banned.add("Brainstorm");
- banned.add("Bronze Tablet");
banned.add("Channel");
banned.add("Demonic Consultation");
banned.add("Earthcraft");
@@ -56,25 +53,21 @@ public class Premodern extends Constructed {
banned.add("Force of Will");
banned.add("Goblin Recruiter");
banned.add("Grim Monolith");
- banned.add("Jeweled Bird");
banned.add("Mana Vault");
banned.add("Memory Jar");
- banned.add("Mind Twist");
banned.add("Mind's Desire");
+ banned.add("Mind Twist");
banned.add("Mystical Tutor");
banned.add("Necropotence");
- banned.add("Rebirth");
banned.add("Show and Tell");
banned.add("Strip Mine");
- banned.add("Tempest Efreet");
banned.add("Tendrils of Agony");
banned.add("Time Spiral");
- banned.add("Timmerian Fiends");
banned.add("Tolarian Academy");
banned.add("Vampiric Tutor");
banned.add("Windfall");
banned.add("Worldgorger Dragon");
- banned.add("Yawgmoth's Will");
banned.add("Yawgmoth's Bargain");
+ banned.add("Yawgmoth's Will");
}
}
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java
index 92f45d511ba..52d733412d2 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java
@@ -59,7 +59,6 @@ public class TinyLeaders extends Constructed {
banned.add("Mox Sapphire");
banned.add("Najeela, the Blade-Blossom");
banned.add("Necropotence");
- banned.add("Shahrazad");
banned.add("Sisay, Weatherlight Captain");
banned.add("Skullclamp");
banned.add("Sol Ring");
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java
index 3a7f2662caf..1641ece3ac5 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java
@@ -16,39 +16,6 @@ public class Vintage extends Constructed {
setCodes.add(set.getCode());
}
}
- banned.add("Advantageous Proclamation");
- banned.add("Amulet of Quoz");
- banned.add("Backup Plan");
- banned.add("Brago's Favor");
- banned.add("Bronze Tablet");
- banned.add("Chaos Orb");
- banned.add("Cleanse");
- banned.add("Crusade");
- banned.add("Contract from Below");
- banned.add("Darkpact");
- banned.add("Demonic Attorney");
- banned.add("Double Stroke");
- banned.add("Falling Star");
- banned.add("Immediate Action");
- banned.add("Imprison");
- banned.add("Invoke Prejudice");
- banned.add("Iterative Analysis");
- banned.add("Jeweled Bird");
- banned.add("Jihad");
- banned.add("Muzzio's Preparations");
- banned.add("Power Play");
- banned.add("Pradesh Gypsies");
- banned.add("Rebirth");
- banned.add("Secret Summoning");
- banned.add("Secrets of Paradise");
- banned.add("Sentinel Dispatch");
- banned.add("Shahrazad");
- banned.add("Stone-Throwing Devils");
- banned.add("Tempest Efreet");
- banned.add("Timmerian Fiends");
- banned.add("Unexpected Potential");
- banned.add("Worldknit");
-
restricted.add("Ancestral Recall");
restricted.add("Balance");
restricted.add("Black Lotus");
diff --git a/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java b/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java
index d2391aab2fc..3b9445e36e8 100644
--- a/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java
+++ b/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java
@@ -13,7 +13,7 @@ import java.util.Map;
public class Limited extends DeckValidator {
public Limited() {
- super("Limited");
+ super("Limited", null);
}
@Override
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
index 5b347cb2a92..770d3b0aaec 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
@@ -396,7 +396,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
&& stackObject.getControllerId().equals(playerId)) {
Target target = effect.getTarget();
if (!target.doneChosing()) {
- for (UUID targetId : target.possibleTargets(stackObject.getSourceId(), stackObject.getControllerId(), game)) {
+ for (UUID targetId : target.possibleTargets(stackObject.getControllerId(), stackObject.getStackAbility(), game)) {
Game sim = game.copy();
StackAbility newAbility = (StackAbility) stackObject.copy();
SearchEffect newEffect = getSearchEffect(newAbility);
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java
index 4cff650ac63..ee208d00d68 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java
@@ -124,8 +124,7 @@ public class SimulatedPlayer2 extends ComputerPlayer {
// calculate the mana that can be used for the x part
int numAvailable = getAvailableManaProducers(game).size() - ability.getManaCosts().manaValue();
- Card card = game.getCard(ability.getSourceId());
- if (card != null && numAvailable > 0) {
+ if (numAvailable > 0) {
// check if variable mana costs is included and get the multiplier
VariableManaCost variableManaCost = null;
for (ManaCost cost : ability.getManaCostsToPay()) {
@@ -159,7 +158,7 @@ public class SimulatedPlayer2 extends ComputerPlayer {
if (varCost != null) {
varCost.setPaid();
}
- card.adjustTargets(newAbility, game);
+ newAbility.adjustTargets(game);
// add the different possible target option for the specific X value
if (!newAbility.getTargets().getUnchosen().isEmpty()) {
addTargetOptions(options, newAbility, targetNum, game);
diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
index d7deb819b41..8393ebf864a 100644
--- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
@@ -122,12 +122,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
@Override
- public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
- return choose(outcome, target, sourceId, game, null);
+ public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
+ return choose(outcome, target, source, game, null);
}
@Override
- public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map options) {
+ public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map options) {
if (log.isDebugEnabled()) {
log.debug("choose: " + outcome.toString() + ':' + target.toString());
@@ -143,9 +143,10 @@ public class ComputerPlayer extends PlayerImpl implements Player {
&& target.getAbilityController() != null) {
abilityControllerId = target.getAbilityController();
}
+ UUID sourceId = source != null ? source.getSourceId() : null;
boolean required = target.isRequired(sourceId, game);
- Set possibleTargets = target.possibleTargets(sourceId, abilityControllerId, game);
+ Set possibleTargets = target.possibleTargets(abilityControllerId, source, game);
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
required = false;
}
@@ -160,7 +161,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
if (target.getOriginalTarget() instanceof TargetPlayer) {
- return setTargetPlayer(outcome, target, null, sourceId, abilityControllerId, randomOpponentId, game, required);
+ return setTargetPlayer(outcome, target, null, abilityControllerId, randomOpponentId, game, required);
}
if (target.getOriginalTarget() instanceof TargetDiscard) {
@@ -191,12 +192,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
List targets;
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
- targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets());
if (!outcome.isGood()) {
Collections.reverse(targets);
}
for (Permanent permanent : targets) {
- if (origTarget.canTarget(abilityControllerId, permanent.getId(), sourceId, game, false) && !target.getTargets().contains(permanent.getId())) {
+ if (origTarget.canTarget(abilityControllerId, permanent.getId(), source, game, false) && !target.getTargets().contains(permanent.getId())) {
target.add(permanent.getId(), game);
return true;
}
@@ -217,18 +218,18 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List targets;
if (outcome.isCanTargetAll()) {
- targets = threats(null, sourceId, filter, game, target.getTargets());
+ targets = threats(null, source, filter, game, target.getTargets());
} else {
if (outcome.isGood()) {
- targets = threats(abilityControllerId, sourceId, filter, game, target.getTargets());
+ targets = threats(abilityControllerId, source, filter, game, target.getTargets());
} else {
- targets = threats(randomOpponentId, sourceId, filter, game, target.getTargets());
+ targets = threats(randomOpponentId, source, filter, game, target.getTargets());
}
if (targets.isEmpty() && target.isRequired()) {
if (!outcome.isGood()) {
- targets = threats(abilityControllerId, sourceId, filter, game, target.getTargets());
+ targets = threats(abilityControllerId, source, filter, game, target.getTargets());
} else {
- targets = threats(randomOpponentId, sourceId, filter, game, target.getTargets());
+ targets = threats(randomOpponentId, source, filter, game, target.getTargets());
}
}
}
@@ -257,7 +258,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetCardInHand
|| (target.getZone() == Zone.HAND && (target.getOriginalTarget() instanceof TargetCard))) {
List cards = new ArrayList<>();
- for (UUID cardId : target.possibleTargets(sourceId, this.getId(), game)) {
+ for (UUID cardId : target.possibleTargets(this.getId(), source, game)) {
Card card = game.getCard(cardId);
if (card != null) {
cards.add(card);
@@ -278,9 +279,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List targets;
TargetAnyTarget origTarget = (TargetAnyTarget) target.getOriginalTarget();
if (outcome.isGood()) {
- targets = threats(abilityControllerId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
} else {
- targets = threats(randomOpponentId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(randomOpponentId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
}
for (Permanent permanent : targets) {
List alreadyTargetted = target.getTargets();
@@ -309,9 +310,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List targets;
TargetCreatureOrPlayer origTarget = (TargetCreatureOrPlayer) target.getOriginalTarget();
if (outcome.isGood()) {
- targets = threats(abilityControllerId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} else {
- targets = threats(randomOpponentId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
+ targets = threats(randomOpponentId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
}
for (Permanent permanent : targets) {
List alreadyTargeted = target.getTargets();
@@ -339,8 +340,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
List targets;
TargetPermanentOrPlayer origTarget = (TargetPermanentOrPlayer) target.getOriginalTarget();
- List ownedTargets = threats(abilityControllerId, sourceId, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
- List opponentTargets = threats(randomOpponentId, sourceId, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ List ownedTargets = threats(abilityControllerId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ List opponentTargets = threats(randomOpponentId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
if (outcome.isGood()) {
targets = ownedTargets;
} else {
@@ -463,7 +464,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetSource) {
Set targets;
- targets = target.possibleTargets(sourceId, abilityControllerId, game);
+ targets = target.possibleTargets(abilityControllerId, source, game);
for (UUID targetId : targets) {
MageObject targetObject = game.getObject(targetId);
if (targetObject != null) {
@@ -517,7 +518,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
boolean required = target.isRequired(sourceId, game);
- Set possibleTargets = target.possibleTargets(sourceId, abilityControllerId, game);
+ Set possibleTargets = target.possibleTargets(abilityControllerId, source, game);
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
required = false;
}
@@ -537,11 +538,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
if (target.getOriginalTarget() instanceof TargetPlayer) {
- return setTargetPlayer(outcome, target, source, sourceId, abilityControllerId, randomOpponentId, game, required);
+ return setTargetPlayer(outcome, target, source, abilityControllerId, randomOpponentId, game, required);
}
// Angel of Serenity trigger
- if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
+ if (target.getOriginalTarget() instanceof TargetCardInGraveyardBattlefieldOrStack) {
Cards cards = new CardsImpl(possibleTargets);
List possibleCards = new ArrayList<>(cards.getCards(game));
for (Card card : possibleCards) {
@@ -642,7 +643,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
List targets;
- targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets());
if (!outcome.isGood()) {
Collections.reverse(targets);
}
@@ -671,7 +672,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
+ target.getOriginalTarget().getClass().getCanonicalName());
}
- findBestPermanentTargets(outcome, abilityControllerId, sourceId, filter,
+ findBestPermanentTargets(outcome, abilityControllerId, sourceId, source, filter,
game, target, goodList, badList, allList);
// use good list all the time and add maximum targets
@@ -700,9 +701,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List targets;
TargetCreatureOrPlayer origTarget = ((TargetCreatureOrPlayer) target.getOriginalTarget());
if (outcome.isGood()) {
- targets = threats(abilityControllerId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
} else {
- targets = threats(randomOpponentId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
+ targets = threats(randomOpponentId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
}
if (targets.isEmpty()) {
@@ -742,9 +743,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List targets;
TargetAnyTarget origTarget = ((TargetAnyTarget) target.getOriginalTarget());
if (outcome.isGood()) {
- targets = threats(abilityControllerId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
} else {
- targets = threats(randomOpponentId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(randomOpponentId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
}
if (targets.isEmpty()) {
@@ -785,9 +786,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List targets;
TargetPermanentOrPlayer origTarget = ((TargetPermanentOrPlayer) target.getOriginalTarget());
if (outcome.isGood()) {
- targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
} else {
- targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(randomOpponentId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
}
if (targets.isEmpty()) {
@@ -823,9 +824,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
// normal cycle (good for you, bad for opponents)
// possible good/bad permanents
if (outcome.isGood()) {
- targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
} else {
- targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
+ targets = threats(randomOpponentId, source, ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
}
// possible good/bad players
@@ -930,12 +931,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List targets;
boolean outcomeTargets = true;
if (outcome.isGood()) {
- targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
+ targets = threats(abilityControllerId, source, origTarget.getPermanentFilter(), game, target.getTargets());
} else {
- targets = threats(randomOpponentId, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
+ targets = threats(randomOpponentId, source, origTarget.getPermanentFilter(), game, target.getTargets());
}
if (targets.isEmpty() && required) {
- targets = threats(null, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
+ targets = threats(null, source, origTarget.getPermanentFilter(), game, target.getTargets());
Collections.reverse(targets);
outcomeTargets = false;
}
@@ -976,24 +977,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
if (target.getOriginalTarget() instanceof TargetDefender) {
- // TODO: Improve, now planeswalker is always chosen if it exits
- List targets;
- targets = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_PLANESWALKER, randomOpponentId, game);
- if (targets != null && !targets.isEmpty()) {
- for (Permanent planeswalker : targets) {
- if (target.canTarget(abilityControllerId, planeswalker.getId(), source, game)) {
- target.addTarget(planeswalker.getId(), source, game);
- }
- if (target.isChosen()) {
- return true;
- }
- }
- }
- if (!target.isChosen()) {
- if (target.canTarget(abilityControllerId, randomOpponentId, source, game)) {
- target.addTarget(randomOpponentId, source, game);
- }
- }
+ UUID randomDefender = RandomUtil.randomFromCollection(possibleTargets);
+ target.addTarget(randomDefender, source, game);
return target.isChosen();
}
@@ -1024,7 +1009,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
List cards = new ArrayList<>();
- for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
+ for (UUID uuid : target.possibleTargets(source.getControllerId(), source, game)) {
Card card = game.getCard(uuid);
if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
cards.add(card);
@@ -1042,7 +1027,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
List stackObjects = new ArrayList<>();
- for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
+ for (UUID uuid : target.possibleTargets(source.getControllerId(), source, game)) {
StackObject stackObject = game.getStack().getStackObject(uuid);
if (stackObject != null) {
stackObjects.add(stackObject);
@@ -1058,7 +1043,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
return target.isChosen();
}
- if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
+ if (target.getOriginalTarget() instanceof TargetCardInGraveyardBattlefieldOrStack) {
List cards = new ArrayList<>();
for (Player player : game.getPlayers().values()) {
cards.addAll(player.getGraveyard().getCards(game));
@@ -1145,7 +1130,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
// permanents kill
for (UUID opponentId : opponents) {
- targets = threats(opponentId, sourceId, StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A, game, target.getTargets());
+ targets = threats(opponentId, source, StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A, game, target.getTargets());
// planeswalker kill
for (Permanent permanent : targets) {
@@ -1172,9 +1157,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
// own permanents will be checked multiple times... that's ok
for (UUID opponentId : opponents) {
if (outcome.isGood()) {
- targets = threats(getId(), sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
+ targets = threats(getId(), source, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
} else {
- targets = threats(opponentId, sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
+ targets = threats(opponentId, source, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
}
// planeswalkers
@@ -1208,9 +1193,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (UUID opponentId : opponents) {
if (!outcome.isGood()) {
// bad on yourself, uses weakest targets
- targets = threats(getId(), sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
+ targets = threats(getId(), source, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
} else {
- targets = threats(opponentId, sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
+ targets = threats(opponentId, source, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
}
// creatures - non killable (TODO: add extra skill checks like undestructeable)
@@ -1668,7 +1653,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
// pay phyrexian life costs
- if (cost instanceof PhyrexianManaCost) {
+ if (cost.isPhyrexian()) {
return cost.pay(ability, game, ability, playerId, false, null) || approvingObject != null;
}
@@ -2005,7 +1990,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
// we still use playerId when getting cards even if they don't control the search
- List cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), source != null ? source.getSourceId() : null, playerId, game));
+ List cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), playerId, source, game));
while (!target.doneChosing()) {
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
if (card != null) {
@@ -2125,7 +2110,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
continue AvailableMode;
}
}
- if (mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and where targets are available
+ if (mode.getTargets().canChoose(source.getControllerId(), source, game)) { // and where targets are available
return mode;
}
}
@@ -2710,7 +2695,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
return worst;
}
- protected void findBestPermanentTargets(Outcome outcome, UUID abilityControllerId, UUID sourceId, FilterPermanent filter, Game game, Target target,
+ protected void findBestPermanentTargets(Outcome outcome, UUID abilityControllerId, UUID sourceId, Ability source, FilterPermanent filter, Game game, Target target,
List goodList, List badList, List allList) {
// searching for most valuable/powerfull permanents
goodList.clear();
@@ -2719,7 +2704,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
List usedTargets = target.getTargets();
// search all
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, abilityControllerId, sourceId, game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, abilityControllerId, source, game)) {
if (usedTargets.contains(permanent.getId())) {
continue;
}
@@ -2767,19 +2752,19 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
- protected List threats(UUID playerId, UUID sourceId, FilterPermanent filter, Game game, List targets) {
- return threats(playerId, sourceId, filter, game, targets, true);
+ protected List threats(UUID playerId, Ability source, FilterPermanent filter, Game game, List targets) {
+ return threats(playerId, source, filter, game, targets, true);
}
- protected List threats(UUID playerId, UUID sourceId, FilterPermanent filter, Game game, List targets, boolean mostValueableGoFirst) {
+ protected List threats(UUID playerId, Ability source, FilterPermanent filter, Game game, List targets, boolean mostValueableGoFirst) {
// most valuable/powerfull permanents goes at first
List threats;
if (playerId == null) {
- threats = game.getBattlefield().getActivePermanents(filter, this.getId(), sourceId, game); // all permanents within the range of the player
+ threats = game.getBattlefield().getActivePermanents(filter, this.getId(), source, game); // all permanents within the range of the player
} else {
FilterPermanent filterCopy = filter.copy();
filterCopy.add(new ControllerIdPredicate(playerId));
- threats = game.getBattlefield().getActivePermanents(filter, this.getId(), sourceId, game);
+ threats = game.getBattlefield().getActivePermanents(filter, this.getId(), source, game);
}
Iterator it = threats.iterator();
while (it.hasNext()) { // remove permanents already targeted
@@ -2897,7 +2882,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
*
* @param source null on choose and non-null on chooseTarget
*/
- private boolean setTargetPlayer(Outcome outcome, Target target, Ability source, UUID sourceId, UUID abilityControllerId, UUID randomOpponentId, Game game, boolean required) {
+ private boolean setTargetPlayer(Outcome outcome, Target target, Ability source, UUID abilityControllerId, UUID randomOpponentId, Game game, boolean required) {
Outcome affectedOutcome;
if (abilityControllerId == this.playerId) {
// selects for itself
@@ -2931,6 +2916,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
return false;
}
+ UUID sourceId = source != null ? source.getSourceId() : null;
if (target.getOriginalTarget() instanceof TargetPlayer) {
if (affectedOutcome.isGood()) {
if (source == null) {
@@ -2997,26 +2983,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
* @return
*/
private UUID getRandomOpponent(UUID abilityControllerId, Game game) {
- UUID randomOpponentId = null;
- Set opponents = game.getOpponents(abilityControllerId);
- if (opponents.size() > 1) {
- int rand = RandomUtil.nextInt(opponents.size());
- int count = 0;
- for (UUID currentId : opponents) {
- if (count == rand) {
- randomOpponentId = currentId;
- break;
- }
- }
- } else if (opponents.size() == 1) {
- randomOpponentId = game.getOpponents(abilityControllerId).iterator().next();
- }
- return randomOpponentId;
+ return RandomUtil.randomFromCollection(game.getOpponents(abilityControllerId));
}
@Override
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean noMana) {
- Map useable = PlayerImpl.getCastableSpellAbilities(game, this.getId(), card, game.getState().getZone(card.getId()), noMana);
+ Map useable = PlayerImpl.getCastableSpellAbilities(game, this.getId(), card, game.getState().getZone(card.getId()), noMana);
return (SpellAbility) useable.values().stream().findFirst().orElse(null);
}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java
index f887ca55c93..4eb502940c3 100644
--- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java
+++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java
@@ -221,7 +221,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
}
protected boolean chooseRandomTarget(Target target, Ability source, Game game) {
- Set possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
+ Set possibleTargets = target.possibleTargets(playerId, source, game);
if (possibleTargets.isEmpty()) {
return false;
}
@@ -245,19 +245,19 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
}
@Override
- public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
+ public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
if (this.isHuman()) {
return chooseRandom(target, game);
}
- return super.choose(outcome, target, sourceId, game);
+ return super.choose(outcome, target, source, game);
}
@Override
- public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map options) {
+ public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map options) {
if (this.isHuman()) {
return chooseRandom(target, game);
}
- return super.choose(outcome, target, sourceId, game, options);
+ return super.choose(outcome, target, source, game, options);
}
@Override
@@ -302,7 +302,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
- Set possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
+ Set possibleTargets = target.possibleTargets(playerId, source, game);
if (possibleTargets.isEmpty()) {
return !target.isRequired(source);
}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java
index 097c08ef3b7..18c518cbd21 100644
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java
+++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java
@@ -235,7 +235,7 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player {
if (effect != null && ability.getControllerId().equals(playerId)) {
Target target = effect.getTarget();
if (!target.doneChosing()) {
- for (UUID targetId: target.possibleTargets(ability.getSourceId(), ability.getControllerId(), game)) {
+ for (UUID targetId: target.possibleTargets(ability.getControllerId(), ability.getStackAbility(), game)) {
Game sim = game.copy();
StackAbility newAbility = (StackAbility) ability.copy();
SearchEffect newEffect = getSearchEffect((StackAbility) newAbility);
diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
index d2528ce6c2b..89f4d072ddf 100644
--- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
@@ -498,12 +498,12 @@ public class HumanPlayer extends PlayerImpl {
}
@Override
- public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
- return choose(outcome, target, sourceId, game, null);
+ public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
+ return choose(outcome, target, source, game, null);
}
@Override
- public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map options) {
+ public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map options) {
if (gameInCheckPlayableState(game)) {
return true;
}
@@ -519,12 +519,12 @@ public class HumanPlayer extends PlayerImpl {
}
while (canRespond()) {
- Set targetIds = target.possibleTargets(sourceId, abilityControllerId, game);
+ Set targetIds = target.possibleTargets(abilityControllerId, source, game);
if (targetIds == null || targetIds.isEmpty()) {
return target.getTargets().size() >= target.getNumberOfTargets();
}
- boolean required = target.isRequired(sourceId, game);
+ boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
if (target.getTargets().size() >= target.getNumberOfTargets()) {
required = false;
}
@@ -535,7 +535,7 @@ public class HumanPlayer extends PlayerImpl {
updateGameStatePriority("choose(5)", game);
prepareForResponse(game);
if (!isExecutingMacro()) {
- game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(sourceId, game)), targetIds, required, getOptions(target, options));
+ game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), targetIds, required, getOptions(target, options));
}
waitForResponse(game);
@@ -554,14 +554,14 @@ public class HumanPlayer extends PlayerImpl {
}
if (target instanceof TargetPermanent) {
- if (((TargetPermanent) target).canTarget(abilityControllerId, responseId, sourceId, game, false)) {
+ if (((TargetPermanent) target).canTarget(abilityControllerId, responseId, source, game, false)) {
target.add(responseId, game);
if (target.doneChosing()) {
return true;
}
}
} else {
- MageObject object = game.getObject(sourceId);
+ MageObject object = game.getObject(source);
if (object instanceof Ability) {
if (target.canTarget(responseId, (Ability) object, game)) {
if (target.getTargets().contains(responseId)) { // if already included remove it with
@@ -617,7 +617,7 @@ public class HumanPlayer extends PlayerImpl {
Map options = new HashMap<>();
while (canRespond()) {
- Set possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
+ Set possibleTargets = target.possibleTargets(abilityControllerId, source, game);
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
if (possibleTargets.isEmpty()
|| target.getTargets().size() >= target.getNumberOfTargets()) {
@@ -845,7 +845,7 @@ public class HumanPlayer extends PlayerImpl {
// 1. Select targets
while (canRespond()) {
- Set possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
+ Set possibleTargets = target.possibleTargets(abilityControllerId, source, game);
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
if (possibleTargets.isEmpty()
|| target.getSize() >= target.getNumberOfTargets()) {
@@ -979,7 +979,7 @@ public class HumanPlayer extends PlayerImpl {
FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
filter.add(new ControllerIdPredicate(playerId));
// stop skip on any/zero permanents available
- int possibleBlockersCount = game.getBattlefield().count(filter, null, playerId, game);
+ int possibleBlockersCount = game.getBattlefield().count(filter, playerId, null, game);
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
quickStop = canStopOnAny || canStopOnZero;
@@ -1482,7 +1482,7 @@ public class HumanPlayer extends PlayerImpl {
// can't see lands as playable and must know the reason (if they click on land then they get that message)
if (abilityToCast.getAbilityType() == AbilityType.SPELL) {
Spell spell = game.getStack().getSpell(abilityToCast.getSourceId());
- boolean haveManaAbilities = object.getAbilities().stream().anyMatch(a -> a instanceof ManaAbility);
+ boolean haveManaAbilities = object.getAbilities().stream().anyMatch(ManaAbility.class::isInstance);
if (spell != null && !spell.isResolving() && haveManaAbilities) {
switch (spell.getCurrentActivatingManaAbilitiesStep()) {
// if you used special mana ability like convoke then normal mana abilities will be restricted to use, see Convoke for details
@@ -1605,9 +1605,9 @@ public class HumanPlayer extends PlayerImpl {
} else if (responseId != null) {
Permanent attacker = game.getPermanent(responseId);
if (attacker != null) {
- if (filterCreatureForCombat.match(attacker, null, playerId, game)) {
+ if (filterCreatureForCombat.match(attacker, playerId, null, game)) {
selectDefender(game.getCombat().getDefenders(), attacker.getId(), game);
- } else if (filterAttack.match(attacker, null, playerId, game) && game.getStack().isEmpty()) {
+ } else if (filterAttack.match(attacker, playerId, null, game) && game.getStack().isEmpty()) {
removeAttackerIfPossible(game, attacker);
}
}
@@ -1737,7 +1737,6 @@ public class HumanPlayer extends PlayerImpl {
return true;
} else {
TargetDefender target = new TargetDefender(possibleDefender, attackerId);
- target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player
if (forcedToAttack) {
StringBuilder sb = new StringBuilder(target.getTargetName());
Permanent attacker = game.getPermanent(attackerId);
@@ -1757,7 +1756,6 @@ public class HumanPlayer extends PlayerImpl {
protected UUID selectDefenderForAllAttack(Set defenders, Game game) {
TargetDefender target = new TargetDefender(defenders, null);
- target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player
if (chooseTarget(Outcome.Damage, target, null, game)) {
return getFixedResponseUUID(game);
}
@@ -1774,7 +1772,7 @@ public class HumanPlayer extends PlayerImpl {
filter.add(new ControllerIdPredicate(defendingPlayerId));
// stop skip on any/zero permanents available
- int possibleBlockersCount = game.getBattlefield().count(filter, null, playerId, game);
+ int possibleBlockersCount = game.getBattlefield().count(filter, playerId, source, game);
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
@@ -1812,9 +1810,9 @@ public class HumanPlayer extends PlayerImpl {
if (blocker != null) {
boolean removeBlocker = false;
// does not block yet and can block or can block more attackers
- if (filter.match(blocker, null, playerId, game)) {
+ if (filter.match(blocker, playerId, source, game)) {
selectCombatGroup(defendingPlayerId, blocker.getId(), game);
- } else if (filterBlock.match(blocker, null, playerId, game)
+ } else if (filterBlock.match(blocker, playerId, source, game)
&& game.getStack().isEmpty()) {
removeBlocker = true;
}
@@ -1894,7 +1892,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game);
if (!isExecutingMacro()) {
// possible attackers to block
- Set attackers = target.possibleTargets(null, playerId, game);
+ Set attackers = target.possibleTargets(playerId, null, game);
Permanent blocker = game.getPermanent(blockerId);
Set possibleTargets = new HashSet<>();
for (UUID attackerId : attackers) {
@@ -1934,7 +1932,7 @@ public class HumanPlayer extends PlayerImpl {
if (singleTargetName != null) {
target.setTargetName(singleTargetName);
}
- choose(Outcome.Damage, target, source.getSourceId(), game);
+ choose(Outcome.Damage, target, source, game);
if (targets.isEmpty() || targets.contains(target.getFirstTarget())) {
int damageAmount = getAmount(0, remainingDamage, "Select amount", game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
@@ -2187,10 +2185,10 @@ public class HumanPlayer extends PlayerImpl {
MageObject object = game.getObject(card.getId()); // must be object to find real abilities (example: commander)
if (object != null) {
String message = "Choose ability to cast" + (noMana ? " for FREE" : "") + "
" + object.getLogName();
- LinkedHashMap useableAbilities = PlayerImpl.getCastableSpellAbilities(game, playerId, object, game.getState().getZone(object.getId()), noMana);
+ LinkedHashMap useableAbilities = PlayerImpl.getCastableSpellAbilities(game, playerId, object, game.getState().getZone(object.getId()), noMana);
if (useableAbilities != null
&& useableAbilities.size() == 1) {
- return (SpellAbility) useableAbilities.values().iterator().next();
+ return useableAbilities.values().iterator().next();
} else if (useableAbilities != null
&& !useableAbilities.isEmpty()) {
@@ -2204,7 +2202,7 @@ public class HumanPlayer extends PlayerImpl {
UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
if (useableAbilities.containsKey(responseId)) {
- return (SpellAbility) useableAbilities.get(responseId);
+ return useableAbilities.get(responseId);
}
}
}
@@ -2224,7 +2222,7 @@ public class HumanPlayer extends PlayerImpl {
if (modes.size() > 1) {
// done option for up to choices
boolean canEndChoice = modes.getSelectedModes().size() >= modes.getMinModes() || modes.isMayChooseNone();
- MageObject obj = game.getObject(source.getSourceId());
+ MageObject obj = game.getObject(source);
Map modeMap = new LinkedHashMap<>();
int modeIndex = 0;
AvailableModes:
@@ -2244,7 +2242,7 @@ public class HumanPlayer extends PlayerImpl {
}
}
- if (mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and needed targets have to be available
+ if (mode.getTargets().canChoose(source.getControllerId(), source, game)) { // and needed targets have to be available
String modeText = mode.getEffects().getText(mode);
if (obj != null) {
modeText = modeText.replace("{this}", obj.getName());
diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/KhansExpandedCube.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/KhansExpandedCube.java
new file mode 100644
index 00000000000..2115310b97e
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/KhansExpandedCube.java
@@ -0,0 +1,512 @@
+package mage.tournament.cubes;
+
+import mage.game.draft.DraftCube;
+
+/**
+ * @author TheBear132
+ * This cube is taken from this article https://magic.wizards.com/en/articles/archive/magic-online/khans-expanded-cube-2019-07-23
+ * If the cards are from any of the Tarkir sets, the preferred set will be set to that set
+ */
+
+public class KhansExpandedCube extends DraftCube {
+
+ public KhansExpandedCube() {
+ super("MTGO Khans Expanded Cube");
+
+ cubeCards.add(new DraftCube.CardIdentity("Herald of Anafenza", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Embodiment of Spring", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Bloodsoaked Champion", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Kolaghan Stormsinger", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Experiment One", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Taigam, Ojutai Master", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Chronomaton", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Arid Mesa", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Hateblade", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Enclave Cryptologist", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Cruel Sadist", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Monastery Swiftspear", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Gnarlwood Dryad", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ojutai, Soul of Winter", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Filigree Familiar", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ash Barrens", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Woe-Reaper", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Deranged Assistant", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Disowned Ancestor", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Abbot of Keral Keep", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Patron of the Wild", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Dragonlord Silumgar", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Pilgrim's Eye", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Battlefield Forge", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ainok Bond-Kin", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Elusive Spellfist", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ruthless Ripper", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Firebrand Archer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Pelt Collector", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Connive // Concoct", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Skittering Surveyor", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Blood Crypt", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Daring Skyjek", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Jeskai Elder", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Shambling Goblin", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Horde Ambusher", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ainok Survivalist", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Dreadhorde Butcher", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Awakened Amalgam", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bloodfell Caves", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Hidden Dragonslayer", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Jeskai Sage", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Battle Brawler", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Ire Shaman", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Broodhatch Nantuko", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Dragonlord Kolaghan", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Peace Strider", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bloodstained Mire", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Master of Pearls", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Plaxmanta", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Kitesail Freebooter", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Jeering Instigator", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Deadly Recluse", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ghor-Clan Rampager", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Rampaging Monument", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Blooming Marsh", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Remorseful Cleric", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Qarsi Deceiver", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Skullhunter", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Kiln Fiend", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Decorated Champion", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Atarka, World Render", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Solemn Simulacrum", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Blossoming Sands", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Seeker of the Way", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Spellweaver Eternal", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Silumgar Assassin", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mogg War Marshal", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Den Protector", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Knight of Autumn", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Chamber Sentry", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Botanical Sanctum", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Soulfire Grand Master", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Stratus Dancer", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Skinthinner", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Nef-Crop Entangler", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Glade Watcher", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Dromoka, the Eternal", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Duplicant", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Breeding Pool", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Steward of Solidarity", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Willbender", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sultai Emissary", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Skirk Marauder", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Heir of the Wilds", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Chief of the Edge", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Animation Module", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Caves of Koilos", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Tithe Taker", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Echo Tracer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Aphetto Exterminator", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Thermo-Alchemist", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Obsessive Skinner", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Chief of the Scale", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ghostfire Blade", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Concealed Courtyard", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Wall of Omens", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Riptide Entrancer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Blood-Chin Fanatic", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("War-Name Aspirant", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Rattleclaw Mystic", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Elenda, the Dusk Rose", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sylvok Lifestaff", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Dismal Backwater", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Abzan Falconer", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Riptide Survivor", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Graveblade Marauder", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Crater Elemental", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ilysian Caryatid", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mortify", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Triangle of War", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Evolving Wilds", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Arashin Foremost", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Aphetto Runecaster", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Grim Haruspex", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Flamewake Phoenix", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Deathmist Raptor", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Start // Finish", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Cranial Archive", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Flooded Strand", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Kor Sanctifiers", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Gurmag Drowner", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Strike Leader", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Legion Warboss", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Springbloom Druid", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Utter End", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Dream Chisel", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Frontier Bivouac", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Hordechief", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Kheru Spellsnatcher", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Necravolver", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bonecrusher Giant", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Tuskguard Captain", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Castigate", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Guild Globe", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Godless Shrine", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Monastery Mentor", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Master of the Veil", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bane of the Living", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Reckless Bushwhacker", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Anavolver", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Obzedat's Aid", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Leering Emblem", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Grand Coliseum", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Wingbeat Warrior", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mistfire Weaver", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Bellowing Saddlebrute", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Skirk Commando", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Armorcraft Judge", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Death Grasp", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Prophetic Prism", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Hallowed Fountain", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Abzan Battle Priest", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Niblis of Frost", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Gift of Doom", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Smelt-Ward Minotaur", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Goreclaw, Terror of Qal Sisma", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Campaign of Vengeance", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Stormrider Rig", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Hissing Quagmire", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Aven Liberator", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Talrand, Sky Summoner", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Grinning Demon", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ashcloud Phoenix", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Nantuko Vigilante", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Golgari Guildmage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Trip Noose", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Inspiring Vantage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Daru Sanctifier", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Chromeshell Crab", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Haunted Cadaver", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Atarka Efreet", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Serpentine Basilisk", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Dreg Mangler", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Arcane Encyclopedia", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Jungle Hollow", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Dragonscale General", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Icefall Regent", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Haunted Dead", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Battering Craghorn", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sultai Flayer", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Corpsejack Menace", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sickleslicer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Llanowar Wastes", ""));
+ cubeCards.add(new DraftCube.CardIdentity("High Sentinels of Arashin", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ixidor, Reality Sculptor", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mer-Ek Nightblade", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Blistering Firecat", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Surrak, the Hunt Caller", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Izoni, Thousand-Eyed", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bonehoard", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Lumbering Falls", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ojutai Exemplars", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ixidron", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Thrasher Brute", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Erratic Cyclops", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Thelonite Hermit", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Assassin's Trophy", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Obelisk of Alara", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Marsh Flats", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Stonehorn Dignitary", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mischievous Quanar", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Creakwood Ghoul", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Goblin Heelcutter", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Challenger Troll", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Grisly Salvage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Misty Rainforest", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Elite Scaleguard", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Soulblade Djinn", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Rakshasa Gravecaller", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Heart-Piercer", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Conclave Naturalists", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Find // Finality", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mystic Monastery", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Giant Killer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Vesuvan Shapeshifter", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Noosegraf Mob", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Caldera Hellion", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Gigapede", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Death Frenzy", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Needle Spires", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Patron of the Valiant", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Brine Elemental", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Silent Specter", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Charging Monstrosaur", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Hystrodon", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Deadbridge Chant", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Nomad Outpost", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Wingmate Roc", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Quicksilver Dragon", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Gurmag Angler", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Dragon-Style Twins", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Kessig Cagebreakers", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Nyx Weaver", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Opulent Palace", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Daru Lancer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Thousand Winds", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Tombstalker", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Flamerush Rider", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Pine Walker", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Coiling Oracle", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Overgrown Tomb", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Exalted Angel", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Dive Down", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Necropolis Fiend", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Quakefoot Cyclops", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Primal Whisperer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Icefeather Aven", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Polluted Delta", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Linvala, the Preserver", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Opt", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ghastly Demise", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Skarrgan Hellkite", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Hooting Mandrills", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mystic Snake", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Prismatic Vista", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Harm's Way", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Stubborn Denial", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Moment of Craving", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Firemaw Kavu", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Root Elemental", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sagu Mauler", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Rugged Highlands", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Path to Exile", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Disdainful Stroke", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Vicious Offering", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Rockshard Elemental", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temur War Shaman", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Applied Biomancy", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sacred Foundry", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sheltering Light", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Force Away", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Expunge", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bedlam Reveler", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Hooded Hydra", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ethereal Ambush", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Sandsteppe Citadel", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Adamant Will", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Impulse", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Murder", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Weapon Surge", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Venomspout Brackus", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Incubation // Incongruity", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Scalding Tarn", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Artful Maneuver", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Jilt", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Foul Renewal", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Burning Oil", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Earthbrawn", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Urban Evolution", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Scoured Barrens", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Disenchant", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Reality Shift", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Price of Fame", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Lightning Strike", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Grapple with the Past", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Secret Plans", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Shambling Vent", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Feat of Resistance", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Think Twice", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Murderous Cut", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Temur Battle Rage", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Winds of Qal Sisma", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Yavimaya's Embrace", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Shivan Reef", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Feeling of Dread", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Twisted Reflection", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Reach of Shadows", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Omen of the Forge", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Crushing Canopy", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Stormchaser Mage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Spirebluff Canal", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Phalanx Tactics", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Winds of Rebuke", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Death Wind", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Brimstone Volley", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Gnaw to the Bone", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bloodwater Entity", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Steam Vents", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Valorous Stance", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Forbidden Alchemy", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Duress", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Geistblast", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Thornado", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Wee Dragonauts", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Stomping Ground", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Generous Gift", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Phantasmal Form", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Chainer's Edict", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Risk Factor", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Wild Hunger", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Crackling Drake", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Swiftwater Cliffs", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Radiant's Judgment", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Repulse", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Agonizing Remorse", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Bolt Bend", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Become Immense", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Hypersonic Dragon", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple Garden", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Rally the Peasants", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sinister Sabotage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Morgue Theft", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Burn Away", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Savage Swipe", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Izzet Charm", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Abandon", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Miraculous Recovery", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Chemister's Insight", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mire Triton", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Deem Worthy", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Epic Confrontation", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Electrolyze", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Deceit", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Oust", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Commit // Memory", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Doomfall", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Flames of the Raze-Boar", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Savage Punch", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Sonic Assault", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Enlightenment", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Collective Effort", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Icy Blast", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Heartless Pillage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Faithless Looting", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Tracker's Instincts", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Winterflame", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Epiphany", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Slaughter the Strong", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Dig Through Time", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Infest", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Flame Slash", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Winding Way", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Prophetic Bolt", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Malady", ""));
+ cubeCards.add(new DraftCube.CardIdentity("End Hostilities", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Callous Dismissal", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Parting Thoughts", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Reckless Charge", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Map the Wastes", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Honored Crop-Captain", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Malice", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Fell the Mighty", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Chart a Course", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Wander in Death", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Nightbird's Clutches", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Voracious Hydra", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Sunhome Guildmage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Mystery", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Myth Realized", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Strategic Planning", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Moan of the Unhallowed", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Roast", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Nissa's Judgment", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Viashino Firstblade", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Plenty", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mastery of the Unseen", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Write into Being", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Smiting Helix", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Tormenting Voice", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Spider Spawning", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Firemane Avenger", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Silence", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Silkwrap", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Set Adrift", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Vigor Mortis", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Arc Lightning", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("See the Unwritten", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Foundry Champion", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Temple of Triumph", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Suspension Field", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Treasure Cruise", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Crux of Fate", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Collective Defiance", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Hardened Scales", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Integrity // Intervention", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Fabled Passage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Lightform", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Spontaneous Mutation", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Dead Drop", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Repeating Barrage", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Obscuring Aether", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Response // Resurgence", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Thornwood Falls", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Stasis Snare", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Riddleform", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Debilitating Injury", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Rolling Temblor", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Durable Handicraft", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Ride Down", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Tranquil Cove", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Cast Out", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Cloudform", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Raiders' Spoils", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Crater's Claws", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Trail of Mystery", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("War Flare", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Verdant Catacombs", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Righteous Cause", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Skywise Teachings", "Dragons of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Raiders' Wake", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Rageform", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Colossal Majesty", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Warleader's Helix", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Wandering Fumarole", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Mantis Rider", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Watery Grave", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Shu Yun, the Silent Tempest", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Wind-Scarred Crag", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Elsha of the Infinite", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Windswept Heath", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Warden of the Eye", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Wooded Foothills", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Efreet Weaponmaster", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Yavimaya Coast", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Kykar, Wind's Fury", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Jeskai Charm", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Flying Crane Technique", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Jeskai Ascendancy", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Alesha, Who Smiles at Death", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Butcher of the Horde", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ankle Shanker", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Zurgo Helmsmasher", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ponyback Brigade", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Crackling Doom", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Charm", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Mardu Ascendancy", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Fervent Charge", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Anafenza, the Foremost", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Siege Rhino", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Armament Corps", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ivorytusk Fortress", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Abzan Guide", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Abzan Charm", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Ready // Willing", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Duneblast", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Abzan Ascendancy", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Sidisi, Brood Tyrant", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Rakshasa Vizier", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Sultai Soothsayer", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Abomination of Gudul", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Muldrotha, the Gravetide", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Tasigur, the Golden Fang", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Sultai Charm", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Villainous Wealth", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Sultai Ascendancy", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Savage Knuckleblade", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Yasova Dragonclaw", "Fate Reforged"));
+ cubeCards.add(new DraftCube.CardIdentity("Avalanche Tusker", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Bear's Companion", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Surrak Dragonclaw", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Intet, the Dreamer", ""));
+ cubeCards.add(new DraftCube.CardIdentity("Snowhorn Rider", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Temur Charm", "Khans of Tarkir"));
+ cubeCards.add(new DraftCube.CardIdentity("Temur Ascendancy", "Khans of Tarkir"));
+ }
+}
diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeFebruary2022.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeFebruary2022.java
new file mode 100644
index 00000000000..5c7c6ddf1d4
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeFebruary2022.java
@@ -0,0 +1,552 @@
+package mage.tournament.cubes;
+
+import mage.game.draft.DraftCube;
+
+public class VintageCubeFebruary2022 extends DraftCube {
+
+ public VintageCubeFebruary2022() {
+ super("MTGO Vintage Cube Februrary 2022");
+
+ cubeCards.add(new CardIdentity("Abbot of Keral Keep", ""));
+ cubeCards.add(new CardIdentity("Abrade", ""));
+ cubeCards.add(new CardIdentity("Academy Ruins", ""));
+ cubeCards.add(new CardIdentity("Acidic Slime", ""));
+ cubeCards.add(new CardIdentity("Adanto Vanguard", ""));
+ cubeCards.add(new CardIdentity("Adeline, Resplendent Cathar", ""));
+ cubeCards.add(new CardIdentity("Ancestral Recall", ""));
+ cubeCards.add(new CardIdentity("Ancestral Vision", ""));
+ cubeCards.add(new CardIdentity("Ancient Tomb", ""));
+ cubeCards.add(new CardIdentity("Animate Dead", ""));
+ cubeCards.add(new CardIdentity("Arbor Elf", ""));
+ cubeCards.add(new CardIdentity("Archangel Avacyn", ""));
+ cubeCards.add(new CardIdentity("Archon of Cruelty", ""));
+ cubeCards.add(new CardIdentity("Archon of Valor's Reach", ""));
+ cubeCards.add(new CardIdentity("Arid Mesa", ""));
+ cubeCards.add(new CardIdentity("Armageddon", ""));
+ cubeCards.add(new CardIdentity("Ashen Rider", ""));
+ cubeCards.add(new CardIdentity("Ashiok, Nightmare Weaver", ""));
+ cubeCards.add(new CardIdentity("Assassin's Trophy", ""));
+ cubeCards.add(new CardIdentity("Augur of Autumn", ""));
+ cubeCards.add(new CardIdentity("Avalanche Riders", ""));
+ cubeCards.add(new CardIdentity("Avenger of Zendikar", ""));
+ cubeCards.add(new CardIdentity("Azorius Signet", ""));
+ cubeCards.add(new CardIdentity("Badlands", ""));
+ cubeCards.add(new CardIdentity("Balance", ""));
+ cubeCards.add(new CardIdentity("Baleful Strix", ""));
+ cubeCards.add(new CardIdentity("Baneslayer Angel", ""));
+ cubeCards.add(new CardIdentity("Banishing Light", ""));
+ cubeCards.add(new CardIdentity("Baral, Chief of Compliance", ""));
+ cubeCards.add(new CardIdentity("Basalt Monolith", ""));
+ cubeCards.add(new CardIdentity("Batterskull", ""));
+ cubeCards.add(new CardIdentity("Bayou", ""));
+ cubeCards.add(new CardIdentity("Bazaar of Baghdad", ""));
+ cubeCards.add(new CardIdentity("Birds of Paradise", ""));
+ cubeCards.add(new CardIdentity("Birgi, God of Storytelling", ""));
+ cubeCards.add(new CardIdentity("Birthing Pod", ""));
+ cubeCards.add(new CardIdentity("Bitterblossom", ""));
+ cubeCards.add(new CardIdentity("Black Lotus", ""));
+ cubeCards.add(new CardIdentity("Blackcleave Cliffs", ""));
+ cubeCards.add(new CardIdentity("Blade Splicer", ""));
+ cubeCards.add(new CardIdentity("Blightsteel Colossus", ""));
+ cubeCards.add(new CardIdentity("Blood Crypt", ""));
+ cubeCards.add(new CardIdentity("Bloodchief's Thirst", ""));
+ cubeCards.add(new CardIdentity("Bloodghast", ""));
+ cubeCards.add(new CardIdentity("Bloodstained Mire", ""));
+ cubeCards.add(new CardIdentity("Bloodthirsty Adversary", ""));
+ cubeCards.add(new CardIdentity("Bloodtithe Harvester", ""));
+ cubeCards.add(new CardIdentity("Blooming Marsh", ""));
+ cubeCards.add(new CardIdentity("Bolas's Citadel", ""));
+ cubeCards.add(new CardIdentity("Bomat Courier", ""));
+ cubeCards.add(new CardIdentity("Bone Shredder", ""));
+ cubeCards.add(new CardIdentity("Bonecrusher Giant", ""));
+ cubeCards.add(new CardIdentity("Boros Signet", ""));
+ cubeCards.add(new CardIdentity("Boseiju, Who Endures", ""));
+ cubeCards.add(new CardIdentity("Botanical Sanctum", ""));
+ cubeCards.add(new CardIdentity("Braids, Cabal Minion", ""));
+ cubeCards.add(new CardIdentity("Brain Freeze", ""));
+ cubeCards.add(new CardIdentity("Brainstorm", ""));
+ cubeCards.add(new CardIdentity("Brazen Borrower", ""));
+ cubeCards.add(new CardIdentity("Breeding Pool", ""));
+ cubeCards.add(new CardIdentity("Bribery", ""));
+ cubeCards.add(new CardIdentity("Burst Lightning", ""));
+ cubeCards.add(new CardIdentity("Cabal Ritual", ""));
+ cubeCards.add(new CardIdentity("Cathar Commando", ""));
+ cubeCards.add(new CardIdentity("Celestial Colonnade", ""));
+ cubeCards.add(new CardIdentity("Chain Lightning", ""));
+ cubeCards.add(new CardIdentity("Chandra, Torch of Defiance", ""));
+ cubeCards.add(new CardIdentity("Channel", ""));
+ cubeCards.add(new CardIdentity("Char", ""));
+ cubeCards.add(new CardIdentity("Chart a Course", ""));
+ cubeCards.add(new CardIdentity("Chrome Mox", ""));
+ cubeCards.add(new CardIdentity("Circle of Dreams Druid", ""));
+ cubeCards.add(new CardIdentity("Coalition Relic", ""));
+ cubeCards.add(new CardIdentity("Coercive Portal", ""));
+ cubeCards.add(new CardIdentity("Collective Brutality", ""));
+ cubeCards.add(new CardIdentity("Concealed Courtyard", ""));
+ cubeCards.add(new CardIdentity("Condemn", ""));
+ cubeCards.add(new CardIdentity("Consecrated Sphinx", ""));
+ cubeCards.add(new CardIdentity("Containment Priest", ""));
+ cubeCards.add(new CardIdentity("Copperline Gorge", ""));
+ cubeCards.add(new CardIdentity("Council's Judgment", ""));
+ cubeCards.add(new CardIdentity("Counterspell", ""));
+ cubeCards.add(new CardIdentity("Courser of Kruphix", ""));
+ cubeCards.add(new CardIdentity("Craterhoof Behemoth", ""));
+ cubeCards.add(new CardIdentity("Creeping Tar Pit", ""));
+ cubeCards.add(new CardIdentity("Crop Rotation", ""));
+ cubeCards.add(new CardIdentity("Crucible of Worlds", ""));
+ cubeCards.add(new CardIdentity("Cryptbreaker", ""));
+ cubeCards.add(new CardIdentity("Cryptic Command", ""));
+ cubeCards.add(new CardIdentity("Cultivate", ""));
+ cubeCards.add(new CardIdentity("Custodi Lich", ""));
+ cubeCards.add(new CardIdentity("Dack Fayden", ""));
+ cubeCards.add(new CardIdentity("Damn", ""));
+ cubeCards.add(new CardIdentity("Damnation", ""));
+ cubeCards.add(new CardIdentity("Daretti, Ingenious Iconoclast", ""));
+ cubeCards.add(new CardIdentity("Daretti, Scrap Savant", ""));
+ cubeCards.add(new CardIdentity("Dark Confidant", ""));
+ cubeCards.add(new CardIdentity("Dark Depths", ""));
+ cubeCards.add(new CardIdentity("Dark Ritual", ""));
+ cubeCards.add(new CardIdentity("Darkslick Shores", ""));
+ cubeCards.add(new CardIdentity("Dauthi Voidwalker", ""));
+ cubeCards.add(new CardIdentity("Daze", ""));
+ cubeCards.add(new CardIdentity("Deathcap Glade", ""));
+ cubeCards.add(new CardIdentity("Deceiver Exarch", ""));
+ cubeCards.add(new CardIdentity("Demonic Tutor", ""));
+ cubeCards.add(new CardIdentity("Deranged Hermit", ""));
+ cubeCards.add(new CardIdentity("Deserted Beach", ""));
+ cubeCards.add(new CardIdentity("Desperate Ritual", ""));
+ cubeCards.add(new CardIdentity("Destructive Force", ""));
+ cubeCards.add(new CardIdentity("Devoted Druid", ""));
+ cubeCards.add(new CardIdentity("Dig Through Time", ""));
+ cubeCards.add(new CardIdentity("Dimir Signet", ""));
+ cubeCards.add(new CardIdentity("Dire Fleet Daredevil", ""));
+ cubeCards.add(new CardIdentity("Disenchant", ""));
+ cubeCards.add(new CardIdentity("Dismember", ""));
+ cubeCards.add(new CardIdentity("Dockside Extortionist", ""));
+ cubeCards.add(new CardIdentity("Dragon's Rage Channeler", ""));
+ cubeCards.add(new CardIdentity("Dreamroot Cascade", ""));
+ cubeCards.add(new CardIdentity("Duress", ""));
+ cubeCards.add(new CardIdentity("Eater of Virtue", ""));
+ cubeCards.add(new CardIdentity("Echo of Eons", ""));
+ cubeCards.add(new CardIdentity("Edric, Spymaster of Trest", ""));
+ cubeCards.add(new CardIdentity("Eidolon of the Great Revel", ""));
+ cubeCards.add(new CardIdentity("Elder Gargaroth", ""));
+ cubeCards.add(new CardIdentity("Elesh Norn, Grand Cenobite", ""));
+ cubeCards.add(new CardIdentity("Elite Spellbinder", ""));
+ cubeCards.add(new CardIdentity("Elspeth Conquers Death", ""));
+ cubeCards.add(new CardIdentity("Elspeth, Knight-Errant", ""));
+ cubeCards.add(new CardIdentity("Elspeth, Sun's Champion", ""));
+ cubeCards.add(new CardIdentity("Elvish Mystic", ""));
+ cubeCards.add(new CardIdentity("Elvish Reclaimer", ""));
+ cubeCards.add(new CardIdentity("Embereth Shieldbreaker", ""));
+ cubeCards.add(new CardIdentity("Empty the Warrens", ""));
+ cubeCards.add(new CardIdentity("Emrakul, the Aeons Torn", ""));
+ cubeCards.add(new CardIdentity("Emrakul, the Promised End", ""));
+ cubeCards.add(new CardIdentity("Emry, Lurker of the Loch", ""));
+ cubeCards.add(new CardIdentity("Endurance", ""));
+ cubeCards.add(new CardIdentity("Entomb", ""));
+ cubeCards.add(new CardIdentity("Ephemerate", ""));
+ cubeCards.add(new CardIdentity("Escape to the Wilds", ""));
+ cubeCards.add(new CardIdentity("Esper Sentinel", ""));
+ cubeCards.add(new CardIdentity("Eternal Witness", ""));
+ cubeCards.add(new CardIdentity("Eureka", ""));
+ cubeCards.add(new CardIdentity("Everflowing Chalice", ""));
+ cubeCards.add(new CardIdentity("Exhume", ""));
+ cubeCards.add(new CardIdentity("Expansion // Explosion", ""));
+ cubeCards.add(new CardIdentity("Expressive Iteration", ""));
+ cubeCards.add(new CardIdentity("Fable of the Mirror-Breaker", ""));
+ cubeCards.add(new CardIdentity("Fact or Fiction", ""));
+ cubeCards.add(new CardIdentity("Faithless Looting", ""));
+ cubeCards.add(new CardIdentity("Fallen Shinobi", ""));
+ cubeCards.add(new CardIdentity("Fastbond", ""));
+ cubeCards.add(new CardIdentity("Fatal Push", ""));
+ cubeCards.add(new CardIdentity("Fauna Shaman", ""));
+ cubeCards.add(new CardIdentity("Field of the Dead", ""));
+ cubeCards.add(new CardIdentity("Fiery Islet", ""));
+ cubeCards.add(new CardIdentity("Figure of Destiny", ""));
+ cubeCards.add(new CardIdentity("Finale of Devastation", ""));
+ cubeCards.add(new CardIdentity("Fireblast", ""));
+ cubeCards.add(new CardIdentity("Firebolt", ""));
+ cubeCards.add(new CardIdentity("Flickerwisp", ""));
+ cubeCards.add(new CardIdentity("Flooded Strand", ""));
+ cubeCards.add(new CardIdentity("Force of Negation", ""));
+ cubeCards.add(new CardIdentity("Force of Will", ""));
+ cubeCards.add(new CardIdentity("Fractured Identity", ""));
+ cubeCards.add(new CardIdentity("Frantic Search", ""));
+ cubeCards.add(new CardIdentity("Fury", ""));
+ cubeCards.add(new CardIdentity("Fyndhorn Elves", ""));
+ cubeCards.add(new CardIdentity("Gaea's Cradle", ""));
+ cubeCards.add(new CardIdentity("Garruk Relentless", ""));
+ cubeCards.add(new CardIdentity("Garruk Wildspeaker", ""));
+ cubeCards.add(new CardIdentity("Geist of Saint Traft", ""));
+ cubeCards.add(new CardIdentity("Gideon Blackblade", ""));
+ cubeCards.add(new CardIdentity("Gideon Jura", ""));
+ cubeCards.add(new CardIdentity("Gideon, Ally of Zendikar", ""));
+ cubeCards.add(new CardIdentity("Gilded Drake", ""));
+ cubeCards.add(new CardIdentity("Gilded Lotus", ""));
+ cubeCards.add(new CardIdentity("Gitaxian Probe", ""));
+ cubeCards.add(new CardIdentity("Giver of Runes", ""));
+ cubeCards.add(new CardIdentity("Glen Elendra Archmage", ""));
+ cubeCards.add(new CardIdentity("Goblin Bombardment", ""));
+ cubeCards.add(new CardIdentity("Goblin Electromancer", ""));
+ cubeCards.add(new CardIdentity("Goblin Guide", ""));
+ cubeCards.add(new CardIdentity("Goblin Rabblemaster", ""));
+ cubeCards.add(new CardIdentity("Goblin Welder", ""));
+ cubeCards.add(new CardIdentity("Godless Shrine", ""));
+ cubeCards.add(new CardIdentity("Goldspan Dragon", ""));
+ cubeCards.add(new CardIdentity("Golgari Signet", ""));
+ cubeCards.add(new CardIdentity("Golos, Tireless Pilgrim", ""));
+ cubeCards.add(new CardIdentity("Gonti, Lord of Luxury", ""));
+ cubeCards.add(new CardIdentity("Grave Titan", ""));
+ cubeCards.add(new CardIdentity("Green Sun's Zenith", ""));
+ cubeCards.add(new CardIdentity("Grief", ""));
+ cubeCards.add(new CardIdentity("Grim Lavamancer", ""));
+ cubeCards.add(new CardIdentity("Grim Monolith", ""));
+ cubeCards.add(new CardIdentity("Griselbrand", ""));
+ cubeCards.add(new CardIdentity("Grist, the Hunger Tide", ""));
+ cubeCards.add(new CardIdentity("Gruul Signet", ""));
+ cubeCards.add(new CardIdentity("Gush", ""));
+ cubeCards.add(new CardIdentity("Halana and Alena, Partners", ""));
+ cubeCards.add(new CardIdentity("Hallowed Fountain", ""));
+ cubeCards.add(new CardIdentity("Hangarback Walker", ""));
+ cubeCards.add(new CardIdentity("Haunted Ridge", ""));
+ cubeCards.add(new CardIdentity("Hazoret the Fervent", ""));
+ cubeCards.add(new CardIdentity("Heartbeat of Spring", ""));
+ cubeCards.add(new CardIdentity("Hellrider", ""));
+ cubeCards.add(new CardIdentity("Hero of Bladehold", ""));
+ cubeCards.add(new CardIdentity("Hero's Downfall", ""));
+ cubeCards.add(new CardIdentity("Hexdrinker", ""));
+ cubeCards.add(new CardIdentity("High Tide", ""));
+ cubeCards.add(new CardIdentity("Horizon Canopy", ""));
+ cubeCards.add(new CardIdentity("Hornet Queen", ""));
+ cubeCards.add(new CardIdentity("Hullbreaker Horror", ""));
+ cubeCards.add(new CardIdentity("Huntmaster of the Fells", ""));
+ cubeCards.add(new CardIdentity("Hydroid Krasis", ""));
+ cubeCards.add(new CardIdentity("Hymn to Tourach", ""));
+ cubeCards.add(new CardIdentity("Ignoble Hierarch", ""));
+ cubeCards.add(new CardIdentity("Imperial Recruiter", ""));
+ cubeCards.add(new CardIdentity("Imperial Seal", ""));
+ cubeCards.add(new CardIdentity("Incinerate", ""));
+ cubeCards.add(new CardIdentity("Infernal Grasp", ""));
+ cubeCards.add(new CardIdentity("Inferno Titan", ""));
+ cubeCards.add(new CardIdentity("Inkwell Leviathan", ""));
+ cubeCards.add(new CardIdentity("Inquisition of Kozilek", ""));
+ cubeCards.add(new CardIdentity("Inspiring Vantage", ""));
+ cubeCards.add(new CardIdentity("Intrepid Adversary", ""));
+ cubeCards.add(new CardIdentity("Iona, Shield of Emeria", ""));
+ cubeCards.add(new CardIdentity("Izzet Signet", ""));
+ cubeCards.add(new CardIdentity("Jace, the Mind Sculptor", ""));
+ cubeCards.add(new CardIdentity("Jace, Vryn's Prodigy", ""));
+ cubeCards.add(new CardIdentity("Jin-Gitaxias, Progress Tyrant", ""));
+ cubeCards.add(new CardIdentity("Jokulhaups", ""));
+ cubeCards.add(new CardIdentity("Joraga Treespeaker", ""));
+ cubeCards.add(new CardIdentity("Karakas", ""));
+ cubeCards.add(new CardIdentity("Karmic Guide", ""));
+ cubeCards.add(new CardIdentity("Karn Liberated", ""));
+ cubeCards.add(new CardIdentity("Karn, Scion of Urza", ""));
+ cubeCards.add(new CardIdentity("Kiki-Jiki, Mirror Breaker", ""));
+ cubeCards.add(new CardIdentity("Kitchen Finks", ""));
+ cubeCards.add(new CardIdentity("Knight of Autumn", ""));
+ cubeCards.add(new CardIdentity("Knight of the Reliquary", ""));
+ cubeCards.add(new CardIdentity("Kogla, the Titan Ape", ""));
+ cubeCards.add(new CardIdentity("Kolaghan's Command", ""));
+ cubeCards.add(new CardIdentity("Koth of the Hammer", ""));
+ cubeCards.add(new CardIdentity("Kroxa, Titan of Death's Hunger", ""));
+ cubeCards.add(new CardIdentity("Kuldotha Forgemaster", ""));
+ cubeCards.add(new CardIdentity("Laelia, the Blade Reforged", ""));
+ cubeCards.add(new CardIdentity("Land Tax", ""));
+ cubeCards.add(new CardIdentity("Lavaclaw Reaches", ""));
+ cubeCards.add(new CardIdentity("Leonin Relic-Warder", ""));
+ cubeCards.add(new CardIdentity("Leovold, Emissary of Trest", ""));
+ cubeCards.add(new CardIdentity("Library of Alexandria", ""));
+ cubeCards.add(new CardIdentity("Life from the Loam", ""));
+ cubeCards.add(new CardIdentity("Light Up the Stage", ""));
+ cubeCards.add(new CardIdentity("Lightning Bolt", ""));
+ cubeCards.add(new CardIdentity("Lightning Helix", ""));
+ cubeCards.add(new CardIdentity("Liliana of the Veil", ""));
+ cubeCards.add(new CardIdentity("Liliana, the Last Hope", ""));
+ cubeCards.add(new CardIdentity("Lion Sash", ""));
+ cubeCards.add(new CardIdentity("Lion's Eye Diamond", ""));
+ cubeCards.add(new CardIdentity("Living Death", ""));
+ cubeCards.add(new CardIdentity("Llanowar Elves", ""));
+ cubeCards.add(new CardIdentity("Lodestone Golem", ""));
+ cubeCards.add(new CardIdentity("Lotus Bloom", ""));
+ cubeCards.add(new CardIdentity("Lotus Petal", ""));
+ cubeCards.add(new CardIdentity("Lurrus of the Dream-Den", ""));
+ cubeCards.add(new CardIdentity("Lyra Dawnbringer", ""));
+ cubeCards.add(new CardIdentity("Maelstrom Pulse", ""));
+ cubeCards.add(new CardIdentity("Magus of the Order", ""));
+ cubeCards.add(new CardIdentity("Makeshift Mannequin", ""));
+ cubeCards.add(new CardIdentity("Mana Crypt", ""));
+ cubeCards.add(new CardIdentity("Mana Drain", ""));
+ cubeCards.add(new CardIdentity("Mana Flare", ""));
+ cubeCards.add(new CardIdentity("Mana Leak", ""));
+ cubeCards.add(new CardIdentity("Mana Tithe", ""));
+ cubeCards.add(new CardIdentity("Mana Vault", ""));
+ cubeCards.add(new CardIdentity("Manamorphose", ""));
+ cubeCards.add(new CardIdentity("Marsh Flats", ""));
+ cubeCards.add(new CardIdentity("Massacre Wurm", ""));
+ cubeCards.add(new CardIdentity("Memory Deluge", ""));
+ cubeCards.add(new CardIdentity("Memory Jar", ""));
+ cubeCards.add(new CardIdentity("Mesmeric Fiend", ""));
+ cubeCards.add(new CardIdentity("Metalworker", ""));
+ cubeCards.add(new CardIdentity("Mind Twist", ""));
+ cubeCards.add(new CardIdentity("Mind's Desire", ""));
+ cubeCards.add(new CardIdentity("Mindslaver", ""));
+ cubeCards.add(new CardIdentity("Mirari's Wake", ""));
+ cubeCards.add(new CardIdentity("Miscalculation", ""));
+ cubeCards.add(new CardIdentity("Mishra's Factory", ""));
+ cubeCards.add(new CardIdentity("Mishra's Workshop", ""));
+ cubeCards.add(new CardIdentity("Misty Rainforest", ""));
+ cubeCards.add(new CardIdentity("Monastery Mentor", ""));
+ cubeCards.add(new CardIdentity("Monastery Swiftspear", ""));
+ cubeCards.add(new CardIdentity("Mother of Runes", ""));
+ cubeCards.add(new CardIdentity("Mox Diamond", ""));
+ cubeCards.add(new CardIdentity("Mox Emerald", ""));
+ cubeCards.add(new CardIdentity("Mox Jet", ""));
+ cubeCards.add(new CardIdentity("Mox Pearl", ""));
+ cubeCards.add(new CardIdentity("Mox Ruby", ""));
+ cubeCards.add(new CardIdentity("Mox Sapphire", ""));
+ cubeCards.add(new CardIdentity("Mulldrifter", ""));
+ cubeCards.add(new CardIdentity("Murderous Rider", ""));
+ cubeCards.add(new CardIdentity("Murktide Regent", ""));
+ cubeCards.add(new CardIdentity("Mutavault", ""));
+ cubeCards.add(new CardIdentity("Myr Battlesphere", ""));
+ cubeCards.add(new CardIdentity("Mystic Confluence", ""));
+ cubeCards.add(new CardIdentity("Mystical Tutor", ""));
+ cubeCards.add(new CardIdentity("Nahiri, the Harbinger", ""));
+ cubeCards.add(new CardIdentity("Narset, Parter of Veils", ""));
+ cubeCards.add(new CardIdentity("Nashi, Moon Sage's Scion", ""));
+ cubeCards.add(new CardIdentity("Natural Order", ""));
+ cubeCards.add(new CardIdentity("Necromancy", ""));
+ cubeCards.add(new CardIdentity("Night's Whisper", ""));
+ cubeCards.add(new CardIdentity("Nighthawk Scavenger", ""));
+ cubeCards.add(new CardIdentity("Nissa, Vastwood Seer", ""));
+ cubeCards.add(new CardIdentity("Nissa, Who Shakes the World", ""));
+ cubeCards.add(new CardIdentity("Niv-Mizzet Reborn", ""));
+ cubeCards.add(new CardIdentity("Noble Hierarch", ""));
+ cubeCards.add(new CardIdentity("Nurturing Peatland", ""));
+ cubeCards.add(new CardIdentity("Oath of Druids", ""));
+ cubeCards.add(new CardIdentity("Oblivion Stone", ""));
+ cubeCards.add(new CardIdentity("Oko, Thief of Crowns", ""));
+ cubeCards.add(new CardIdentity("Olivia, Crimson Bride", ""));
+ cubeCards.add(new CardIdentity("Omnath, Locus of Creation", ""));
+ cubeCards.add(new CardIdentity("Oona's Prowler", ""));
+ cubeCards.add(new CardIdentity("Ophiomancer", ""));
+ cubeCards.add(new CardIdentity("Opposition", ""));
+ cubeCards.add(new CardIdentity("Oracle of Mul Daya", ""));
+ cubeCards.add(new CardIdentity("Orzhov Signet", ""));
+ cubeCards.add(new CardIdentity("Oust", ""));
+ cubeCards.add(new CardIdentity("Overgrown Farmland", ""));
+ cubeCards.add(new CardIdentity("Overgrown Tomb", ""));
+ cubeCards.add(new CardIdentity("Pack Rat", ""));
+ cubeCards.add(new CardIdentity("Palace Jailer", ""));
+ cubeCards.add(new CardIdentity("Palinchron", ""));
+ cubeCards.add(new CardIdentity("Parallax Wave", ""));
+ cubeCards.add(new CardIdentity("Past in Flames", ""));
+ cubeCards.add(new CardIdentity("Path to Exile", ""));
+ cubeCards.add(new CardIdentity("Pest Infestation", ""));
+ cubeCards.add(new CardIdentity("Pestermite", ""));
+ cubeCards.add(new CardIdentity("Phantasmal Image", ""));
+ cubeCards.add(new CardIdentity("Phyrexian Metamorph", ""));
+ cubeCards.add(new CardIdentity("Phyrexian Revoker", ""));
+ cubeCards.add(new CardIdentity("Pia and Kiran Nalaar", ""));
+ cubeCards.add(new CardIdentity("Plateau", ""));
+ cubeCards.add(new CardIdentity("Plow Under", ""));
+ cubeCards.add(new CardIdentity("Polluted Delta", ""));
+ cubeCards.add(new CardIdentity("Polukranos, World Eater", ""));
+ cubeCards.add(new CardIdentity("Ponder", ""));
+ cubeCards.add(new CardIdentity("Porcelain Legionnaire", ""));
+ cubeCards.add(new CardIdentity("Portent", ""));
+ cubeCards.add(new CardIdentity("Preordain", ""));
+ cubeCards.add(new CardIdentity("Primeval Titan", ""));
+ cubeCards.add(new CardIdentity("Prismatic Vista", ""));
+ cubeCards.add(new CardIdentity("Progenitus", ""));
+ cubeCards.add(new CardIdentity("Putrid Imp", ""));
+ cubeCards.add(new CardIdentity("Pyretic Ritual", ""));
+ cubeCards.add(new CardIdentity("Questing Beast", ""));
+ cubeCards.add(new CardIdentity("Ragavan, Nimble Pilferer", ""));
+ cubeCards.add(new CardIdentity("Raging Ravine", ""));
+ cubeCards.add(new CardIdentity("Rakdos Signet", ""));
+ cubeCards.add(new CardIdentity("Ramunap Excavator", ""));
+ cubeCards.add(new CardIdentity("Ravages of War", ""));
+ cubeCards.add(new CardIdentity("Ravenous Chupacabra", ""));
+ cubeCards.add(new CardIdentity("Razorverge Thicket", ""));
+ cubeCards.add(new CardIdentity("Reanimate", ""));
+ cubeCards.add(new CardIdentity("Reclamation Sage", ""));
+ cubeCards.add(new CardIdentity("Recruiter of the Guard", ""));
+ cubeCards.add(new CardIdentity("Recurring Nightmare", ""));
+ cubeCards.add(new CardIdentity("Red Elemental Blast", ""));
+ cubeCards.add(new CardIdentity("Regrowth", ""));
+ cubeCards.add(new CardIdentity("Relic of Progenitus", ""));
+ cubeCards.add(new CardIdentity("Remand", ""));
+ cubeCards.add(new CardIdentity("Repeal", ""));
+ cubeCards.add(new CardIdentity("Restoration Angel", ""));
+ cubeCards.add(new CardIdentity("Retrofitter Foundry", ""));
+ cubeCards.add(new CardIdentity("Rishadan Port", ""));
+ cubeCards.add(new CardIdentity("Rockfall Vale", ""));
+ cubeCards.add(new CardIdentity("Rofellos, Llanowar Emissary", ""));
+ cubeCards.add(new CardIdentity("Rotting Regisaur", ""));
+ cubeCards.add(new CardIdentity("Runaway Steam-Kin", ""));
+ cubeCards.add(new CardIdentity("Sacred Foundry", ""));
+ cubeCards.add(new CardIdentity("Sakura-Tribe Elder", ""));
+ cubeCards.add(new CardIdentity("Satoru Umezawa", ""));
+ cubeCards.add(new CardIdentity("Savannah", ""));
+ cubeCards.add(new CardIdentity("Scalding Tarn", ""));
+ cubeCards.add(new CardIdentity("Scavenging Ooze", ""));
+ cubeCards.add(new CardIdentity("Scrapheap Scrounger", ""));
+ cubeCards.add(new CardIdentity("Scrubland", ""));
+ cubeCards.add(new CardIdentity("Sea Gate Stormcaller", ""));
+ cubeCards.add(new CardIdentity("Seachrome Coast", ""));
+ cubeCards.add(new CardIdentity("Seasoned Pyromancer", ""));
+ cubeCards.add(new CardIdentity("Sedgemoor Witch", ""));
+ cubeCards.add(new CardIdentity("Seething Song", ""));
+ cubeCards.add(new CardIdentity("Selesnya Signet", ""));
+ cubeCards.add(new CardIdentity("Selfless Spirit", ""));
+ cubeCards.add(new CardIdentity("Sensei's Divining Top", ""));
+ cubeCards.add(new CardIdentity("Shallow Grave", ""));
+ cubeCards.add(new CardIdentity("Shark Typhoon", ""));
+ cubeCards.add(new CardIdentity("Shattered Sanctum", ""));
+ cubeCards.add(new CardIdentity("Shelldock Isle", ""));
+ cubeCards.add(new CardIdentity("Shipwreck Marsh", ""));
+ cubeCards.add(new CardIdentity("Show and Tell", ""));
+ cubeCards.add(new CardIdentity("Showdown of the Skalds", ""));
+ cubeCards.add(new CardIdentity("Shriekmaw", ""));
+ cubeCards.add(new CardIdentity("Silent Clearing", ""));
+ cubeCards.add(new CardIdentity("Silverblade Paladin", ""));
+ cubeCards.add(new CardIdentity("Simic Signet", ""));
+ cubeCards.add(new CardIdentity("Skullclamp", ""));
+ cubeCards.add(new CardIdentity("Skyclave Apparition", ""));
+ cubeCards.add(new CardIdentity("Skyclave Shade", ""));
+ cubeCards.add(new CardIdentity("Smokestack", ""));
+ cubeCards.add(new CardIdentity("Smuggler's Copter", ""));
+ cubeCards.add(new CardIdentity("Snapcaster Mage", ""));
+ cubeCards.add(new CardIdentity("Sneak Attack", ""));
+ cubeCards.add(new CardIdentity("Snuff Out", ""));
+ cubeCards.add(new CardIdentity("Sol Ring", ""));
+ cubeCards.add(new CardIdentity("Solitude", ""));
+ cubeCards.add(new CardIdentity("Soulfire Grand Master", ""));
+ cubeCards.add(new CardIdentity("Sower of Temptation", ""));
+ cubeCards.add(new CardIdentity("Spear of Heliod", ""));
+ cubeCards.add(new CardIdentity("Spectral Procession", ""));
+ cubeCards.add(new CardIdentity("Spell Pierce", ""));
+ cubeCards.add(new CardIdentity("Spellseeker", ""));
+ cubeCards.add(new CardIdentity("Sphinx of the Steel Wind", ""));
+ cubeCards.add(new CardIdentity("Spirebluff Canal", ""));
+ cubeCards.add(new CardIdentity("Spirit-Sister's Call", ""));
+ cubeCards.add(new CardIdentity("Splinter Twin", ""));
+ cubeCards.add(new CardIdentity("Steam Vents", ""));
+ cubeCards.add(new CardIdentity("Stomping Ground", ""));
+ cubeCards.add(new CardIdentity("Stoneforge Mystic", ""));
+ cubeCards.add(new CardIdentity("Stormcarved Coast", ""));
+ cubeCards.add(new CardIdentity("Strip Mine", ""));
+ cubeCards.add(new CardIdentity("Student of Warfare", ""));
+ cubeCards.add(new CardIdentity("Sulfuric Vortex", ""));
+ cubeCards.add(new CardIdentity("Sun Titan", ""));
+ cubeCards.add(new CardIdentity("Sunbaked Canyon", ""));
+ cubeCards.add(new CardIdentity("Sundering Titan", ""));
+ cubeCards.add(new CardIdentity("Sundown Pass", ""));
+ cubeCards.add(new CardIdentity("Survival of the Fittest", ""));
+ cubeCards.add(new CardIdentity("Suspicious Stowaway", ""));
+ cubeCards.add(new CardIdentity("Sword of Body and Mind", ""));
+ cubeCards.add(new CardIdentity("Sword of Feast and Famine", ""));
+ cubeCards.add(new CardIdentity("Sword of Fire and Ice", ""));
+ cubeCards.add(new CardIdentity("Swords to Plowshares", ""));
+ cubeCards.add(new CardIdentity("Sylvan Caryatid", ""));
+ cubeCards.add(new CardIdentity("Sylvan Library", ""));
+ cubeCards.add(new CardIdentity("Taiga", ""));
+ cubeCards.add(new CardIdentity("Tamiyo, Compleated Sage", ""));
+ cubeCards.add(new CardIdentity("Tangle Wire", ""));
+ cubeCards.add(new CardIdentity("Teferi, Hero of Dominaria", ""));
+ cubeCards.add(new CardIdentity("Teferi, Time Raveler", ""));
+ cubeCards.add(new CardIdentity("Temple Garden", ""));
+ cubeCards.add(new CardIdentity("Tendrils of Agony", ""));
+ cubeCards.add(new CardIdentity("Terastodon", ""));
+ cubeCards.add(new CardIdentity("Tezzeret the Seeker", ""));
+ cubeCards.add(new CardIdentity("Thalia, Guardian of Thraben", ""));
+ cubeCards.add(new CardIdentity("Thassa's Oracle", ""));
+ cubeCards.add(new CardIdentity("The Gitrog Monster", ""));
+ cubeCards.add(new CardIdentity("The Restoration of Eiganjo", ""));
+ cubeCards.add(new CardIdentity("The Scarab God", ""));
+ cubeCards.add(new CardIdentity("The Wandering Emperor", ""));
+ cubeCards.add(new CardIdentity("Thespian's Stage", ""));
+ cubeCards.add(new CardIdentity("Thieving Skydiver", ""));
+ cubeCards.add(new CardIdentity("Thirst for Discovery", ""));
+ cubeCards.add(new CardIdentity("Thoughtseize", ""));
+ cubeCards.add(new CardIdentity("Thousand-Year Storm", ""));
+ cubeCards.add(new CardIdentity("Thraben Inspector", ""));
+ cubeCards.add(new CardIdentity("Thragtusk", ""));
+ cubeCards.add(new CardIdentity("Thran Dynamo", ""));
+ cubeCards.add(new CardIdentity("Through the Breach", ""));
+ cubeCards.add(new CardIdentity("Thundermaw Hellkite", ""));
+ cubeCards.add(new CardIdentity("Tidehollow Sculler", ""));
+ cubeCards.add(new CardIdentity("Time Spiral", ""));
+ cubeCards.add(new CardIdentity("Time Walk", ""));
+ cubeCards.add(new CardIdentity("Time Warp", ""));
+ cubeCards.add(new CardIdentity("Timetwister", ""));
+ cubeCards.add(new CardIdentity("Tinker", ""));
+ cubeCards.add(new CardIdentity("Tireless Tracker", ""));
+ cubeCards.add(new CardIdentity("Tolarian Academy", ""));
+ cubeCards.add(new CardIdentity("Toski, Bearer of Secrets", ""));
+ cubeCards.add(new CardIdentity("Tovolar's Huntmaster", ""));
+ cubeCards.add(new CardIdentity("Toxic Deluge", ""));
+ cubeCards.add(new CardIdentity("Treachery", ""));
+ cubeCards.add(new CardIdentity("Treasure Cruise", ""));
+ cubeCards.add(new CardIdentity("Trinket Mage", ""));
+ cubeCards.add(new CardIdentity("Tropical Island", ""));
+ cubeCards.add(new CardIdentity("Tundra", ""));
+ cubeCards.add(new CardIdentity("Turnabout", ""));
+ cubeCards.add(new CardIdentity("Ugin, the Spirit Dragon", ""));
+ cubeCards.add(new CardIdentity("Ulamog, the Ceaseless Hunger", ""));
+ cubeCards.add(new CardIdentity("Ulamog, the Infinite Gyre", ""));
+ cubeCards.add(new CardIdentity("Umezawa's Jitte", ""));
+ cubeCards.add(new CardIdentity("Unburial Rites", ""));
+ cubeCards.add(new CardIdentity("Underground Sea", ""));
+ cubeCards.add(new CardIdentity("Underworld Breach", ""));
+ cubeCards.add(new CardIdentity("Unholy Heat", ""));
+ cubeCards.add(new CardIdentity("Upheaval", ""));
+ cubeCards.add(new CardIdentity("Uro, Titan of Nature's Wrath", ""));
+ cubeCards.add(new CardIdentity("Urza's Saga", ""));
+ cubeCards.add(new CardIdentity("Urza, Lord High Artificer", ""));
+ cubeCards.add(new CardIdentity("Usher of the Fallen", ""));
+ cubeCards.add(new CardIdentity("Utopia Sprawl", ""));
+ cubeCards.add(new CardIdentity("Vampire Hexmage", ""));
+ cubeCards.add(new CardIdentity("Vampiric Tutor", ""));
+ cubeCards.add(new CardIdentity("Vendilion Clique", ""));
+ cubeCards.add(new CardIdentity("Venser, Shaper Savant", ""));
+ cubeCards.add(new CardIdentity("Verdant Catacombs", ""));
+ cubeCards.add(new CardIdentity("Vindicate", ""));
+ cubeCards.add(new CardIdentity("Volcanic Island", ""));
+ cubeCards.add(new CardIdentity("Volrath's Stronghold", ""));
+ cubeCards.add(new CardIdentity("Voltaic Visionary", ""));
+ cubeCards.add(new CardIdentity("Vraska, Golgari Queen", ""));
+ cubeCards.add(new CardIdentity("Vryn Wingmare", ""));
+ cubeCards.add(new CardIdentity("Walking Ballista", ""));
+ cubeCards.add(new CardIdentity("Wall of Omens", ""));
+ cubeCards.add(new CardIdentity("Wall of Roots", ""));
+ cubeCards.add(new CardIdentity("Wasteland", ""));
+ cubeCards.add(new CardIdentity("Waterlogged Grove", ""));
+ cubeCards.add(new CardIdentity("Watery Grave", ""));
+ cubeCards.add(new CardIdentity("Wear // Tear", ""));
+ cubeCards.add(new CardIdentity("Wheel of Fortune", ""));
+ cubeCards.add(new CardIdentity("Wheel of Misfortune", ""));
+ cubeCards.add(new CardIdentity("Whisperwood Elemental", ""));
+ cubeCards.add(new CardIdentity("Windswept Heath", ""));
+ cubeCards.add(new CardIdentity("Winter Orb", ""));
+ cubeCards.add(new CardIdentity("Wishclaw Talisman", ""));
+ cubeCards.add(new CardIdentity("Woe Strider", ""));
+ cubeCards.add(new CardIdentity("Wooded Foothills", ""));
+ cubeCards.add(new CardIdentity("Woodfall Primus", ""));
+ cubeCards.add(new CardIdentity("Worldly Tutor", ""));
+ cubeCards.add(new CardIdentity("Worn Powerstone", ""));
+ cubeCards.add(new CardIdentity("Wrath of God", ""));
+ cubeCards.add(new CardIdentity("Wrenn and Six", ""));
+ cubeCards.add(new CardIdentity("Wurmcoil Engine", ""));
+ cubeCards.add(new CardIdentity("Yawgmoth's Bargain", ""));
+ cubeCards.add(new CardIdentity("Yawgmoth's Will", ""));
+ cubeCards.add(new CardIdentity("Yorion, Sky Nomad", ""));
+ cubeCards.add(new CardIdentity("Young Pyromancer", ""));
+ cubeCards.add(new CardIdentity("Zealous Conscripts", ""));
+ }
+}
+
diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml
index 98e89221bc2..13840ba7b4f 100644
--- a/Mage.Server/config/config.xml
+++ b/Mage.Server/config/config.xml
@@ -123,6 +123,7 @@
+
@@ -153,6 +154,7 @@
+
diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml
index b2b663f6b41..8b7709a0c7f 100644
--- a/Mage.Server/release/config/config.xml
+++ b/Mage.Server/release/config/config.xml
@@ -115,6 +115,7 @@
+
@@ -145,6 +146,7 @@
+
diff --git a/Mage.Sets/src/mage/cards/a/ALittleChat.java b/Mage.Sets/src/mage/cards/a/ALittleChat.java
new file mode 100644
index 00000000000..ff344510382
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ALittleChat.java
@@ -0,0 +1,35 @@
+package mage.cards.a;
+
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
+import mage.abilities.keyword.CasualtyAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ALittleChat extends CardImpl {
+
+ public ALittleChat(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
+
+ // Casualty 1
+ this.addAbility(new CasualtyAbility(this, 1));
+
+ // Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library.
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(2, 1, PutCards.HAND, PutCards.BOTTOM_ANY));
+ }
+
+ private ALittleChat(final ALittleChat card) {
+ super(card);
+ }
+
+ @Override
+ public ALittleChat copy() {
+ return new ALittleChat(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AbandonReason.java b/Mage.Sets/src/mage/cards/a/AbandonReason.java
index a34140c11b6..10e297ca4ec 100644
--- a/Mage.Sets/src/mage/cards/a/AbandonReason.java
+++ b/Mage.Sets/src/mage/cards/a/AbandonReason.java
@@ -12,6 +12,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
+import mage.constants.Outcome;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -25,6 +26,7 @@ public final class AbandonReason extends CardImpl {
// Up to two target creatures each get +1/+0 and gain first strike until end of turn.
Effect effect = new BoostTargetEffect(1, 0, Duration.EndOfTurn);
+ effect.setOutcome(Outcome.Benefit);
effect.setText("Up to two target creatures each get +1/+0");
this.getSpellAbility().addEffect(effect);
effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, "and gain first strike until end of turn");
@@ -32,7 +34,7 @@ public final class AbandonReason extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
// Madness {1}{R}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{1}{R}")));
}
private AbandonReason(final AbandonReason card) {
diff --git a/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java b/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java
index fc4253b964a..1c1bb693c25 100644
--- a/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java
+++ b/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java
@@ -3,6 +3,7 @@ package mage.cards.a;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
@@ -25,13 +26,17 @@ import mage.watchers.Watcher;
*/
public final class AbandonedSarcophagus extends CardImpl {
+ private static final FilterCard filter = new FilterCard("nonland cards with cycling");
+
+ static {
+ filter.add(Predicates.not(CardType.LAND.getPredicate()));
+ filter.add(new AbilityPredicate(CyclingAbility.class));
+ }
+
public AbandonedSarcophagus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// You may cast nonland cards with cycling from your graveyard.
- FilterCard filter = new FilterCard("nonland cards with cycling");
- filter.add(Predicates.not(CardType.LAND.getPredicate()));
- filter.add(new AbilityPredicate(CyclingAbility.class));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new PlayFromNotOwnHandZoneAllEffect(filter,
Zone.GRAVEYARD, true, TargetController.YOU, Duration.WhileOnBattlefield)
@@ -77,16 +82,20 @@ class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent != null) {
- return controller.moveCards(permanent, Zone.EXILED, source, game);
- }
- Card card = game.getCard(event.getTargetId());
- if (card != null) {
- return controller.moveCards(card, Zone.EXILED, source, game);
- }
+ if (controller == null) {
+ return false;
}
+
+ Permanent permanent = game.getPermanent(event.getTargetId());
+ if (permanent != null) {
+ return controller.moveCards(permanent, Zone.EXILED, source, game);
+ }
+
+ Card card = game.getCard(event.getTargetId());
+ if (card != null) {
+ return controller.moveCards(card, Zone.EXILED, source, game);
+ }
+
return false;
}
@@ -97,32 +106,46 @@ class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- boolean cardWasCycledThisTurn = false;
- boolean cardHasCycling = false;
if (!(((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD)) {
return false;
}
+
Player controller = game.getPlayer(source.getControllerId());
- AbandonedSarcophagusWatcher watcher = game.getState().getWatcher(AbandonedSarcophagusWatcher.class);
- Card card = game.getCard(event.getTargetId());
- if (card == null
- || controller == null
- || watcher == null
- || !card.isOwnedBy(controller.getId())) {
+ if (controller == null) {
return false;
}
+
+ Card card = game.getCard(event.getTargetId());
+ if (card == null) {
+ return false;
+ }
+ if (!card.isOwnedBy(controller.getId())) {
+ return false;
+ }
+
+ AbandonedSarcophagusWatcher watcher = game.getState().getWatcher(AbandonedSarcophagusWatcher.class);
+ if (watcher == null) {
+ return false;
+ }
+
+ boolean cardHasCycling = false;
for (Ability ability : card.getAbilities(game)) {
if (ability instanceof CyclingAbility) {
cardHasCycling = true;
+ break;
}
}
+
Cards cards = watcher.getCardsCycledThisTurn(controller.getId());
- for (Card c : cards.getCards(game)) {
- if (c == card) {
+ boolean cardWasCycledThisTurn = false;
+
+ for (Card cardCycledThisTurn : cards.getCards(game)) {
+ if (cardCycledThisTurn == card) {
cardWasCycledThisTurn = true;
watcher.getCardsCycledThisTurn(controller.getId()).remove(card); //remove reference to the card as it is no longer needed
}
}
+
return !cardWasCycledThisTurn && cardHasCycling;
}
}
@@ -137,17 +160,26 @@ class AbandonedSarcophagusWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.CYCLE_CARD) {
- Card card = game.getCard(event.getSourceId());
- Player controller = game.getPlayer(event.getPlayerId());
- if (card != null
- && controller != null
- && card.isOwnedBy(controller.getId())) {
- Cards c = getCardsCycledThisTurn(event.getPlayerId());
- c.add(card);
- cycledCardsThisTurn.put(event.getPlayerId(), c);
- }
+ if (event.getType() != GameEvent.EventType.CYCLE_CARD) {
+ return;
}
+
+ Card card = game.getCard(event.getSourceId());
+ if (card == null) {
+ return;
+ }
+
+ Player controller = game.getPlayer(event.getPlayerId());
+ if (controller == null) {
+ return;
+ }
+ if (!card.isOwnedBy(controller.getId())) {
+ return;
+ }
+
+ Cards c = getCardsCycledThisTurn(event.getPlayerId());
+ c.add(card);
+ cycledCardsThisTurn.put(event.getPlayerId(), c);
}
public Cards getCardsCycledThisTurn(UUID playerId) {
diff --git a/Mage.Sets/src/mage/cards/a/Abeyance.java b/Mage.Sets/src/mage/cards/a/Abeyance.java
index 5281148c49f..3f6e49e7cc2 100644
--- a/Mage.Sets/src/mage/cards/a/Abeyance.java
+++ b/Mage.Sets/src/mage/cards/a/Abeyance.java
@@ -68,7 +68,7 @@ class AbeyanceEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't cast instant or sorcery spells or activate abilities "
+ "that aren't mana abilities this turn (" + mageObject.getIdName() + ").";
diff --git a/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java b/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java
index 57f88bca5f1..eb03cb26a99 100644
--- a/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java
+++ b/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java
@@ -14,7 +14,7 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
-import mage.game.permanent.token.TokenImpl;
+import mage.game.permanent.token.HarpyToken;
import java.util.UUID;
@@ -34,7 +34,7 @@ public final class AbhorrentOverlord extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Abhorrent Overlord enters the battlefield, create a number of 1/1 black Harpy creature tokens with flying equal to your devotion to black.
- Effect effect = new CreateTokenEffect(new AbhorrentOverlordHarpyToken(), DevotionCount.B);
+ Effect effect = new CreateTokenEffect(new HarpyToken(), DevotionCount.B);
effect.setText("create a number of 1/1 black Harpy creature tokens with flying equal to your devotion to black. (Each {B} in the mana costs of permanents you control counts toward your devotion to black.)");
this.addAbility(new EntersBattlefieldTriggeredAbility(effect).addHint(DevotionCount.B.getHint()));
@@ -51,25 +51,3 @@ public final class AbhorrentOverlord extends CardImpl {
return new AbhorrentOverlord(this);
}
}
-
-class AbhorrentOverlordHarpyToken extends TokenImpl {
-
- AbhorrentOverlordHarpyToken() {
- super("Harpy", "1/1 black Harpy creature tokens with flying");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add(SubType.HARPY);
- power = new MageInt(1);
- toughness = new MageInt(1);
-
- this.addAbility(FlyingAbility.getInstance());
- }
-
- private AbhorrentOverlordHarpyToken(final AbhorrentOverlordHarpyToken token) {
- super(token);
- }
-
- public AbhorrentOverlordHarpyToken copy() {
- return new AbhorrentOverlordHarpyToken(this);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/a/AbominationOfGudul.java b/Mage.Sets/src/mage/cards/a/AbominationOfGudul.java
index 516ee4e8729..acab700c50f 100644
--- a/Mage.Sets/src/mage/cards/a/AbominationOfGudul.java
+++ b/Mage.Sets/src/mage/cards/a/AbominationOfGudul.java
@@ -35,7 +35,7 @@ public final class AbominationOfGudul extends CardImpl {
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(effect, true));
// Morph 2BGU
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{B}{G}{U}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{2}{B}{G}{U}")));
}
private AbominationOfGudul(final AbominationOfGudul card) {
diff --git a/Mage.Sets/src/mage/cards/a/Abrade.java b/Mage.Sets/src/mage/cards/a/Abrade.java
index 697bfc9d969..6bec2a4cc02 100644
--- a/Mage.Sets/src/mage/cards/a/Abrade.java
+++ b/Mage.Sets/src/mage/cards/a/Abrade.java
@@ -25,8 +25,7 @@ public final class Abrade extends CardImpl {
getSpellAbility().addTarget(new TargetCreaturePermanent());
// Destroy target artifact.
- Mode mode = new Mode();
- mode.addEffect(new DestroyTargetEffect());
+ Mode mode = new Mode(new DestroyTargetEffect());
mode.addTarget(new TargetArtifactPermanent());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AbuJafar.java b/Mage.Sets/src/mage/cards/a/AbuJafar.java
index 15d9931ddfa..0747eb9c3e8 100644
--- a/Mage.Sets/src/mage/cards/a/AbuJafar.java
+++ b/Mage.Sets/src/mage/cards/a/AbuJafar.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.common.DestroyAllEffect;
@@ -9,28 +7,31 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
+import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.permanent.BlockedByIdPredicate;
-import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
+import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
+
+import java.util.UUID;
/**
- *
* @author MarcoMarin
*/
public final class AbuJafar extends CardImpl {
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creatures blocking or blocked by it");
+
+ static {
+ filter.add(BlockingOrBlockedBySourcePredicate.EITHER);
+ }
+
public AbuJafar(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
this.subtype.add(SubType.HUMAN);
this.power = new MageInt(0);
this.toughness = new MageInt(1);
- FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures blocking or blocked by it");
- filter.add(Predicates.or(new BlockedByIdPredicate(this.getId()),
- new BlockingAttackerIdPredicate(this.getId())));
-
- // When Abu Ja'far dies, destroy all creatures blocking or blocked by it. They can't be regenerated.
+ // When Abu Ja'far dies, destroy all creatures blocking or blocked by it. They can't be regenerated.
this.addAbility(new DiesSourceTriggeredAbility(new DestroyAllEffect(filter, true), false));
}
diff --git a/Mage.Sets/src/mage/cards/a/AbunasChant.java b/Mage.Sets/src/mage/cards/a/AbunasChant.java
index 60014da754f..22e990edba4 100644
--- a/Mage.Sets/src/mage/cards/a/AbunasChant.java
+++ b/Mage.Sets/src/mage/cards/a/AbunasChant.java
@@ -28,8 +28,7 @@ public final class AbunasChant extends CardImpl {
//You gain 5 life;
this.getSpellAbility().addEffect(new GainLifeEffect(5));
//or prevent the next 5 damage that would be dealt to target creature this turn.
- Mode mode = new Mode();
- mode.addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, 5));
+ Mode mode = new Mode(new PreventDamageToTargetEffect(Duration.EndOfTurn, 5));
mode.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().getModes().addMode(mode);
// Entwine {2}
diff --git a/Mage.Sets/src/mage/cards/a/Abundance.java b/Mage.Sets/src/mage/cards/a/Abundance.java
index 2e4522f30d4..a7a1f9fed52 100644
--- a/Mage.Sets/src/mage/cards/a/Abundance.java
+++ b/Mage.Sets/src/mage/cards/a/Abundance.java
@@ -64,7 +64,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(event.getPlayerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller != null && sourceObject != null) {
FilterCard filter = new FilterCard();
if (controller.chooseUse(Outcome.Detriment, "Choose card type:",
@@ -79,7 +79,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl {
Card selectedCard = null;
for (Card card : controller.getLibrary().getCards(game)) {
toReveal.add(card);
- if (filter.match(card, source.getSourceId(), source.getControllerId(), game)) {
+ if (filter.match(card, source.getControllerId(), source, game)) {
selectedCard = card;
break;
}
diff --git a/Mage.Sets/src/mage/cards/a/AbzanCharm.java b/Mage.Sets/src/mage/cards/a/AbzanCharm.java
index 577ebe8ea8a..fbd888d447c 100644
--- a/Mage.Sets/src/mage/cards/a/AbzanCharm.java
+++ b/Mage.Sets/src/mage/cards/a/AbzanCharm.java
@@ -38,14 +38,12 @@ public final class AbzanCharm extends CardImpl {
this.getSpellAbility().addEffect(new ExileTargetEffect());
// *You draw two cards and you lose 2 life
- Mode mode = new Mode();
- mode.addEffect(new DrawCardSourceControllerEffect(2));
+ Mode mode = new Mode(new DrawCardSourceControllerEffect(2));
mode.addEffect(new LoseLifeSourceControllerEffect(2));
this.getSpellAbility().addMode(mode);
// *Distribute two +1/+1 counters among one or two target creatures.
- mode = new Mode();
- mode.addEffect(new DistributeCountersEffect(CounterType.P1P1, 2, false, "one or two target creatures"));
+ mode = new Mode(new DistributeCountersEffect(CounterType.P1P1, 2, false, "one or two target creatures"));
mode.addTarget(new TargetCreaturePermanentAmount(2));
this.getSpellAbility().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/a/AbzanGuide.java b/Mage.Sets/src/mage/cards/a/AbzanGuide.java
index 16b0df19ffb..4f64e3f24fc 100644
--- a/Mage.Sets/src/mage/cards/a/AbzanGuide.java
+++ b/Mage.Sets/src/mage/cards/a/AbzanGuide.java
@@ -28,7 +28,7 @@ public final class AbzanGuide extends CardImpl {
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// Morph {2}{W}{B}{G}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{W}{B}{G}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{2}{W}{B}{G}")));
}
private AbzanGuide(final AbzanGuide card) {
diff --git a/Mage.Sets/src/mage/cards/a/AcademicProbation.java b/Mage.Sets/src/mage/cards/a/AcademicProbation.java
index 229bc44c342..5c99e662b25 100644
--- a/Mage.Sets/src/mage/cards/a/AcademicProbation.java
+++ b/Mage.Sets/src/mage/cards/a/AcademicProbation.java
@@ -37,8 +37,7 @@ public final class AcademicProbation extends CardImpl {
this.getSpellAbility().addEffect(new OpponentsCantCastChosenUntilNextTurnEffect().setText("opponents can't cast spells with the chosen name until your next turn"));
// • Choose target nonland permanent. Until your next turn, it can't attack or block, and its activated abilities can't be activated.
- Mode restrictMode = new Mode();
- restrictMode.addEffect(new AcademicProbationRestrictionEffect());
+ Mode restrictMode = new Mode(new AcademicProbationRestrictionEffect());
restrictMode.addTarget(new TargetNonlandPermanent());
this.getSpellAbility().addMode(restrictMode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AcademyResearchers.java b/Mage.Sets/src/mage/cards/a/AcademyResearchers.java
index b6646bf014e..0aaa9bbba05 100644
--- a/Mage.Sets/src/mage/cards/a/AcademyResearchers.java
+++ b/Mage.Sets/src/mage/cards/a/AcademyResearchers.java
@@ -73,7 +73,7 @@ class AcademyResearchersEffect extends OneShotEffect {
if (controller != null && academyResearchers != null) {
filterCardInHand.add(new AuraCardCanAttachToPermanentId(academyResearchers.getId()));
TargetCardInHand target = new TargetCardInHand(0, 1, filterCardInHand);
- if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
+ if (controller.choose(Outcome.PutCardInPlay, target, source, game)) {
Card auraInHand = game.getCard(target.getFirstTarget());
if (auraInHand != null) {
game.getState().setValue("attachTo:" + auraInHand.getId(), academyResearchers);
diff --git a/Mage.Sets/src/mage/cards/a/AcademyRuins.java b/Mage.Sets/src/mage/cards/a/AcademyRuins.java
index 4a5bf489d83..71f1b35cff6 100644
--- a/Mage.Sets/src/mage/cards/a/AcademyRuins.java
+++ b/Mage.Sets/src/mage/cards/a/AcademyRuins.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
@@ -13,17 +11,18 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.constants.Zone;
-import mage.filter.common.FilterArtifactCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author Plopman
*/
public final class AcademyRuins extends CardImpl {
public AcademyRuins(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
addSuperType(SuperType.LEGENDARY);
// {T}: Add {C}.
@@ -31,7 +30,7 @@ public final class AcademyRuins extends CardImpl {
// {1}{U}, {T}: Put target artifact card from your graveyard on top of your library.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibraryTargetEffect(true), new ManaCostsImpl("{1}{U}"));
ability.addCost(new TapSourceCost());
- ability.addTarget(new TargetCardInYourGraveyard(new FilterArtifactCard("artifact card from your graveyard")));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AccessDenied.java b/Mage.Sets/src/mage/cards/a/AccessDenied.java
new file mode 100644
index 00000000000..0776f2cd386
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AccessDenied.java
@@ -0,0 +1,65 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.permanent.token.ThopterColorlessToken;
+import mage.game.stack.StackObject;
+import mage.target.TargetSpell;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AccessDenied extends CardImpl {
+
+ public AccessDenied(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}");
+
+ // Counter target spell. Create X 1/1 colorless Thopter artifact creature tokens with flying, where X is that spell's mana value.
+ this.getSpellAbility().addEffect(new AccessDeniedEffect());
+ this.getSpellAbility().addTarget(new TargetSpell());
+ }
+
+ private AccessDenied(final AccessDenied card) {
+ super(card);
+ }
+
+ @Override
+ public AccessDenied copy() {
+ return new AccessDenied(this);
+ }
+}
+
+class AccessDeniedEffect extends OneShotEffect {
+
+ AccessDeniedEffect() {
+ super(Outcome.Benefit);
+ staticText = "counter target spell. Create X 1/1 colorless Thopter " +
+ "artifact creature tokens with flying, where X is that spell's mana value";
+ }
+
+ private AccessDeniedEffect(final AccessDeniedEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AccessDeniedEffect copy() {
+ return new AccessDeniedEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ StackObject stackObject = game.getStack().getStackObject(targetPointer.getFirst(game, source));
+ if (stackObject != null) {
+ game.getStack().counter(source.getFirstTarget(), source, game);
+ return new ThopterColorlessToken().putOntoBattlefield(stackObject.getManaValue(), game, source);
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AcclaimedContender.java b/Mage.Sets/src/mage/cards/a/AcclaimedContender.java
index 9ffedd21655..51003c288d8 100644
--- a/Mage.Sets/src/mage/cards/a/AcclaimedContender.java
+++ b/Mage.Sets/src/mage/cards/a/AcclaimedContender.java
@@ -5,14 +5,13 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
@@ -56,9 +55,8 @@ public final class AcclaimedContender extends CardImpl {
// When Acclaimed Contender enters the battlefield, if you control another Knight, look at the top five cards of your library. You may reveal a Knight, Aura, Equipment, or legendary artifact card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
- StaticValue.get(5), false, StaticValue.get(1), filter2, Zone.LIBRARY, false,
- true, false, Zone.HAND, true, false, false
- ).setBackInRandomOrder(true)), condition, "When {this} enters the battlefield, " +
+ 5, 1, filter2, PutCards.HAND, PutCards.BOTTOM_RANDOM
+ )), condition, "When {this} enters the battlefield, " +
"if you control another Knight, look at the top five cards of your library. " +
"You may reveal a Knight, Aura, Equipment, or legendary artifact card from among them " +
"and put it into your hand. Put the rest on the bottom of your library in a random order."
diff --git a/Mage.Sets/src/mage/cards/a/AccursedWitch.java b/Mage.Sets/src/mage/cards/a/AccursedWitch.java
index bf88d81b5e9..a6ad8937615 100644
--- a/Mage.Sets/src/mage/cards/a/AccursedWitch.java
+++ b/Mage.Sets/src/mage/cards/a/AccursedWitch.java
@@ -84,8 +84,7 @@ class AccursedWitchReturnTransformedEffect extends OneShotEffect {
}
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
- UUID secondFaceId = card.getSecondCardFace().getId();
- game.getState().setValue("attachTo:" + secondFaceId, attachTo.getId());
+ game.getState().setValue("attachTo:" + source.getSourceId(), attachTo.getId());
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
attachTo.addAttachment(card.getId(), source, game);
}
diff --git a/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java b/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java
index 6ea9dee4c1e..19f34cfbf69 100644
--- a/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java
+++ b/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java
@@ -103,7 +103,7 @@ class AcererakTheArchlichEffect extends OneShotEffect {
}
TargetPermanent target = new TargetControlledCreaturePermanent(0, 1);
target.setNotTarget(true);
- player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
+ player.choose(Outcome.Sacrifice, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null && permanent.sacrifice(source, game)) {
tokens--;
diff --git a/Mage.Sets/src/mage/cards/a/AchHansRun.java b/Mage.Sets/src/mage/cards/a/AchHansRun.java
index 619615a29a3..e8b9c2e6ec0 100644
--- a/Mage.Sets/src/mage/cards/a/AchHansRun.java
+++ b/Mage.Sets/src/mage/cards/a/AchHansRun.java
@@ -78,7 +78,7 @@ class AchHansRunEffect extends OneShotEffect {
if (!controller.searchLibrary(target, source, game)) {
return false;
}
- Card card = controller.getLibrary().remove(target.getFirstTarget(), game);
+ Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
if (card == null || !controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/a/AcidSpewerDragon.java b/Mage.Sets/src/mage/cards/a/AcidSpewerDragon.java
index 81047f0d9ed..e7c3488df2b 100644
--- a/Mage.Sets/src/mage/cards/a/AcidSpewerDragon.java
+++ b/Mage.Sets/src/mage/cards/a/AcidSpewerDragon.java
@@ -43,7 +43,7 @@ public final class AcidSpewerDragon extends CardImpl {
this.addAbility(DeathtouchAbility.getInstance());
// Megamorph {5}{B}{B}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{B}{B}"), true));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{5}{B}{B}"), true));
// When Acid-Spewer Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false));
diff --git a/Mage.Sets/src/mage/cards/a/AcidicSliver.java b/Mage.Sets/src/mage/cards/a/AcidicSliver.java
index 12826a9efd1..b808edb913f 100644
--- a/Mage.Sets/src/mage/cards/a/AcidicSliver.java
+++ b/Mage.Sets/src/mage/cards/a/AcidicSliver.java
@@ -38,7 +38,7 @@ public final class AcidicSliver extends CardImpl {
ability.addTarget(new TargetAnyTarget());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityAllEffect(ability,
- Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS,
+ Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS,
"All Slivers have \"{2}, Sacrifice this permanent: This permanent deals 2 damage to any target.\"")));
}
diff --git a/Mage.Sets/src/mage/cards/a/AcidicSoil.java b/Mage.Sets/src/mage/cards/a/AcidicSoil.java
index ea0ac39142d..be950588e28 100644
--- a/Mage.Sets/src/mage/cards/a/AcidicSoil.java
+++ b/Mage.Sets/src/mage/cards/a/AcidicSoil.java
@@ -50,7 +50,7 @@ class AcidicSoilEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- List permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source.getSourceId(), game);
+ List permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source, game);
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
diff --git a/Mage.Sets/src/mage/cards/a/AcolyteOfAffliction.java b/Mage.Sets/src/mage/cards/a/AcolyteOfAffliction.java
index 58791c6deb2..b206f0338b7 100644
--- a/Mage.Sets/src/mage/cards/a/AcolyteOfAffliction.java
+++ b/Mage.Sets/src/mage/cards/a/AcolyteOfAffliction.java
@@ -73,7 +73,7 @@ class AcolyteOfAfflictionEffect extends OneShotEffect {
}
player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.GRAVEYARD, source, game);
TargetCard target = new TargetCardInYourGraveyard(0, 1, filter, true);
- if (!player.choose(Outcome.ReturnToHand, target, source.getSourceId(), game)) {
+ if (!player.choose(Outcome.ReturnToHand, target, source, game)) {
return true;
}
Card card = game.getCard(target.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/a/AcquisitionOctopus.java b/Mage.Sets/src/mage/cards/a/AcquisitionOctopus.java
index e49d61f6490..1d55d604dd8 100644
--- a/Mage.Sets/src/mage/cards/a/AcquisitionOctopus.java
+++ b/Mage.Sets/src/mage/cards/a/AcquisitionOctopus.java
@@ -80,6 +80,6 @@ class AcquisitionOctopusTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "When {this} or equipped creature deals combat damage to a player, draw a card.";
+ return "Whenever {this} or equipped creature deals combat damage to a player, draw a card.";
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java b/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java
index 15313ce5fd1..c505455aa14 100644
--- a/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java
+++ b/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java
@@ -22,10 +22,10 @@ public final class AcrobaticManeuver extends CardImpl {
// Exile target creature you control, then return that card to the battlefield under its owner's control.
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addEffect(new ExileTargetForSourceEffect());
- this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false));
+ this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(","));
// Draw a card.
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
"));
}
private AcrobaticManeuver(final AcrobaticManeuver card) {
diff --git a/Mage.Sets/src/mage/cards/a/ActOfAuthority.java b/Mage.Sets/src/mage/cards/a/ActOfAuthority.java
index 0001376bc54..d288540ba90 100644
--- a/Mage.Sets/src/mage/cards/a/ActOfAuthority.java
+++ b/Mage.Sets/src/mage/cards/a/ActOfAuthority.java
@@ -54,7 +54,7 @@ class ActOfAuthorityEffect extends OneShotEffect {
this.staticText = "you may exile target artifact or enchantment. If you do, its controller gains control of {this}";
}
- public ActOfAuthorityEffect(final ActOfAuthorityEffect effect) {
+ private ActOfAuthorityEffect(final ActOfAuthorityEffect effect) {
super(effect);
}
@@ -66,29 +66,32 @@ class ActOfAuthorityEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
- if (targetPermanent != null && new ExileTargetEffect().apply(game, source)) {
- Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
- if (sourcePermanent != null) {
- ContinuousEffect effect = new ActOfAuthorityGainControlEffect(Duration.Custom, targetPermanent.getControllerId());
- effect.setTargetPointer(new FixedTarget(sourcePermanent, game));
- game.addEffect(effect, source);
- }
- return true;
- }
- return false;
+ if (targetPermanent == null) { return false; }
+
+ ExileTargetEffect exileTargetEffect = new ExileTargetEffect();
+ if (!exileTargetEffect.apply(game, source)) { return false; }
+
+ Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
+ if (sourcePermanent == null) { return true; }
+
+ ContinuousEffect effect = new ActOfAuthorityGainControlEffect(Duration.Custom, targetPermanent.getControllerId());
+ effect.setTargetPointer(new FixedTarget(sourcePermanent, game));
+ game.addEffect(effect, source);
+ return true;
}
}
+// TODO: These and it's duplicates can probably be replaced by a gain control of effect
class ActOfAuthorityGainControlEffect extends ContinuousEffectImpl {
- UUID controller;
+ private final UUID controller;
public ActOfAuthorityGainControlEffect(Duration duration, UUID controller) {
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.controller = controller;
}
- public ActOfAuthorityGainControlEffect(final ActOfAuthorityGainControlEffect effect) {
+ private ActOfAuthorityGainControlEffect(final ActOfAuthorityGainControlEffect effect) {
super(effect);
this.controller = effect.controller;
}
@@ -100,14 +103,16 @@ class ActOfAuthorityGainControlEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
- Permanent permanent = game.getPermanent(source.getFirstTarget());
- if (targetPointer != null) {
+ Permanent permanent;
+ if (targetPointer == null) {
+ permanent = game.getPermanent(source.getFirstTarget());
+ } else {
permanent = game.getPermanent(targetPointer.getFirst(game, source));
}
- if (permanent != null) {
- return permanent.changeControllerId(controller, game, source);
- }
- return false;
+
+ if (permanent == null) { return false; }
+
+ return permanent.changeControllerId(controller, game, source);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/ActiveVolcano.java b/Mage.Sets/src/mage/cards/a/ActiveVolcano.java
index fe765fcf52a..2bfe9897f98 100644
--- a/Mage.Sets/src/mage/cards/a/ActiveVolcano.java
+++ b/Mage.Sets/src/mage/cards/a/ActiveVolcano.java
@@ -36,8 +36,7 @@ public final class ActiveVolcano extends CardImpl {
this.getSpellAbility().addTarget(new TargetPermanent(filterBlue));
// or return target Island to its owner's hand.
- Mode mode = new Mode();
- mode.addEffect(new ReturnToHandTargetEffect());
+ Mode mode = new Mode(new ReturnToHandTargetEffect());
mode.addTarget(new TargetPermanent(filterIsland));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AdarkarValkyrie.java b/Mage.Sets/src/mage/cards/a/AdarkarValkyrie.java
index beded6f827f..b7efc2fde8a 100644
--- a/Mage.Sets/src/mage/cards/a/AdarkarValkyrie.java
+++ b/Mage.Sets/src/mage/cards/a/AdarkarValkyrie.java
@@ -84,18 +84,17 @@ class AdarkarValkyrieEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
- if (permanent != null) {
- DelayedTriggeredAbility delayedAbility = new AdarkarValkyrieDelayedTriggeredAbility(new MageObjectReference(permanent, game));
- game.addDelayedTriggeredAbility(delayedAbility, source);
- return true;
- }
- return false;
+ if (permanent == null) { return false; }
+
+ DelayedTriggeredAbility delayedAbility = new AdarkarValkyrieDelayedTriggeredAbility(new MageObjectReference(permanent, game));
+ game.addDelayedTriggeredAbility(delayedAbility, source);
+ return true;
}
}
class AdarkarValkyrieDelayedTriggeredAbility extends DelayedTriggeredAbility {
- protected MageObjectReference mor;
+ private final MageObjectReference mor;
public AdarkarValkyrieDelayedTriggeredAbility(MageObjectReference mor) {
super(new ReturnToBattlefieldUnderYourControlTargetEffect(), Duration.EndOfTurn);
@@ -119,14 +118,17 @@ class AdarkarValkyrieDelayedTriggeredAbility extends DelayedTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- if (((ZoneChangeEvent) event).isDiesEvent()
- && mor.refersTo(((ZoneChangeEvent) event).getTarget(), game)
- && game.getState().getZone(event.getTargetId()) == Zone.GRAVEYARD) { // must be in the graveyard
- getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game));
- return true;
+ if (!((ZoneChangeEvent) event).isDiesEvent()) { return false; }
- }
- return false;
+ if (!mor.refersTo(((ZoneChangeEvent) event).getTarget(), game)) { return false; }
+
+ // TODO: Must it? Why?
+ // Must be in the graveyard
+ if (game.getState().getZone(event.getTargetId()) != Zone.GRAVEYARD) { return false; }
+
+ getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game));
+
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java
index f2f120e6945..0cc9aac12e7 100644
--- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java
+++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java
@@ -91,7 +91,7 @@ class DamagedByPiratesWatcher extends Watcher {
}
public boolean damagedByEnoughPirates(UUID sourceId) {
- return damageSourceIds.keySet().contains(sourceId) && damageSourceIds.get(sourceId).size() > 2;
+ return damageSourceIds.containsKey(sourceId) && damageSourceIds.get(sourceId).size() > 2;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AdunOakenshield.java b/Mage.Sets/src/mage/cards/a/AdunOakenshield.java
index a50becf6298..e3ebbb16dec 100644
--- a/Mage.Sets/src/mage/cards/a/AdunOakenshield.java
+++ b/Mage.Sets/src/mage/cards/a/AdunOakenshield.java
@@ -1,24 +1,22 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author shieldal
*/
public final class AdunOakenshield extends CardImpl {
@@ -33,7 +31,7 @@ public final class AdunOakenshield extends CardImpl {
this.toughness = new MageInt(2);
//{B}{R}{G}, {T}: Return target creature card from your graveyard to your hand.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{B}{R}{G}"));
+ Ability ability = new SimpleActivatedAbility(new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{B}{R}{G}"));
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AdventureAwaits.java b/Mage.Sets/src/mage/cards/a/AdventureAwaits.java
index ec7fc5b76c9..52d331b8222 100644
--- a/Mage.Sets/src/mage/cards/a/AdventureAwaits.java
+++ b/Mage.Sets/src/mage/cards/a/AdventureAwaits.java
@@ -1,16 +1,14 @@
package mage.cards.a;
import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.Mode;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.*;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
-import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
@@ -22,7 +20,8 @@ public final class AdventureAwaits extends CardImpl {
public AdventureAwaits(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
- // Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. If you don't put a card into your hand this way, draw a card.
+ // Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in a random order. If you don't put a card into your hand this way, draw a card.
this.getSpellAbility().addEffect(new AdventureAwaitsEffect());
}
@@ -36,14 +35,10 @@ public final class AdventureAwaits extends CardImpl {
}
}
-class AdventureAwaitsEffect extends OneShotEffect {
+class AdventureAwaitsEffect extends LookLibraryAndPickControllerEffect {
AdventureAwaitsEffect() {
- super(Outcome.Benefit);
- staticText = "Look at the top five cards of your library. " +
- "You may reveal a creature card from among them and put it into your hand. " +
- "Put the rest on the bottom of your library in a random order. " +
- "If you didn't put a card into your hand this way, draw a card.";
+ super(5, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM);
}
private AdventureAwaitsEffect(final AdventureAwaitsEffect effect) {
@@ -56,25 +51,16 @@ class AdventureAwaitsEffect extends OneShotEffect {
}
@Override
- public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
- if (player == null) {
- return false;
- }
- Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 5));
- TargetCard target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_CREATURE);
- player.choose(outcome, cards, target, game);
- Card card = game.getCard(target.getFirstTarget());
- if (card != null && player.chooseUse(outcome, "Put " + card.getName() + " into your hand?",
- "Otherwise draw a card", "Put into hand", "Draw a card", source, game
- )) {
- player.moveCards(card, Zone.HAND, source, game);
- cards.remove(card);
- player.putCardsOnBottomOfLibrary(cards, game, source, false);
- } else {
- player.putCardsOnBottomOfLibrary(cards, game, source, false);
+ public boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) {
+ super.actionWithPickedCards(game, source, player, pickedCards, otherCards);
+ if (pickedCards.isEmpty()) {
player.drawCards(1, source, game);
}
return true;
}
+
+ @Override
+ public String getText(Mode mode) {
+ return super.getText(mode).concat(". If you didn't put a card into your hand this way, draw a card");
+ }
}
diff --git a/Mage.Sets/src/mage/cards/a/AdventurousImpulse.java b/Mage.Sets/src/mage/cards/a/AdventurousImpulse.java
index afcafa4f6f3..4b447bd211e 100644
--- a/Mage.Sets/src/mage/cards/a/AdventurousImpulse.java
+++ b/Mage.Sets/src/mage/cards/a/AdventurousImpulse.java
@@ -1,14 +1,12 @@
-
package mage.cards.a;
import java.util.UUID;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.FilterCard;
-import mage.filter.predicate.Predicates;
+import mage.filter.StaticFilters;
/**
*
@@ -16,18 +14,14 @@ import mage.filter.predicate.Predicates;
*/
public final class AdventurousImpulse extends CardImpl {
- private static final FilterCard filter = new FilterCard("a creature or land card");
-
- static {
- filter.add(Predicates.or(CardType.CREATURE.getPredicate(), CardType.LAND.getPredicate()));
- }
-
public AdventurousImpulse(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{G}");
- //Look at the top three cards of your library. You may reveal a creature or land card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(StaticValue.get(3), false, StaticValue.get(1), filter, false));
-
+ // Look at the top three cards of your library.
+ // You may reveal a creature or land card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in any order.
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
+ 3, 1, StaticFilters.FILTER_CARD_CREATURE_OR_LAND, PutCards.HAND, PutCards.BOTTOM_ANY));
}
private AdventurousImpulse(final AdventurousImpulse card) {
diff --git a/Mage.Sets/src/mage/cards/a/AdviceFromTheFae.java b/Mage.Sets/src/mage/cards/a/AdviceFromTheFae.java
index d998ff65bd6..a4cd6e707c4 100644
--- a/Mage.Sets/src/mage/cards/a/AdviceFromTheFae.java
+++ b/Mage.Sets/src/mage/cards/a/AdviceFromTheFae.java
@@ -1,37 +1,36 @@
-
package mage.cards.a;
-import java.util.Objects;
-import java.util.Set;
import java.util.UUID;
-import mage.MageObject;
import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
-import mage.cards.*;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.predicate.permanent.ControllerIdPredicate;
+import mage.filter.StaticFilters;
import mage.game.Game;
-import mage.players.Player;
-import mage.target.TargetCard;
/**
*
- * @author jeffwadsworth
+ * @author awjackson
*/
public final class AdviceFromTheFae extends CardImpl {
public AdviceFromTheFae(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2/U}{2/U}{2/U}");
- // ({2U} can be paid with any two mana or with {U}. This card's converted mana cost is 6.)
- // Look at the top five cards of your library. If you control more creatures than each other player, put two of those cards into your hand. Otherwise, put one of them into your hand. Then put the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new AdviceFromTheFaeEffect());
-
+ // Look at the top five cards of your library. If you control more creatures than each other player,
+ // put two of those cards into your hand. Otherwise, put one of them into your hand.
+ // Then put the rest on the bottom of your library in any order.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new LookLibraryAndPickControllerEffect(5, 2, PutCards.HAND, PutCards.BOTTOM_ANY),
+ new LookLibraryAndPickControllerEffect(5, 1, PutCards.HAND, PutCards.BOTTOM_ANY),
+ AdviceFromTheFaeCondition.instance, "Look at the top five cards of your library. " +
+ "If you control more creatures than each other player, put two of those cards into your hand. " +
+ "Otherwise, put one of them into your hand. Then put the rest on the bottom of your library in any order."
+ ));
}
private AdviceFromTheFae(final AdviceFromTheFae card) {
@@ -44,52 +43,23 @@ public final class AdviceFromTheFae extends CardImpl {
}
}
-class AdviceFromTheFaeEffect extends OneShotEffect {
-
- public AdviceFromTheFaeEffect() {
- super(Outcome.DrawCard);
- this.staticText = "Look at the top five cards of your library. If you control more creatures than each other player, put two of those cards into your hand. Otherwise, put one of them into your hand. Then put the rest on the bottom of your library in any order";
- }
-
- public AdviceFromTheFaeEffect(final AdviceFromTheFaeEffect effect) {
- super(effect);
- }
-
- @Override
- public AdviceFromTheFaeEffect copy() {
- return new AdviceFromTheFaeEffect(this);
- }
+enum AdviceFromTheFaeCondition implements Condition {
+ instance;
@Override
public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- MageObject mageObject = game.getObject(source.getSourceId());
- if (controller != null && mageObject != null) {
- Set topCards = controller.getLibrary().getTopCards(game, 5);
- Cards cardsFromLibrary = new CardsImpl();
- for (Card card : topCards) {
- cardsFromLibrary.add(card);
+ int max = 0;
+ UUID controllerId = source.getControllerId();
+ for (UUID playerId : game.getState().getPlayersInRange(controllerId, game)) {
+ if (!playerId.equals(controllerId)) {
+ max = Math.max(max, game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game));
}
- controller.lookAtCards(mageObject.getIdName(), cardsFromLibrary, game);
- int max = 0;
- for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
- FilterCreaturePermanent filter = new FilterCreaturePermanent();
- filter.add(new ControllerIdPredicate(playerId));
- if (!Objects.equals(playerId, controller.getId())) {
- if (max < game.getBattlefield().countAll(filter, playerId, game)) {
- max = game.getBattlefield().countAll(filter, playerId, game);
- }
- }
- }
- boolean moreCreatures = game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), controller.getId(), game) > max;
- TargetCard target = new TargetCard(moreCreatures ? 2 : 1, Zone.LIBRARY, new FilterCard());
- if (controller.choose(Outcome.DrawCard, cardsFromLibrary, target, game)) {
- cardsFromLibrary.removeAll(target.getTargets());
- controller.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
- }
- controller.putCardsOnBottomOfLibrary(cardsFromLibrary, game, source, true);
- return true;
}
- return false;
+ return game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, controllerId, game) > max;
+ }
+
+ @Override
+ public String toString() {
+ return "you control more creatures than each other player";
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AerialModification.java b/Mage.Sets/src/mage/cards/a/AerialModification.java
index f31af209783..83aacbb8bf2 100644
--- a/Mage.Sets/src/mage/cards/a/AerialModification.java
+++ b/Mage.Sets/src/mage/cards/a/AerialModification.java
@@ -24,7 +24,7 @@ import mage.target.TargetPermanent;
*/
public final class AerialModification extends CardImpl {
- private static final FilterPermanent filter = new FilterPermanent("creature or vehicle");
+ private static final FilterPermanent filter = new FilterPermanent("creature or Vehicle");
static {
filter.add(Predicates.or(CardType.CREATURE.getPredicate(),
diff --git a/Mage.Sets/src/mage/cards/a/AerialSurveyor.java b/Mage.Sets/src/mage/cards/a/AerialSurveyor.java
new file mode 100644
index 00000000000..b96d633b7e6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AerialSurveyor.java
@@ -0,0 +1,115 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.common.LandsYouControlHint;
+import mage.abilities.keyword.CrewAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterBasicLandCard;
+import mage.filter.common.FilterLandPermanent;
+import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
+import mage.game.Controllable;
+import mage.game.Game;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class AerialSurveyor extends CardImpl {
+
+ private static final FilterCard filter = new FilterBasicLandCard(SubType.PLAINS);
+
+ public AerialSurveyor(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{W}");
+
+ this.subtype.add(SubType.VEHICLE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Aerial Surveyor attacks, if defending player controls more lands than you, search your library for a basic Plains card, put it onto the battlefield tapped, then shuffle.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new AttacksTriggeredAbility(
+ new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true)
+ ), AerialSurveyorCondition.instance, "Whenever {this} attacks, if defending player " +
+ "controls more lands than you, search your library for a basic Plains card, " +
+ "put it onto the battlefield tapped, then shuffle."
+ ).addHint(LandsYouControlHint.instance).addHint(AerialSurveyorHint.instance));
+
+ // Crew 2
+ this.addAbility(new CrewAbility(2));
+ }
+
+ private AerialSurveyor(final AerialSurveyor card) {
+ super(card);
+ }
+
+ @Override
+ public AerialSurveyor copy() {
+ return new AerialSurveyor(this);
+ }
+}
+
+enum AerialSurveyorCondition implements Condition {
+ instance;
+ private static final FilterPermanent filter = new FilterLandPermanent();
+
+ static {
+ filter.add(DefendingPlayerControlsPredicate.instance);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return game.getBattlefield().count(
+ filter, source.getControllerId(), source, game
+ ) > game.getBattlefield().count(
+ StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
+ source.getControllerId(), source, game
+ );
+ }
+}
+
+enum AerialSurveyorHint implements Hint {
+ instance;
+
+ @Override
+ public String getText(Game game, Ability ability) {
+ return game.getBattlefield()
+ .getActivePermanents(
+ StaticFilters.FILTER_LAND,
+ ability.getControllerId(),
+ ability, game
+ ).stream()
+ .map(Controllable::getControllerId)
+ .filter(game.getOpponents(ability.getControllerId())::contains)
+ .collect(Collectors.toMap(Function.identity(), u -> 1, Integer::sum))
+ .entrySet()
+ .stream()
+ .filter(entry -> game.getPlayer(entry.getKey()) != null)
+ .map(entry -> "Lands " + game.getPlayer(entry.getKey()).getName() + " controls: " + entry.getValue())
+ .collect(Collectors.joining("
"));
+ }
+
+ @Override
+ public AerialSurveyorHint copy() {
+ return instance;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AerieBowmasters.java b/Mage.Sets/src/mage/cards/a/AerieBowmasters.java
index f6bbbf1e108..e84f91122d2 100644
--- a/Mage.Sets/src/mage/cards/a/AerieBowmasters.java
+++ b/Mage.Sets/src/mage/cards/a/AerieBowmasters.java
@@ -28,7 +28,7 @@ public final class AerieBowmasters extends CardImpl {
this.addAbility(ReachAbility.getInstance());
// Megamorph {5}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.))
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{G}"), true));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{5}{G}"), true));
}
diff --git a/Mage.Sets/src/mage/cards/a/AetherChaser.java b/Mage.Sets/src/mage/cards/a/AetherChaser.java
index b6fa2065f94..7e13cf0556a 100644
--- a/Mage.Sets/src/mage/cards/a/AetherChaser.java
+++ b/Mage.Sets/src/mage/cards/a/AetherChaser.java
@@ -36,8 +36,7 @@ public final class AetherChaser extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(2)));
// Whenever Aether Chaser attacks, you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token.
- this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2)), false,
- "Whenever {this} attacks you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token."));
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2))));
}
private AetherChaser(final AetherChaser card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherFigment.java b/Mage.Sets/src/mage/cards/a/AetherFigment.java
index 90847b3dc68..3a3258f5709 100644
--- a/Mage.Sets/src/mage/cards/a/AetherFigment.java
+++ b/Mage.Sets/src/mage/cards/a/AetherFigment.java
@@ -37,7 +37,7 @@ public final class AetherFigment extends CardImpl {
Ability ability = new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)),
KickedCondition.instance,
- "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it",
+ "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it.",
"");
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AetherGust.java b/Mage.Sets/src/mage/cards/a/AetherGust.java
index dbff727bf7a..438586ef456 100644
--- a/Mage.Sets/src/mage/cards/a/AetherGust.java
+++ b/Mage.Sets/src/mage/cards/a/AetherGust.java
@@ -1,19 +1,15 @@
package mage.cards.a;
+import mage.MageObject;
import mage.ObjectColor;
-import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.PutOnLibraryTargetEffect;
+import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.filter.common.FilterSpellOrPermanent;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
-import mage.game.Game;
-import mage.players.Player;
import mage.target.common.TargetSpellOrPermanent;
import java.util.UUID;
@@ -25,7 +21,7 @@ public final class AetherGust extends CardImpl {
private static final FilterSpellOrPermanent filter
= new FilterSpellOrPermanent("spell or permanent that's red or green");
- private static final Predicate predicate = Predicates.or(
+ private static final Predicate predicate = Predicates.or(
new ColorPredicate(ObjectColor.RED),
new ColorPredicate(ObjectColor.GREEN)
);
@@ -39,8 +35,11 @@ public final class AetherGust extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Choose target spell or permanent that's red or green. Its owner puts it on the top or bottom of their library.
- this.getSpellAbility().addEffect(new AetherGustEffect());
- this.getSpellAbility().addTarget(new TargetSpellOrPermanent(1, 1, filter, false));
+ this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect(
+ "choose target spell or permanent that's red or green. " +
+ "Its owner puts it on the top or bottom of their library"
+ ));
+ this.getSpellAbility().addTarget(new TargetSpellOrPermanent(filter));
}
private AetherGust(final AetherGust card) {
@@ -52,34 +51,3 @@ public final class AetherGust extends CardImpl {
return new AetherGust(this);
}
}
-
-class AetherGustEffect extends OneShotEffect {
-
- AetherGustEffect() {
- super(Outcome.Removal);
- staticText = "Choose target spell or permanent that's red or green. " +
- "Its owner puts it on the top or bottom of their library.";
- }
-
- private AetherGustEffect(final AetherGustEffect effect) {
- super(effect);
- }
-
- @Override
- public AetherGustEffect copy() {
- return new AetherGustEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
- if (player == null) {
- return false;
- }
- if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
- "", "Top", "Bottom", source, game)) {
- return new PutOnLibraryTargetEffect(true).apply(game, source);
- }
- return new PutOnLibraryTargetEffect(false).apply(game, source);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/AetherHerder.java b/Mage.Sets/src/mage/cards/a/AetherHerder.java
index dfb7b51e861..63653549124 100644
--- a/Mage.Sets/src/mage/cards/a/AetherHerder.java
+++ b/Mage.Sets/src/mage/cards/a/AetherHerder.java
@@ -34,8 +34,7 @@ public final class AetherHerder extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(2)));
// Whenever Aether Herder attacks, you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token.
- this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2)), false,
- "Whenever {this} attacks you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token."));
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2))));
}
private AetherHerder(final AetherHerder card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherInspector.java b/Mage.Sets/src/mage/cards/a/AetherInspector.java
index 6ba31ee9731..6ea57c07011 100644
--- a/Mage.Sets/src/mage/cards/a/AetherInspector.java
+++ b/Mage.Sets/src/mage/cards/a/AetherInspector.java
@@ -36,8 +36,7 @@ public final class AetherInspector extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(2)));
// Whenever Aether Inspector attacks, you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token.
- this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2)), false,
- "Whenever {this} attacks you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token."));
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2))));
}
private AetherInspector(final AetherInspector card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherMembrane.java b/Mage.Sets/src/mage/cards/a/AetherMembrane.java
index ed335085ff1..0e856ced535 100644
--- a/Mage.Sets/src/mage/cards/a/AetherMembrane.java
+++ b/Mage.Sets/src/mage/cards/a/AetherMembrane.java
@@ -3,9 +3,8 @@ package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
-import mage.abilities.common.BlocksSourceTriggeredAbility;
+import mage.abilities.common.BlocksCreatureTriggeredAbility;
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.keyword.DefenderAbility;
@@ -34,9 +33,11 @@ public final class AetherMembrane extends CardImpl {
this.addAbility(ReachAbility.getInstance());
// Whenever Aether Membrane blocks a creature, return that creature to its owner's hand at end of combat.
- Effect effect = new ReturnToHandTargetEffect();
- effect.setText("return that creature to its owner's hand at end of combat");
- this.addAbility(new BlocksSourceTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(effect)), false, true));
+ this.addAbility(new BlocksCreatureTriggeredAbility(
+ new CreateDelayedTriggeredAbilityEffect(
+ new AtTheEndOfCombatDelayedTriggeredAbility(new ReturnToHandTargetEffect())
+ ).setText("return that creature to its owner's hand at end of combat")
+ ));
}
private AetherMembrane(final AetherMembrane card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherShockwave.java b/Mage.Sets/src/mage/cards/a/AetherShockwave.java
index 6ef5a01f7e9..d8e233994cd 100644
--- a/Mage.Sets/src/mage/cards/a/AetherShockwave.java
+++ b/Mage.Sets/src/mage/cards/a/AetherShockwave.java
@@ -31,8 +31,7 @@ public final class AetherShockwave extends CardImpl {
// Choose one - Tap all Spirits; or tap all non-Spirit creatures.
this.getSpellAbility().addEffect(new TapAllEffect(filterSpirit));
- Mode mode = new Mode();
- mode.addEffect(new TapAllEffect(filterNonSpirit));
+ Mode mode = new Mode(new TapAllEffect(filterNonSpirit));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AetherSwooper.java b/Mage.Sets/src/mage/cards/a/AetherSwooper.java
index ad7cf1aab47..5aa40c707dd 100644
--- a/Mage.Sets/src/mage/cards/a/AetherSwooper.java
+++ b/Mage.Sets/src/mage/cards/a/AetherSwooper.java
@@ -37,8 +37,7 @@ public final class AetherSwooper extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(2)));
// Whenever Aether Swooper attacks, you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token.
- this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2)), false,
- "Whenever {this} attacks you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token."));
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2))));
}
private AetherSwooper(final AetherSwooper card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherVial.java b/Mage.Sets/src/mage/cards/a/AetherVial.java
index b5a9f24d614..10866abda9a 100644
--- a/Mage.Sets/src/mage/cards/a/AetherVial.java
+++ b/Mage.Sets/src/mage/cards/a/AetherVial.java
@@ -90,7 +90,7 @@ class AetherVialEffect extends OneShotEffect {
}
TargetCardInHand target = new TargetCardInHand(filter);
- if (controller.choose(this.outcome, target, source.getSourceId(), game)) {
+ if (controller.choose(this.outcome, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
return controller.moveCards(card, Zone.BATTLEFIELD, source, game);
diff --git a/Mage.Sets/src/mage/cards/a/AetherWeb.java b/Mage.Sets/src/mage/cards/a/AetherWeb.java
index ab7aef23932..e635c846f5f 100644
--- a/Mage.Sets/src/mage/cards/a/AetherWeb.java
+++ b/Mage.Sets/src/mage/cards/a/AetherWeb.java
@@ -1,34 +1,32 @@
package mage.cards.a;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.FlashAbility;
+import mage.abilities.keyword.ReachAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
import java.util.UUID;
-import mage.abilities.StaticAbility;
-import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.AsThoughEffectImpl;
-import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
-import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
-import mage.abilities.keyword.ReachAbility;
-import mage.constants.*;
-import mage.abilities.keyword.FlashAbility;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.target.common.TargetCreaturePermanent;
-import mage.abilities.Ability;
-import mage.abilities.effects.common.AttachEffect;
-import mage.target.TargetPermanent;
-import mage.abilities.keyword.EnchantAbility;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-
/**
- *
* @author noahg
*/
public final class AetherWeb extends CardImpl {
public AetherWeb(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
-
+
this.subtype.add(SubType.AURA);
// Flash
@@ -38,15 +36,15 @@ public final class AetherWeb extends CardImpl {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// Enchanted creature gets +1/+1, has reach, and can block creatures with shadow as though they didn't have shadow.
- StaticAbility staticAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1)
- .setText("Enchanted creature gets +1/+1, has reach, and can block creatures with shadow as though they didn't have shadow."));
- staticAbility.addEffect(new GainAbilityAttachedEffect(ReachAbility.getInstance(), AttachmentType.AURA).setText(""));
- staticAbility.addEffect(new AetherWebEffect());
- this.addAbility(staticAbility);
+ Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(1, 1));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ ReachAbility.getInstance(), AttachmentType.AURA
+ ).setText(", has reach"));
+ ability.addEffect(new AetherWebEffect());
+ this.addAbility(ability);
}
private AetherWeb(final AetherWeb card) {
@@ -63,7 +61,7 @@ class AetherWebEffect extends AsThoughEffectImpl {
public AetherWebEffect() {
super(AsThoughEffectType.BLOCK_SHADOW, Duration.WhileOnBattlefield, Outcome.Benefit);
- staticText = "";
+ staticText = ", and can block creatures with shadow as though they didn't have shadow";
}
public AetherWebEffect(final AetherWebEffect effect) {
@@ -85,4 +83,4 @@ class AetherWebEffect extends AsThoughEffectImpl {
Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
return sourcePermanent != null && sourceId.equals(sourcePermanent.getAttachedTo());
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/a/AetherbornMarauder.java b/Mage.Sets/src/mage/cards/a/AetherbornMarauder.java
index b2925e58532..6f252704e5e 100644
--- a/Mage.Sets/src/mage/cards/a/AetherbornMarauder.java
+++ b/Mage.Sets/src/mage/cards/a/AetherbornMarauder.java
@@ -78,12 +78,12 @@ class AetherbornMarauderEffect extends OneShotEffect {
filter.add(AnotherPredicate.instance);
filter.add(CounterType.P1P1.getPredicate());
boolean firstRun = true;
- while (game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
+ while (game.getBattlefield().count(filter, source.getControllerId(), source, game) > 0) {
if (controller.chooseUse(outcome, "Move " + (firstRun ? "any" : "more") + " +1/+1 counters from other permanents you control to " + sourceObject.getLogName() + '?', source, game)) {
firstRun = false;
TargetControlledPermanent target = new TargetControlledPermanent(filter);
target.setNotTarget(true);
- if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) {
+ if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), source, game)) {
Permanent fromPermanent = game.getPermanent(target.getFirstTarget());
if (fromPermanent != null) {
int numberOfCounters = fromPermanent.getCounters(game).getCount(CounterType.P1P1);
diff --git a/Mage.Sets/src/mage/cards/a/AetherflameWall.java b/Mage.Sets/src/mage/cards/a/AetherflameWall.java
index d9ab65b70cd..8ae22cb4824 100644
--- a/Mage.Sets/src/mage/cards/a/AetherflameWall.java
+++ b/Mage.Sets/src/mage/cards/a/AetherflameWall.java
@@ -12,19 +12,17 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
import java.util.UUID;
/**
- *
* @author noahg
*/
public final class AetherflameWall extends CardImpl {
public AetherflameWall(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
-
+
this.subtype.add(SubType.WALL);
this.power = new MageInt(0);
this.toughness = new MageInt(4);
@@ -33,10 +31,13 @@ public final class AetherflameWall extends CardImpl {
this.addAbility(DefenderAbility.getInstance());
// Aetherflame Wall can block creatures with shadow as though they didn’t have shadow.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAsThoughtItHadShadowEffect(Duration.WhileOnBattlefield)));
+ this.addAbility(new SimpleStaticAbility(new CanBlockAsThoughtItHadShadowEffect(Duration.WhileOnBattlefield)
+ .setText("{this} can block creatures with shadow as though they didn't have shadow")));
// {R}: Aetherflame Wall gets +1/+0 until end of turn.
- this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}")));
+ this.addAbility(new SimpleActivatedAbility(
+ new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{R}")
+ ));
}
private AetherflameWall(final AetherflameWall card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherfluxReservoir.java b/Mage.Sets/src/mage/cards/a/AetherfluxReservoir.java
index 4dc5ac6b8fd..99f02213fd2 100644
--- a/Mage.Sets/src/mage/cards/a/AetherfluxReservoir.java
+++ b/Mage.Sets/src/mage/cards/a/AetherfluxReservoir.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
@@ -10,31 +8,30 @@ import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.GainLifeEffect;
-import mage.abilities.hint.ValueHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
import mage.game.Game;
import mage.target.common.TargetAnyTarget;
import mage.watchers.common.CastSpellLastTurnWatcher;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class AetherfluxReservoir extends CardImpl {
public AetherfluxReservoir(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// Whenever you cast a spell, you gain 1 life for each spell you've cast this turn.
- Ability abilityGainLife = new SpellCastControllerTriggeredAbility(new GainLifeEffect(new AetherfluxReservoirDynamicValue()), false);
- abilityGainLife.addHint(new ValueHint("You've cast spells this turn", new AetherfluxReservoirDynamicValue()));
- this.addAbility(abilityGainLife);
+ this.addAbility(new SpellCastControllerTriggeredAbility(new GainLifeEffect(
+ AetherfluxReservoirDynamicValue.instance, "you gain 1 life for each spell you've cast this turn"
+ ), false));
// Pay 50 life: Aetherflux Reservoir deals 50 damage to any target.
- Ability abilityPayLife = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(50), new PayLifeCost(50));
+ Ability abilityPayLife = new SimpleActivatedAbility(new DamageTargetEffect(50), new PayLifeCost(50));
abilityPayLife.addTarget(new TargetAnyTarget());
this.addAbility(abilityPayLife);
}
@@ -49,20 +46,20 @@ public final class AetherfluxReservoir extends CardImpl {
}
}
-class AetherfluxReservoirDynamicValue implements DynamicValue {
+enum AetherfluxReservoirDynamicValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
- CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class);
- if(watcher != null) {
- return watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(sourceAbility.getControllerId());
- }
- return 0;
+ return game
+ .getState()
+ .getWatcher(CastSpellLastTurnWatcher.class)
+ .getAmountOfSpellsPlayerCastOnCurrentTurn(sourceAbility.getControllerId());
}
@Override
public AetherfluxReservoirDynamicValue copy() {
- return new AetherfluxReservoirDynamicValue();
+ return this;
}
@Override
@@ -74,5 +71,4 @@ class AetherfluxReservoirDynamicValue implements DynamicValue {
public String getMessage() {
return "spell you've cast this turn";
}
-
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/Aetherling.java b/Mage.Sets/src/mage/cards/a/Aetherling.java
index 6e7020a9580..ff6d6b5f8a0 100644
--- a/Mage.Sets/src/mage/cards/a/Aetherling.java
+++ b/Mage.Sets/src/mage/cards/a/Aetherling.java
@@ -29,7 +29,7 @@ public final class Aetherling extends CardImpl {
this.toughness = new MageInt(5);
// {U}: Exile Aetherling. Return it to the battlefield under its owner's control at the beginning of the next end step.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true), new ManaCostsImpl("{U}")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(), new ManaCostsImpl("{U}")));
// {U}: Aetherling can't be blocked this turn
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{U}")));
// {1}: Aetherling gets +1/-1 until end of turn.
diff --git a/Mage.Sets/src/mage/cards/a/AethermagesTouch.java b/Mage.Sets/src/mage/cards/a/AethermagesTouch.java
index 027b033d4c0..ad47780bb23 100644
--- a/Mage.Sets/src/mage/cards/a/AethermagesTouch.java
+++ b/Mage.Sets/src/mage/cards/a/AethermagesTouch.java
@@ -60,7 +60,7 @@ class AethermagesTouchEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller != null && sourceObject != null) {
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));
if (!cards.isEmpty()) {
diff --git a/Mage.Sets/src/mage/cards/a/Aetherplasm.java b/Mage.Sets/src/mage/cards/a/Aetherplasm.java
index 9636bde5c7f..3e9f4592edd 100644
--- a/Mage.Sets/src/mage/cards/a/Aetherplasm.java
+++ b/Mage.Sets/src/mage/cards/a/Aetherplasm.java
@@ -3,7 +3,7 @@ package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
-import mage.abilities.common.BlocksSourceTriggeredAbility;
+import mage.abilities.common.BlocksCreatureTriggeredAbility;
import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid;
@@ -34,8 +34,11 @@ public final class Aetherplasm extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
- // Whenever Aetherplasm blocks a creature, you may return Aetherplasm to its owner's hand. If you do, you may put a creature card from your hand onto the battlefield blocking that creature.
- this.addAbility(new BlocksSourceTriggeredAbility(new DoIfCostPaid(new AetherplasmEffect(), new ReturnToHandFromBattlefieldSourceCost()), false, true));
+ // Whenever Aetherplasm blocks a creature, you may return Aetherplasm to its owner's hand.
+ // If you do, you may put a creature card from your hand onto the battlefield blocking that creature.
+ this.addAbility(new BlocksCreatureTriggeredAbility(new DoIfCostPaid(
+ new AetherplasmEffect(), new ReturnToHandFromBattlefieldSourceCost()
+ )));
}
private Aetherplasm(final Aetherplasm card) {
@@ -67,7 +70,7 @@ class AetherplasmEffect extends OneShotEffect {
}
if (player.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand onto the battlefield?", source, game)) {
TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A);
- if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
+ if (player.choose(Outcome.PutCardInPlay, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
Permanent blockedCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
diff --git a/Mage.Sets/src/mage/cards/a/Aetherspouts.java b/Mage.Sets/src/mage/cards/a/Aetherspouts.java
index 6d8a9d09412..1cb48164069 100644
--- a/Mage.Sets/src/mage/cards/a/Aetherspouts.java
+++ b/Mage.Sets/src/mage/cards/a/Aetherspouts.java
@@ -44,11 +44,13 @@ public final class Aetherspouts extends CardImpl {
/*
7/18/2014 The owner of each attacking creature chooses whether to put it on the top or bottom
- of their library. The active player (the player whose turn it is) makes all of
- their choices first, followed by each other player in turn order.
+ of their library.
+ The active player (the player whose turn it is) makes all of their choices first,
+ followed by each other player in turn order.
+
7/18/2014 If an effect puts two or more cards on the top or bottom of a library at the same time,
- the owner of those cards may arrange them in any order. That library's owner doesn't reveal
- the order in which the cards go into their library.
+ the owner of those cards may arrange them in any order.
+ That library's owner doesn't reveal the order in which the cards go into their library.
*/
class AetherspoutsEffect extends OneShotEffect {
@@ -57,7 +59,7 @@ class AetherspoutsEffect extends OneShotEffect {
this.staticText = "For each attacking creature, its owner puts it on the top or bottom of their library";
}
- public AetherspoutsEffect(final AetherspoutsEffect effect) {
+ private AetherspoutsEffect(final AetherspoutsEffect effect) {
super(effect);
}
@@ -70,107 +72,107 @@ class AetherspoutsEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
game.getPlayerList();
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- PlayerList playerList = game.getPlayerList().copy();
- playerList.setCurrent(game.getActivePlayerId());
- Player player = game.getPlayer(game.getActivePlayerId());
- Player activePlayer = player;
- do {
- List permanentsToTop = new ArrayList<>();
- List permanentsToBottom = new ArrayList<>();
- for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) {
- if (permanent.isOwnedBy(player.getId())) {
- if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
- permanentsToTop.add(permanent);
- game.informPlayers(permanent.getLogName() + " goes to the top of " + player.getLogName() + "'s library");
- } else {
- permanentsToBottom.add(permanent);
- game.informPlayers(permanent.getLogName() + " goes to the bottom of " + player.getLogName() + "'s library");
- }
- }
- }
- // cards to top
- Cards cards = new CardsImpl();
- List toLibrary = new ArrayList<>();
- for (Permanent permanent : permanentsToTop) {
- if (permanent instanceof PermanentToken) {
- toLibrary.add(permanent);
- } else {
- Card card = game.getCard(permanent.getId());
- if (card != null) {
- cards.add(card);
- }
- }
- }
- TargetCard target = new TargetCard(Zone.BATTLEFIELD, new FilterCard("order to put on the top of library (last choosen will be the top most)"));
- while (cards.size() > 1) {
- if (!player.canRespond()) {
- return false;
- }
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- Permanent permanent = game.getPermanent(card.getId());
- if (permanent != null) {
- toLibrary.add(permanent);
- }
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- Permanent permanent = game.getPermanent(card.getId());
- if (permanent != null) {
- toLibrary.add(permanent);
- }
- }
- // move all permanents to lib at the same time
- for (Permanent permanent : toLibrary) {
- player.moveCardToLibraryWithInfo(permanent, source, game, Zone.BATTLEFIELD, true, false);
- }
- // cards to bottom
- cards.clear();
- toLibrary.clear();
- for (Permanent permanent : permanentsToBottom) {
- if (permanent instanceof PermanentToken) {
- toLibrary.add(permanent);
- } else {
- Card card = game.getCard(permanent.getId());
- if (card != null) {
- cards.add(card);
- }
- }
- }
- target = new TargetCard(Zone.BATTLEFIELD, new FilterCard("order to put on bottom of library (last choosen will be bottommost card)"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
+ if (controller == null) { return false; }
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- Permanent permanent = game.getPermanent(card.getId());
- if (permanent != null) {
- toLibrary.add(permanent);
- }
+ PlayerList playerList = game.getState().getPlayersInRange(controller.getId(), game);
+ playerList.setCurrent(game.getActivePlayerId());
+ Player player = game.getPlayer(game.getActivePlayerId());
+ Player activePlayer = player;
+ do {
+ List permanentsToTop = new ArrayList<>();
+ List permanentsToBottom = new ArrayList<>();
+ for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source, game)) {
+ if (permanent.isOwnedBy(player.getId())) {
+ if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
+ permanentsToTop.add(permanent);
+ game.informPlayers(permanent.getLogName() + " goes to the top of " + player.getLogName() + "'s library");
+ } else {
+ permanentsToBottom.add(permanent);
+ game.informPlayers(permanent.getLogName() + " goes to the bottom of " + player.getLogName() + "'s library");
}
- target.clearChosen();
}
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
+ }
+ // cards to top
+ Cards cards = new CardsImpl();
+ List toLibrary = new ArrayList<>();
+ for (Permanent permanent : permanentsToTop) {
+ if (permanent instanceof PermanentToken) {
+ toLibrary.add(permanent);
+ } else {
+ Card card = game.getCard(permanent.getId());
+ if (card != null) {
+ cards.add(card);
+ }
+ }
+ }
+ TargetCard target = new TargetCard(Zone.BATTLEFIELD, new FilterCard("order to put on the top of library (last choosen will be the top most)"));
+ while (cards.size() > 1) {
+ if (!player.canRespond()) {
+ return false;
+ }
+ player.choose(Outcome.Neutral, cards, target, game);
+ Card card = cards.get(target.getFirstTarget(), game);
+ if (card != null) {
+ cards.remove(card);
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
toLibrary.add(permanent);
}
}
- // move all permanents to lib at the same time
- for (Permanent permanent : toLibrary) {
- player.moveCardToLibraryWithInfo(permanent, source, game, Zone.BATTLEFIELD, false, false);
+ target.clearChosen();
+ }
+ if (cards.size() == 1) {
+ Card card = cards.get(cards.iterator().next(), game);
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent != null) {
+ toLibrary.add(permanent);
}
- player = playerList.getNext(game, false);
- } while (player != null && !player.getId().equals(game.getActivePlayerId()) && activePlayer.canRespond());
- return true;
- }
- return false;
+ }
+ // move all permanents to lib at the same time
+ for (Permanent permanent : toLibrary) {
+ player.moveCardToLibraryWithInfo(permanent, source, game, Zone.BATTLEFIELD, true, false);
+ }
+ // cards to bottom
+ cards.clear();
+ toLibrary.clear();
+ for (Permanent permanent : permanentsToBottom) {
+ if (permanent instanceof PermanentToken) {
+ toLibrary.add(permanent);
+ } else {
+ Card card = game.getCard(permanent.getId());
+ if (card != null) {
+ cards.add(card);
+ }
+ }
+ }
+ target = new TargetCard(Zone.BATTLEFIELD, new FilterCard("order to put on bottom of library (last choosen will be bottommost card)"));
+ while (player.canRespond() && cards.size() > 1) {
+ player.choose(Outcome.Neutral, cards, target, game);
+
+ Card card = cards.get(target.getFirstTarget(), game);
+ if (card != null) {
+ cards.remove(card);
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent != null) {
+ toLibrary.add(permanent);
+ }
+ }
+ target.clearChosen();
+ }
+ if (cards.size() == 1) {
+ Card card = cards.get(cards.iterator().next(), game);
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent != null) {
+ toLibrary.add(permanent);
+ }
+ }
+ // move all permanents to lib at the same time
+ for (Permanent permanent : toLibrary) {
+ player.moveCardToLibraryWithInfo(permanent, source, game, Zone.BATTLEFIELD, false, false);
+ }
+ player = playerList.getNext(game, false);
+ } while (player != null && !player.getId().equals(game.getActivePlayerId()) && activePlayer.canRespond());
+
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AetherstreamLeopard.java b/Mage.Sets/src/mage/cards/a/AetherstreamLeopard.java
index e10a8848419..7c63853017f 100644
--- a/Mage.Sets/src/mage/cards/a/AetherstreamLeopard.java
+++ b/Mage.Sets/src/mage/cards/a/AetherstreamLeopard.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -16,8 +14,9 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class AetherstreamLeopard extends CardImpl {
@@ -36,8 +35,9 @@ public final class AetherstreamLeopard extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(1)));
// Whenever Aetherstream Leopard attacks, you may pay {E}. If you do, it gets +2/+0 until end of turn.
- this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new BoostSourceEffect(2, 0, Duration.EndOfTurn), new PayEnergyCost(1)), false,
- "Whenever {this} attacks you may pay {E}. If you do, it gets +2/+0 until end of turn."));
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new BoostSourceEffect(
+ 2, 0, Duration.EndOfTurn
+ ).setText("it gets +2/+0 until end of turn"), new PayEnergyCost(1))));
}
private AetherstreamLeopard(final AetherstreamLeopard card) {
diff --git a/Mage.Sets/src/mage/cards/a/Aethertow.java b/Mage.Sets/src/mage/cards/a/Aethertow.java
index f126ce78317..f9af151c47c 100644
--- a/Mage.Sets/src/mage/cards/a/Aethertow.java
+++ b/Mage.Sets/src/mage/cards/a/Aethertow.java
@@ -31,7 +31,7 @@ public final class Aethertow extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
// Conspire
- this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
+ this.addAbility(new ConspireAbility(ConspireAbility.ConspireTargets.ONE));
}
private Aethertow(final Aethertow card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java b/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java
index 5669bb4ebd0..6f39ece334e 100644
--- a/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java
+++ b/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java
@@ -1,8 +1,5 @@
package mage.cards.a;
-import java.util.Set;
-import java.util.UUID;
-import mage.ApprovingObject;
import mage.abilities.Ability;
import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@@ -10,20 +7,22 @@ import mage.abilities.costs.common.PayEnergyCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
-import mage.cards.*;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
-import mage.filter.common.FilterControlledPermanent;
-import mage.filter.common.FilterNonlandCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
-import mage.target.common.TargetCardInLibrary;
+import mage.util.CardUtil;
+
+import java.util.UUID;
/**
- *
* @author emerald000
*/
public final class AetherworksMarvel extends CardImpl {
@@ -35,13 +34,13 @@ public final class AetherworksMarvel extends CardImpl {
// Whenever a permanent you control is put into a graveyard, you get {E}.
this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(
new GetEnergyCountersControllerEffect(1), false,
- new FilterControlledPermanent("a permanent you control"), false));
+ StaticFilters.FILTER_CONTROLLED_A_PERMANENT, false
+ ));
// {T}, Pay {E}{E}{E}{E}{E}{E}: Look at the top six cards of your library.
// You may cast a card from among them without paying its mana cost.
// Put the rest on the bottom of your library in a random order.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new AetherworksMarvelEffect(), new TapSourceCost());
+ Ability ability = new SimpleActivatedAbility(new AetherworksMarvelEffect(), new TapSourceCost());
ability.addCost(new PayEnergyCost(6));
this.addAbility(ability);
}
@@ -78,26 +77,13 @@ class AetherworksMarvelEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Set cardsSet = controller.getLibrary().getTopCards(game, 6);
- Cards cards = new CardsImpl(cardsSet);
- TargetCard target = new TargetCardInLibrary(0, 1,
- new FilterNonlandCard("card to cast without paying its mana cost"));
- if (controller.choose(Outcome.PlayForFree, cards, target, game)) {
- Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
- if (card != null) {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- if (cardWasCast) {
- cards.remove(card);
- }
- }
- }
- controller.putCardsOnBottomOfLibrary(cards, game, source, false);
- return true;
+ if (controller == null) {
+ return false;
}
- return false;
+ Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 6));
+ CardUtil.castSpellWithAttributesForFree(controller, source, game, cards, StaticFilters.FILTER_CARD);
+ cards.retainZone(Zone.LIBRARY, game);
+ controller.putCardsOnBottomOfLibrary(cards, game, source, false);
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/Afterburn.java b/Mage.Sets/src/mage/cards/a/Afterburn.java
index a97a2861afa..a1925110676 100644
--- a/Mage.Sets/src/mage/cards/a/Afterburn.java
+++ b/Mage.Sets/src/mage/cards/a/Afterburn.java
@@ -30,8 +30,7 @@ public final class Afterburn extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Remove target creature from combat.
- Mode mode = new Mode();
- mode.addEffect(new RemoveFromCombatTargetEffect());
+ Mode mode = new Mode(new RemoveFromCombatTargetEffect());
mode.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AgadeemOccultist.java b/Mage.Sets/src/mage/cards/a/AgadeemOccultist.java
index 99b3654a0e5..f96262b5a87 100644
--- a/Mage.Sets/src/mage/cards/a/AgadeemOccultist.java
+++ b/Mage.Sets/src/mage/cards/a/AgadeemOccultist.java
@@ -81,8 +81,8 @@ class AgadeemOccultistEffect extends OneShotEffect {
TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(1, 1, filter);
if (controller != null) {
- if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
- && controller.choose(Outcome.GainControl, target, source.getSourceId(), game)) {
+ if (target.canChoose(source.getControllerId(), source, game)
+ && controller.choose(Outcome.GainControl, target, source, game)) {
if (!target.getTargets().isEmpty()) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/a/AgadeemsAwakening.java b/Mage.Sets/src/mage/cards/a/AgadeemsAwakening.java
index eb16de9bef9..75944abd326 100644
--- a/Mage.Sets/src/mage/cards/a/AgadeemsAwakening.java
+++ b/Mage.Sets/src/mage/cards/a/AgadeemsAwakening.java
@@ -100,8 +100,8 @@ class AgadeemsAwakeningTarget extends TargetCardInYourGraveyard {
}
@Override
- public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
- Set possibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
+ public Set possibleTargets(UUID sourceControllerId, Ability source, Game game) {
+ Set possibleTargets = super.possibleTargets(sourceControllerId, source, game);
Set cmcs = this.getTargets()
.stream()
.map(game::getCard)
diff --git a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java
index 341854f825b..07e0d68aac2 100644
--- a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java
+++ b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java
@@ -35,9 +35,9 @@ public final class AgelessSentinels extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Ageless Sentinels blocks, it becomes a Bird Giant, and it loses defender.
- Ability ability = new BlocksSourceTriggeredAbility(new AgelessSentinelsEffect(), false, false, true);
+ Ability ability = new BlocksSourceTriggeredAbility(new AgelessSentinelsEffect()).setTriggerPhrase("When {this} blocks, ");
Effect effect = new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.WhileOnBattlefield);
- effect.setText(", and it loses defender");
+ effect.setText(", and it loses defender. (It's no longer a Wall. This effect lasts indefinitely.)");
ability.addEffect(effect);
this.addAbility(ability);
}
@@ -50,37 +50,37 @@ public final class AgelessSentinels extends CardImpl {
public AgelessSentinels copy() {
return new AgelessSentinels(this);
}
+}
- private class AgelessSentinelsEffect extends ContinuousEffectImpl {
+class AgelessSentinelsEffect extends ContinuousEffectImpl {
- public AgelessSentinelsEffect() {
- super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
- staticText = "it becomes a Bird Giant";
+ public AgelessSentinelsEffect() {
+ super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
+ staticText = "it becomes a Bird Giant";
+ }
+
+ private AgelessSentinelsEffect(final AgelessSentinelsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AgelessSentinelsEffect copy() {
+ return new AgelessSentinelsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent == null) {
+ return false;
}
+ permanent.removeAllCreatureTypes(game);
+ permanent.addSubType(game, SubType.BIRD, SubType.GIANT);
+ return true;
+ }
- public AgelessSentinelsEffect(final AgelessSentinelsEffect effect) {
- super(effect);
- }
-
- @Override
- public AgelessSentinelsEffect copy() {
- return new AgelessSentinelsEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent permanent = game.getPermanent(source.getSourceId());
- if (permanent == null) {
- return false;
- }
- permanent.removeAllCreatureTypes(game);
- permanent.addSubType(game, SubType.BIRD, SubType.GIANT);
- return true;
- }
-
- @Override
- public boolean hasLayer(Layer layer) {
- return layer == Layer.TypeChangingEffects_4;
- }
+ @Override
+ public boolean hasLayer(Layer layer) {
+ return layer == Layer.TypeChangingEffects_4;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AgitatorAnt.java b/Mage.Sets/src/mage/cards/a/AgitatorAnt.java
index cda362b3783..02541574c22 100644
--- a/Mage.Sets/src/mage/cards/a/AgitatorAnt.java
+++ b/Mage.Sets/src/mage/cards/a/AgitatorAnt.java
@@ -86,12 +86,12 @@ class AgitatorAntEffect extends OneShotEffect {
}
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
targetPermanent.setNotTarget(true);
- player.choose(Outcome.BoostCreature, targetPermanent, source.getSourceId(), game);
+ player.choose(Outcome.BoostCreature, targetPermanent, source, game);
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
if (permanent == null || !permanent.addCounters(CounterType.P1P1.createInstance(2), player.getId(), source, game)) {
continue;
}
- new GoadTargetEffect().setTargetPointer(new FixedTarget(permanent, game)).apply(game, source);
+ game.addEffect(new GoadTargetEffect().setTargetPointer(new FixedTarget(permanent, game)), source);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/a/AidFromTheCowl.java b/Mage.Sets/src/mage/cards/a/AidFromTheCowl.java
index adfcd640ca9..82d0f16613f 100644
--- a/Mage.Sets/src/mage/cards/a/AidFromTheCowl.java
+++ b/Mage.Sets/src/mage/cards/a/AidFromTheCowl.java
@@ -25,7 +25,7 @@ import mage.watchers.common.RevoltWatcher;
public final class AidFromTheCowl extends CardImpl {
private static final String ruleText = "Revolt — At the beginning of your end step, if a permanent you controlled left the battlefield this turn, "
- + "reveal the top card of your library. If it's a permanent card, you may put it onto the battlefield. Otherwise, put it on the bottom of your library.";
+ + "reveal the top card of your library. If it's a permanent card, you may put it onto the battlefield. Otherwise, you may put it on the bottom of your library.";
public AidFromTheCowl(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}{G}");
@@ -65,7 +65,7 @@ class AidFromTheCowlEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller == null || sourceObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/a/AidTheFallen.java b/Mage.Sets/src/mage/cards/a/AidTheFallen.java
index 5e676ec87b8..4b9d5b3c70c 100644
--- a/Mage.Sets/src/mage/cards/a/AidTheFallen.java
+++ b/Mage.Sets/src/mage/cards/a/AidTheFallen.java
@@ -1,7 +1,7 @@
package mage.cards.a;
import mage.abilities.Mode;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -27,13 +27,13 @@ public final class AidTheFallen extends CardImpl {
this.getSpellAbility().getModes().setMaxModes(2);
// • Return target creature card from your graveyard to your hand.
- this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(
StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD
).withChooseHint("returns a creature card to your hand"));
// • Return target planeswalker card from your graveyard to your hand.
- Mode mode = new Mode(new ReturnToHandTargetEffect());
+ Mode mode = new Mode(new ReturnFromGraveyardToHandTargetEffect());
mode.addTarget(new TargetCardInYourGraveyard(filter)
.withChooseHint("returns a planeswalker card to your hand"));
this.getSpellAbility().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/a/AinokGuide.java b/Mage.Sets/src/mage/cards/a/AinokGuide.java
index fd5c6707ce0..3ce99a028dc 100644
--- a/Mage.Sets/src/mage/cards/a/AinokGuide.java
+++ b/Mage.Sets/src/mage/cards/a/AinokGuide.java
@@ -35,8 +35,7 @@ public final class AinokGuide extends CardImpl {
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
// * Search your library for a basic land card, reveal it, then shuffle your library and put that card on top of it.
- Mode mode = new Mode();
- mode.addEffect(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true));
+ Mode mode = new Mode(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true));
ability.addMode(mode);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AinokSurvivalist.java b/Mage.Sets/src/mage/cards/a/AinokSurvivalist.java
index 6e7db4e32b8..58e059e30c9 100644
--- a/Mage.Sets/src/mage/cards/a/AinokSurvivalist.java
+++ b/Mage.Sets/src/mage/cards/a/AinokSurvivalist.java
@@ -37,7 +37,7 @@ public final class AinokSurvivalist extends CardImpl {
this.toughness = new MageInt(1);
// Megamorph {1}{G}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{G}"), true));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{1}{G}"), true));
// When Ainok Survivalist is turned face up, destroy target artifact or enchantment an opponent controls.
Effect effect = new DestroyTargetEffect();
diff --git a/Mage.Sets/src/mage/cards/a/AinokTracker.java b/Mage.Sets/src/mage/cards/a/AinokTracker.java
index 96105d9b3e1..7c0f9ce5bba 100644
--- a/Mage.Sets/src/mage/cards/a/AinokTracker.java
+++ b/Mage.Sets/src/mage/cards/a/AinokTracker.java
@@ -28,7 +28,7 @@ public final class AinokTracker extends CardImpl {
// First Strike
this.addAbility(FirstStrikeAbility.getInstance());
// Morph 4R
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{4}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{4}{R}")));
}
private AinokTracker(final AinokTracker card) {
diff --git a/Mage.Sets/src/mage/cards/a/AirdropAeronauts.java b/Mage.Sets/src/mage/cards/a/AirdropAeronauts.java
index a60bbe3aef9..d62249d4086 100644
--- a/Mage.Sets/src/mage/cards/a/AirdropAeronauts.java
+++ b/Mage.Sets/src/mage/cards/a/AirdropAeronauts.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -16,8 +14,9 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.watchers.common.RevoltWatcher;
+import java.util.UUID;
+
/**
- *
* @author Styxo
*/
public final class AirdropAeronauts extends CardImpl {
@@ -34,10 +33,10 @@ public final class AirdropAeronauts extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Revolt — When Airdrop Aeronauts enters the battlefield, if a permanent you controlled left the battlefield this turn, you gain 5 life.
- Ability ability = new ConditionalInterveningIfTriggeredAbility(new EntersBattlefieldTriggeredAbility(
- new GainLifeEffect(5), false), RevoltCondition.instance,
- "Revolt — When {this} enters the battlefield, if a permanent you controlled left"
- + " the battlefield this turn, you gain 5 life."
+ Ability ability = new ConditionalInterveningIfTriggeredAbility(
+ new EntersBattlefieldTriggeredAbility(new GainLifeEffect(5), false),
+ RevoltCondition.instance, "When {this} enters the battlefield, " +
+ "if a permanent you controlled left the battlefield this turn, you gain 5 life."
);
ability.setAbilityWord(AbilityWord.REVOLT);
this.addAbility(ability, new RevoltWatcher());
diff --git a/Mage.Sets/src/mage/cards/a/AjaniAdversaryOfTyrants.java b/Mage.Sets/src/mage/cards/a/AjaniAdversaryOfTyrants.java
index c6efc37d169..fcdc8d17509 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniAdversaryOfTyrants.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniAdversaryOfTyrants.java
@@ -1,27 +1,27 @@
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
-import mage.constants.SubType;
-import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.counters.CounterType;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.command.emblems.AjaniAdversaryOfTyrantsEmblem;
+import mage.target.TargetPermanent;
import mage.target.common.TargetCardInYourGraveyard;
-import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
/**
- *
* @author TheElk801
*/
public final class AjaniAdversaryOfTyrants extends CardImpl {
@@ -38,11 +38,11 @@ public final class AjaniAdversaryOfTyrants extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Put a +1/+1 counter on each of up to two target creatures.
Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 1);
- ability.addTarget(new TargetCreaturePermanent(0, 2));
+ ability.addTarget(new TargetPermanent(0, 2, StaticFilters.FILTER_PERMANENT_CREATURES));
this.addAbility(ability);
// −2: Return target creature card with converted mana cost 2 or less from your graveyard to the battlefield.
diff --git a/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java b/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java
index 22cf714c4bf..67d51825f00 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java
@@ -4,7 +4,6 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.ControllerLifeCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
@@ -34,7 +33,7 @@ public final class AjaniCallerOfThePride extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Put a +1/+1 counter on up to one target creature.
Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance());
effect.setText("Put a +1/+1 counter on up to one target creature");
diff --git a/Mage.Sets/src/mage/cards/a/AjaniGoldmane.java b/Mage.Sets/src/mage/cards/a/AjaniGoldmane.java
index 6efe3fc8d75..d779587b675 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniGoldmane.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniGoldmane.java
@@ -1,13 +1,7 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
-import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.ContinuousEffectImpl;
-import mage.abilities.effects.Effects;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
@@ -15,17 +9,17 @@ import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.counters.CounterType;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.common.FilterCreaturePermanent;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.game.permanent.token.TokenImpl;
-import mage.players.Player;
+import mage.filter.StaticFilters;
+import mage.game.permanent.token.AvatarToken;
+
+import java.util.UUID;
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public final class AjaniGoldmane extends CardImpl {
@@ -35,20 +29,24 @@ public final class AjaniGoldmane extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: You gain 2 life.
this.addAbility(new LoyaltyAbility(new GainLifeEffect(2), 1));
// -1: Put a +1/+1 counter on each creature you control. Those creatures gain vigilance until end of turn.
- Effects effects1 = new Effects();
- effects1.add(new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()));
- effects1.add(new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn, new FilterCreaturePermanent()));
- this.addAbility(new LoyaltyAbility(effects1, -1));
+ Ability ability = new LoyaltyAbility(new AddCountersAllEffect(
+ CounterType.P1P1.createInstance(),
+ StaticFilters.FILTER_CONTROLLED_CREATURE
+ ), -1);
+ ability.addEffect(new GainAbilityControlledEffect(
+ VigilanceAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_CONTROLLED_CREATURE
+ ).setText("Those creatures gain vigilance until end of turn"));
+ this.addAbility(ability);
// -6: Create a white Avatar creature token. It has "This creature's power and toughness are each equal to your life total."
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new AvatarToken()), -6));
-
}
private AjaniGoldmane(final AjaniGoldmane card) {
@@ -59,54 +57,4 @@ public final class AjaniGoldmane extends CardImpl {
public AjaniGoldmane copy() {
return new AjaniGoldmane(this);
}
-
-}
-
-class AvatarToken extends TokenImpl {
-
- public AvatarToken() {
- super("Avatar", "white Avatar creature token with \"This creature's power and toughness are each equal to your life total.\"");
- cardType.add(CardType.CREATURE);
- subtype.add(SubType.AVATAR);
- color.setWhite(true);
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AvatarTokenEffect()));
- }
- public AvatarToken(final AvatarToken token) {
- super(token);
- }
-
- public AvatarToken copy() {
- return new AvatarToken(this);
- }
-}
-
-class AvatarTokenEffect extends ContinuousEffectImpl {
-
- public AvatarTokenEffect() {
- super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.SetPT_7b, Outcome.BoostCreature);
- }
-
- public AvatarTokenEffect(final AvatarTokenEffect effect) {
- super(effect);
- }
-
- @Override
- public AvatarTokenEffect copy() {
- return new AvatarTokenEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent token = game.getPermanent(source.getSourceId());
- if (token != null) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- token.getPower().setValue(controller.getLife());
- token.getToughness().setValue(controller.getLife());
- return true;
- }
- }
- return false;
- }
-
}
diff --git a/Mage.Sets/src/mage/cards/a/AjaniInspiringLeader.java b/Mage.Sets/src/mage/cards/a/AjaniInspiringLeader.java
index 87c510e8f3a..e7eeb863bb9 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniInspiringLeader.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniInspiringLeader.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
@@ -31,7 +30,7 @@ public final class AjaniInspiringLeader extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +2: You gain 2 life. Put two +1/+1 counters on up to one target creature.
Ability ability = new LoyaltyAbility(new GainLifeEffect(2), 2);
diff --git a/Mage.Sets/src/mage/cards/a/AjaniMentorOfHeroes.java b/Mage.Sets/src/mage/cards/a/AjaniMentorOfHeroes.java
index f4cb427e1e9..f3c9a18acd4 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniMentorOfHeroes.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniMentorOfHeroes.java
@@ -4,9 +4,9 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.counter.DistributeCountersEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -14,7 +14,6 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
-import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreaturePermanent;
@@ -43,15 +42,16 @@ public final class AjaniMentorOfHeroes extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Distribute three +1/+1 counters among one, two, or three target creatures you control
Ability ability = new LoyaltyAbility(new DistributeCountersEffect(CounterType.P1P1, 3, false, "one, two, or three target creatures you control"), 1);
ability.addTarget(new TargetCreaturePermanentAmount(3, filter));
this.addAbility(ability);
- // +1: Look at the top four cards of your library. You may reveal an Aura, creature, or planeswalker card from among them and put that card into your hand. Put the rest on the bottom of your library in any order.
- this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(4, 1, filterCard, true, false, Zone.HAND, true), 1));
+ // +1: Look at the top four cards of your library. You may reveal an Aura, creature, or planeswalker card
+ // from among them and put it into your hand. Put the rest on the bottom of your library in any order.
+ this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(4, 1, filterCard, PutCards.HAND, PutCards.BOTTOM_ANY), 1));
// -8: You gain 100 life.
this.addAbility(new LoyaltyAbility(new GainLifeEffect(100), -8));
diff --git a/Mage.Sets/src/mage/cards/a/AjaniSteadfast.java b/Mage.Sets/src/mage/cards/a/AjaniSteadfast.java
index c951d1b4f02..4d843009533 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniSteadfast.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniSteadfast.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
@@ -44,7 +43,7 @@ public final class AjaniSteadfast extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Until end of turn, up to one target creature gets +1/+1 and gains first strike, vigilance, and lifelink.
Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn);
diff --git a/Mage.Sets/src/mage/cards/a/AjaniStrengthOfThePride.java b/Mage.Sets/src/mage/cards/a/AjaniStrengthOfThePride.java
index d0f076bbe36..b8154b1c060 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniStrengthOfThePride.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniStrengthOfThePride.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@@ -32,7 +31,7 @@ public final class AjaniStrengthOfThePride extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +1: You gain life equal to the number of creatures you control plus the number of planeswalkers you control.
this.addAbility(new LoyaltyAbility(new GainLifeEffect(
diff --git a/Mage.Sets/src/mage/cards/a/AjaniTheGreathearted.java b/Mage.Sets/src/mage/cards/a/AjaniTheGreathearted.java
index 837660006db..e30d19de341 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniTheGreathearted.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniTheGreathearted.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
@@ -38,7 +37,7 @@ public final class AjaniTheGreathearted extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// Creatures you control have vigilance.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
@@ -52,7 +51,7 @@ public final class AjaniTheGreathearted extends CardImpl {
// -2: Put a +1/+1 counter on each creature you control and a loyalty counter on each other planeswalker you control.
Ability ability = new LoyaltyAbility(new AddCountersAllEffect(
- CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURES
+ CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
), -2);
ability.addEffect(new AddCountersAllEffect(
CounterType.LOYALTY.createInstance(), filter
diff --git a/Mage.Sets/src/mage/cards/a/AjaniUnyielding.java b/Mage.Sets/src/mage/cards/a/AjaniUnyielding.java
index 50a5472824e..786318a9df8 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniUnyielding.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniUnyielding.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.ExileAndGainLifeEqualPowerTargetEffect;
import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
@@ -41,7 +40,7 @@ public final class AjaniUnyielding extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +2: Reveal the top three cards of your library. Put all nonland permanent cards revealed this way into your hand and the rest on the bottom of your library in any order.
this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(3, nonlandPermanentFilter, Zone.LIBRARY), 2));
@@ -53,7 +52,7 @@ public final class AjaniUnyielding extends CardImpl {
// -9: Put five +1/+1 counters on each creature you control and five loyalty counters on each other planeswalker you control.
LoyaltyAbility ajaniAbility3 = new LoyaltyAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(5), new FilterControlledCreaturePermanent()), -9);
- ajaniAbility3.addEffect(new AddCountersAllEffect(CounterType.LOYALTY.createInstance(5), planeswalkerFilter));
+ ajaniAbility3.addEffect(new AddCountersAllEffect(CounterType.LOYALTY.createInstance(5), planeswalkerFilter).setText("and five loyalty counters on each other planeswalker you control"));
this.addAbility(ajaniAbility3);
}
diff --git a/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
index 5e8025bcb75..1bff23aab26 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.ControllerLifeCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.RevealCardsFromLibraryUntilEffect;
@@ -32,7 +31,7 @@ public final class AjaniValiantProtector extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +2: Put two +1/+1 counters on up to one target creature.
Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), 2);
diff --git a/Mage.Sets/src/mage/cards/a/AjaniVengeant.java b/Mage.Sets/src/mage/cards/a/AjaniVengeant.java
index 57eee39eda4..84d4f64875d 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniVengeant.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniVengeant.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DestroyAllControlledTargetEffect;
@@ -36,7 +35,7 @@ public final class AjaniVengeant extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: Target permanent doesn't untap during its controller's next untap step.
LoyaltyAbility ability1 = new LoyaltyAbility(new DontUntapInControllersNextUntapStepTargetEffect(), 1);
@@ -46,7 +45,7 @@ public final class AjaniVengeant extends CardImpl {
// −2: Ajani Vengeant deals 3 damage to any target and you gain 3 life.
Effects effects1 = new Effects();
effects1.add(new DamageTargetEffect(3));
- effects1.add(new GainLifeEffect(3));
+ effects1.add(new GainLifeEffect(3).concatBy("and"));
LoyaltyAbility ability2 = new LoyaltyAbility(effects1, -2);
ability2.addTarget(new TargetAnyTarget());
this.addAbility(ability2);
diff --git a/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java b/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java
index e7fd5f8837b..33feec0fdd1 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.ControllerLifeCount;
import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
import mage.abilities.effects.common.GainLifeEffect;
@@ -29,7 +28,7 @@ public final class AjaniWiseCounselor extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +2: You gain 1 life for each creature you control.
this.addAbility(new LoyaltyAbility(new GainLifeEffect(CreaturesYouControlCount.instance)
diff --git a/Mage.Sets/src/mage/cards/a/AjanisInfluence.java b/Mage.Sets/src/mage/cards/a/AjanisInfluence.java
index 94700f16dc7..fd10941fba3 100644
--- a/Mage.Sets/src/mage/cards/a/AjanisInfluence.java
+++ b/Mage.Sets/src/mage/cards/a/AjanisInfluence.java
@@ -2,13 +2,12 @@ package mage.cards.a;
import java.util.UUID;
import mage.ObjectColor;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
@@ -35,12 +34,7 @@ public final class AjanisInfluence extends CardImpl {
// Look at the top five cards of your library. You may reveal a white card form among them and put it into your hand. Put the rest on the bottom of your library in a random order.
this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(5), false, StaticValue.get(1), filter,
- Zone.LIBRARY, false, true, false, Zone.HAND, true, false, false
- ).setBackInRandomOrder(true).setText("Look at the top five cards of your library. "
- + "You may reveal a white card from among them and put it into your hand. "
- + "Put the rest on the bottom of your library in a random order.")
- );
+ 5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM).concatBy("
"));
}
private AjanisInfluence(final AjanisInfluence card) {
diff --git a/Mage.Sets/src/mage/cards/a/AkiriFearlessVoyager.java b/Mage.Sets/src/mage/cards/a/AkiriFearlessVoyager.java
index a7583635ab4..c9dbd3ca820 100644
--- a/Mage.Sets/src/mage/cards/a/AkiriFearlessVoyager.java
+++ b/Mage.Sets/src/mage/cards/a/AkiriFearlessVoyager.java
@@ -142,11 +142,11 @@ class AkiriFearlessVoyagerEffect extends OneShotEffect {
return false;
}
TargetPermanent target = new TargetPermanent(1, 1, filter, true);
- if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)
+ if (!target.canChoose(source.getControllerId(), source, game)
|| !player.chooseUse(outcome, "Unnattach an equipment from a creature you control?", source, game)) {
return false;
}
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
Permanent equipment = game.getPermanent(target.getFirstTarget());
if (equipment == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/a/AkkiBattleSquad.java b/Mage.Sets/src/mage/cards/a/AkkiBattleSquad.java
new file mode 100644
index 00000000000..846e9e22b71
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AkkiBattleSquad.java
@@ -0,0 +1,53 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
+import mage.abilities.effects.common.AdditionalCombatPhaseEffect;
+import mage.abilities.effects.common.UntapAllEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.permanent.ModifiedPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AkkiBattleSquad extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter
+ = new FilterControlledCreaturePermanent("modified creatures you control");
+
+ static {
+ filter.add(ModifiedPredicate.instance);
+ }
+
+ public AkkiBattleSquad(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}");
+
+ this.subtype.add(SubType.GOBLIN);
+ this.subtype.add(SubType.SAMURAI);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // Whenever one or more modified creatures you control attack, untap all modified creatures you control. After this combat phase, there is an additional combat phase. This ability triggers only once each turn.
+ Ability ability = new AttacksCreatureYouControlTriggeredAbility(
+ new UntapAllEffect(filter), false, filter
+ ).setTriggerPhrase("Whenever one or more modified creatures you control attack, ").setTriggersOnce(true);
+ ability.addEffect(new AdditionalCombatPhaseEffect());
+ this.addAbility(ability);
+ }
+
+ private AkkiBattleSquad(final AkkiBattleSquad card) {
+ super(card);
+ }
+
+ @Override
+ public AkkiBattleSquad copy() {
+ return new AkkiBattleSquad(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AkoumBattlesinger.java b/Mage.Sets/src/mage/cards/a/AkoumBattlesinger.java
index b7fb362bb3c..36dedb10152 100644
--- a/Mage.Sets/src/mage/cards/a/AkoumBattlesinger.java
+++ b/Mage.Sets/src/mage/cards/a/AkoumBattlesinger.java
@@ -39,7 +39,7 @@ public final class AkoumBattlesinger extends CardImpl {
// Haste
this.addAbility(HasteAbility.getInstance());
// Whenever Akoum Battlesinger or another Ally enters the battlefield under your control, you may have Ally creatures you control get +1/+0 until end of turn.
- this.addAbility(new AllyEntersBattlefieldTriggeredAbility(new BoostControlledEffect(1, 0, Duration.EndOfTurn, filter, false), true));
+ this.addAbility(new AllyEntersBattlefieldTriggeredAbility(new BoostControlledEffect(1, 0, Duration.EndOfTurn, filter, false), true).setAbilityWord(null));
}
private AkoumBattlesinger(final AkoumBattlesinger card) {
diff --git a/Mage.Sets/src/mage/cards/a/AkoumBoulderfoot.java b/Mage.Sets/src/mage/cards/a/AkoumBoulderfoot.java
index 5f986c84952..7e97709e670 100644
--- a/Mage.Sets/src/mage/cards/a/AkoumBoulderfoot.java
+++ b/Mage.Sets/src/mage/cards/a/AkoumBoulderfoot.java
@@ -27,7 +27,7 @@ public final class AkoumBoulderfoot extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(5);
- Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1), false);
+ Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1, "it"), false);
Target target = new TargetAnyTarget();
ability.addTarget(target);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AkoumHellkite.java b/Mage.Sets/src/mage/cards/a/AkoumHellkite.java
index 9c61c25c58b..2d3cdfd6856 100644
--- a/Mage.Sets/src/mage/cards/a/AkoumHellkite.java
+++ b/Mage.Sets/src/mage/cards/a/AkoumHellkite.java
@@ -58,7 +58,7 @@ class AkoumHellkiteTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, new AkoumHellkiteDamageEffect());
}
- public AkoumHellkiteTriggeredAbility(final AkoumHellkiteTriggeredAbility ability) {
+ private AkoumHellkiteTriggeredAbility(final AkoumHellkiteTriggeredAbility ability) {
super(ability);
}
@@ -75,19 +75,21 @@ class AkoumHellkiteTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent != null
- && permanent.isLand(game)
- && permanent.isControlledBy(getControllerId())) {
- Permanent sourcePermanent = game.getPermanent(getSourceId());
- if (sourcePermanent != null) {
- for (Effect effect : getEffects()) {
- if (effect instanceof AkoumHellkiteDamageEffect) {
- effect.setTargetPointer(new FixedTarget(permanent, game));
- }
- return true;
- }
+ if (permanent == null) { return false; }
+
+ if (!permanent.isLand(game) || !permanent.isControlledBy(getControllerId())) { return false; }
+
+ Permanent sourcePermanent = game.getPermanent(getSourceId());
+ if (sourcePermanent == null) { return false; }
+
+ for (Effect effect : getEffects()) {
+ if (effect instanceof AkoumHellkiteDamageEffect) {
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ return true;
}
+
}
+ // The Hellkit somehow lost it's damage effect but not it's landfall ability
return false;
}
@@ -116,24 +118,22 @@ class AkoumHellkiteDamageEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent land = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
+ if (land == null) { return false; }
+
+ int damage = land.hasSubtype(SubType.MOUNTAIN, game) ? 2 : 1;
+
+ // Get target for damange
Player player = game.getPlayer(source.getFirstTarget());
- if (land != null && player != null) {
- if (land.hasSubtype(SubType.MOUNTAIN, game)) {
- player.damage(2, source.getSourceId(), source, game);
- } else {
- player.damage(1, source.getSourceId(), source, game);
- }
- return true;
- }
Permanent permanent = game.getPermanent(source.getFirstTarget());
- if (land != null && permanent != null) {
- if (land.hasSubtype(SubType.MOUNTAIN, game)) {
- permanent.damage(2, source.getSourceId(), source, game);
- } else {
- permanent.damage(1, source.getSourceId(), source, game);
- }
- return true;
+ if (player == null && permanent == null) { return false; }
+
+ if (player != null) {
+ // Target is a player
+ player.damage(damage, source.getSourceId(), source, game);
+ } else {
+ // Target is a permanent
+ permanent.damage(damage, source.getSourceId(), source, game);
}
- return false;
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AkroanHorse.java b/Mage.Sets/src/mage/cards/a/AkroanHorse.java
index ea9789aebed..2e741b5ea85 100644
--- a/Mage.Sets/src/mage/cards/a/AkroanHorse.java
+++ b/Mage.Sets/src/mage/cards/a/AkroanHorse.java
@@ -37,8 +37,10 @@ public final class AkroanHorse extends CardImpl {
// Defender
this.addAbility(DefenderAbility.getInstance());
+
// When Akroan Horse enters the battlefield, an opponent gains control of it.
this.addAbility(new EntersBattlefieldTriggeredAbility(new AkroanHorseChangeControlEffect(), false));
+
// At the beginning of your upkeep, each opponent create a 1/1 white Soldier creature token.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new AkroanHorseCreateTokenEffect(), TargetController.YOU, false));
}
@@ -60,7 +62,7 @@ class AkroanHorseChangeControlEffect extends OneShotEffect {
this.staticText = "an opponent gains control of it";
}
- public AkroanHorseChangeControlEffect(final AkroanHorseChangeControlEffect effect) {
+ private AkroanHorseChangeControlEffect(final AkroanHorseChangeControlEffect effect) {
super(effect);
}
@@ -88,7 +90,7 @@ class AkroanHorseChangeControlEffect extends OneShotEffect {
class AkroanHorseGainControlEffect extends ContinuousEffectImpl {
- UUID controller;
+ private final UUID controller;
public AkroanHorseGainControlEffect(Duration duration, UUID controller) {
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
@@ -107,14 +109,18 @@ class AkroanHorseGainControlEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
- Permanent permanent = game.getPermanent(source.getFirstTarget());
- if (targetPointer != null) {
+ Permanent permanent;
+
+ if (targetPointer == null) {
+ permanent = game.getPermanent(source.getFirstTarget());
+ } else {
permanent = game.getPermanent(targetPointer.getFirst(game, source));
}
- if (permanent != null) {
- return permanent.changeControllerId(controller, game, source);
- }
- return false;
+
+ if (permanent == null) { return false; }
+
+ return permanent.changeControllerId(controller, game, source);
+
}
@Override
@@ -130,7 +136,7 @@ class AkroanHorseCreateTokenEffect extends OneShotEffect {
this.staticText = "each opponent creates a 1/1 white Soldier creature token";
}
- public AkroanHorseCreateTokenEffect(final AkroanHorseCreateTokenEffect effect) {
+ private AkroanHorseCreateTokenEffect(final AkroanHorseCreateTokenEffect effect) {
super(effect);
}
diff --git a/Mage.Sets/src/mage/cards/a/AkromaAngelOfFury.java b/Mage.Sets/src/mage/cards/a/AkromaAngelOfFury.java
index 84b6c198062..538292d545b 100644
--- a/Mage.Sets/src/mage/cards/a/AkromaAngelOfFury.java
+++ b/Mage.Sets/src/mage/cards/a/AkromaAngelOfFury.java
@@ -41,7 +41,7 @@ public final class AkromaAngelOfFury extends CardImpl {
// {R}: Akroma, Angel of Fury gets +1/+0 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1,0, Duration.EndOfTurn), new ManaCostsImpl("{R}")));
// Morph {3}{R}{R}{R}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{R}{R}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{3}{R}{R}{R}")));
}
private AkromaAngelOfFury(final AkromaAngelOfFury card) {
diff --git a/Mage.Sets/src/mage/cards/a/AkromaVisionOfIxidor.java b/Mage.Sets/src/mage/cards/a/AkromaVisionOfIxidor.java
index b3f27fa3cdc..0e86ee06aa8 100644
--- a/Mage.Sets/src/mage/cards/a/AkromaVisionOfIxidor.java
+++ b/Mage.Sets/src/mage/cards/a/AkromaVisionOfIxidor.java
@@ -104,9 +104,9 @@ class AkromaVisionOfIxidorEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
- source.getControllerId(), source.getSourceId(), game
+ source.getControllerId(), source, game
)) {
- Abilities abilities = permanent.getAbilities(game);
+ Abilities abilities = permanent.getAbilities(game);
int count = classes
.stream()
.map(clazz -> abilities.stream().anyMatch(clazz::isInstance))
diff --git a/Mage.Sets/src/mage/cards/a/AlabasterPotion.java b/Mage.Sets/src/mage/cards/a/AlabasterPotion.java
index 4877d3acebc..1462eaca09c 100644
--- a/Mage.Sets/src/mage/cards/a/AlabasterPotion.java
+++ b/Mage.Sets/src/mage/cards/a/AlabasterPotion.java
@@ -25,8 +25,7 @@ public final class AlabasterPotion extends CardImpl {
// Choose one - Target player gains X life; or prevent the next X damage that would be dealt to any target this turn.
this.getSpellAbility().addEffect(new GainLifeTargetEffect(ManacostVariableValue.REGULAR));
this.getSpellAbility().addTarget(new TargetPlayer());
- Mode mode = new Mode();
- mode.addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, ManacostVariableValue.REGULAR));
+ Mode mode = new Mode(new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, ManacostVariableValue.REGULAR));
mode.addTarget(new TargetAnyTarget());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AlabornZealot.java b/Mage.Sets/src/mage/cards/a/AlabornZealot.java
index ee4c93ca251..9c84b4a111f 100644
--- a/Mage.Sets/src/mage/cards/a/AlabornZealot.java
+++ b/Mage.Sets/src/mage/cards/a/AlabornZealot.java
@@ -1,16 +1,15 @@
-
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
-import mage.abilities.common.BlocksSourceTriggeredAbility;
+import mage.abilities.TriggeredAbility;
+import mage.abilities.common.BlocksCreatureTriggeredAbility;
import mage.abilities.effects.common.DestroySourceEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
-import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.SubType;
/**
*
@@ -27,8 +26,11 @@ public final class AlabornZealot extends CardImpl {
this.toughness = new MageInt(1);
// When Alaborn Zealot blocks a creature, destroy that creature and Alaborn Zealot.
- Ability ability = new BlocksSourceTriggeredAbility(new DestroyTargetEffect().setText("destroy that creature"), false, true, true);
+ TriggeredAbility ability = new BlocksCreatureTriggeredAbility(
+ new DestroyTargetEffect().setText("destroy that creature")
+ );
ability.addEffect(new DestroySourceEffect().setText("and {this}"));
+ ability.setTriggerPhrase("When {this} blocks a creature, ");
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AlchemistsGreeting.java b/Mage.Sets/src/mage/cards/a/AlchemistsGreeting.java
index e87883fed1f..6f401139368 100644
--- a/Mage.Sets/src/mage/cards/a/AlchemistsGreeting.java
+++ b/Mage.Sets/src/mage/cards/a/AlchemistsGreeting.java
@@ -24,7 +24,7 @@ public final class AlchemistsGreeting extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Madness {1}{R}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{1}{R}")));
}
private AlchemistsGreeting(final AlchemistsGreeting card) {
diff --git a/Mage.Sets/src/mage/cards/a/AlertHeedbonder.java b/Mage.Sets/src/mage/cards/a/AlertHeedbonder.java
index 8e77c371bdd..02eb1bdb7cf 100644
--- a/Mage.Sets/src/mage/cards/a/AlertHeedbonder.java
+++ b/Mage.Sets/src/mage/cards/a/AlertHeedbonder.java
@@ -44,7 +44,9 @@ public final class AlertHeedbonder extends CardImpl {
// At the beginning of your end step, you gain 1 life for each creature you control with vigilance.
this.addAbility(new BeginningOfEndStepTriggeredAbility(
- new GainLifeEffect(xValue), TargetController.YOU, false
+ new GainLifeEffect(xValue)
+ .setText("you gain 1 life for each creature you control with vigilance"),
+ TargetController.YOU, false
));
}
diff --git a/Mage.Sets/src/mage/cards/a/AleshasVanguard.java b/Mage.Sets/src/mage/cards/a/AleshasVanguard.java
index 019b3b39153..8a452e8c09f 100644
--- a/Mage.Sets/src/mage/cards/a/AleshasVanguard.java
+++ b/Mage.Sets/src/mage/cards/a/AleshasVanguard.java
@@ -23,7 +23,7 @@ public final class AleshasVanguard extends CardImpl {
this.toughness = new MageInt(3);
// Dash {2}{B}
- this.addAbility(new DashAbility(this, "{2}{B}"));
+ this.addAbility(new DashAbility("{2}{B}"));
}
private AleshasVanguard(final AleshasVanguard card) {
diff --git a/Mage.Sets/src/mage/cards/a/AlhammarretHighArbiter.java b/Mage.Sets/src/mage/cards/a/AlhammarretHighArbiter.java
index 165adfccda2..f49af6d9d42 100644
--- a/Mage.Sets/src/mage/cards/a/AlhammarretHighArbiter.java
+++ b/Mage.Sets/src/mage/cards/a/AlhammarretHighArbiter.java
@@ -138,7 +138,7 @@ class AlhammarretHighArbiterCantCastEffect extends ContinuousRuleModifyingEffect
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You may not cast a card named " + cardName + " (" + mageObject.getIdName() + ").";
}
diff --git a/Mage.Sets/src/mage/cards/a/AliFromCairo.java b/Mage.Sets/src/mage/cards/a/AliFromCairo.java
index 2957af4ef7c..310a6b6428a 100644
--- a/Mage.Sets/src/mage/cards/a/AliFromCairo.java
+++ b/Mage.Sets/src/mage/cards/a/AliFromCairo.java
@@ -65,27 +65,26 @@ class AliFromCairoReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId());
- if (permanent != null) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null
- && (controller.getLife() > 0) &&(controller.getLife() - event.getAmount()) < 1
- && event.getPlayerId().equals(controller.getId())
- ) {
- return true;
- }
- }
- return false;
+ if (permanent == null) { return false; }
+
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false; }
+
+ return (controller.getLife() > 0) && (controller.getLife() - event.getAmount()) < 1
+ && event.getPlayerId().equals(controller.getId());
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- // 10/1/2008: The ability doesn't change how much damage is dealt;
- // it just changes how much life that damage makes you lose.
- // An effect such as Spirit Link will see the full amount of damage being dealt.
- event.setAmount(controller.getLife() - 1);
- }
+ if (controller == null) { return false; }
+
+ // 10/1/2008: The ability doesn't change how much damage is dealt;
+ // it just changes how much life that damage makes you lose.
+ // An effect such as Spirit Link will see the full amount of damage being dealt.
+ event.setAmount(controller.getLife() - 1);
+
+ // TODO: Is this supposed to be false? Seem suspicious
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java b/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java
index 3fc6f9f0f98..c640759be20 100644
--- a/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java
+++ b/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java
@@ -91,7 +91,7 @@ class AlibouAncientWitnessEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- int xValue = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ int xValue = game.getBattlefield().count(filter, source.getControllerId(), source, game);
if (xValue < 1) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java b/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java
index cfde81c4070..6658b9c9e5e 100644
--- a/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java
+++ b/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java
@@ -70,20 +70,20 @@ class AlignedHedronNetworkExileEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false;}
+
Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent == null) { return false; }
+
// If Whale leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
- if (controller != null && permanent != null) {
- Set toExile = new LinkedHashSet<>();
- for (Permanent creature : game.getBattlefield().getActivePermanents(filter, controller.getId(), source.getSourceId(), game)) {
- toExile.add(creature);
- }
- if (!toExile.isEmpty()) {
- controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName());
- new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()).apply(game, source);
- }
- return true;
- }
- return false;
+ Set toExile = new LinkedHashSet<>(game.getBattlefield().getActivePermanents(filter, controller.getId(), source, game));
+ if (toExile.isEmpty()) { return false; }
+
+ controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName());
+ new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()).apply(game, source);
+
+ return true;
+
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AliveWell.java b/Mage.Sets/src/mage/cards/a/AliveWell.java
index d2b9468f9ed..5c10da767e4 100644
--- a/Mage.Sets/src/mage/cards/a/AliveWell.java
+++ b/Mage.Sets/src/mage/cards/a/AliveWell.java
@@ -66,7 +66,7 @@ class WellEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- int life = 2 * game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ int life = 2 * game.getBattlefield().count(filter, source.getControllerId(), source, game);
player.gainLife(life, game, source);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/a/AllHallowsEve.java b/Mage.Sets/src/mage/cards/a/AllHallowsEve.java
index eb9db02f159..1b6e2b12496 100644
--- a/Mage.Sets/src/mage/cards/a/AllHallowsEve.java
+++ b/Mage.Sets/src/mage/cards/a/AllHallowsEve.java
@@ -9,6 +9,7 @@ import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileSpellEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
@@ -34,10 +35,18 @@ public final class AllHallowsEve extends CardImpl {
this.getSpellAbility().addEffect(new ExileSpellEffect());
this.getSpellAbility().addEffect(new AddCountersSourceEffect(
CounterType.SCREAM.createInstance(), StaticValue.get(2), true, true
- ).setText("with 2 scream counters on it"));
+ ).setText("with two scream counters on it"));
- // At the beginning of your upkeep, if All Hallow's Eve is exiled with a scream counter on it, remove a scream counter from it. If there are no more scream counters on it, put it into your graveyard and each player returns all creature cards from their graveyard to the battlefield.
- this.addAbility(new ConditionalInterveningIfTriggeredAbility(new BeginningOfUpkeepTriggeredAbility(Zone.EXILED, new AllHallowsEveEffect(), TargetController.YOU, false), AllHallowsEveCondition.instance, "At the beginning of your upkeep, if {this} is exiled with a scream counter on it, remove a scream counter from it. If there are no more scream counters on it, put it into your graveyard and each player returns all creature cards from their graveyard to the battlefield."));
+ // At the beginning of your upkeep, if All Hallow's Eve is exiled with a scream counter on it, remove a scream counter from it.
+ // If there are no more scream counters on it, put it into your graveyard and each player returns all creature cards from their graveyard to the battlefield.
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(
+ Zone.EXILED,
+ new RemoveCounterSourceEffect(CounterType.SCREAM.createInstance(1)),
+ TargetController.YOU,
+ false
+ );
+ ability.addEffect(new AllHallowsEveEffect());
+ this.addAbility(ability);
}
private AllHallowsEve(final AllHallowsEve card) {
@@ -50,23 +59,12 @@ public final class AllHallowsEve extends CardImpl {
}
}
-enum AllHallowsEveCondition implements Condition {
- instance;
-
- @Override
- public boolean apply(Game game, Ability source) {
- MageObject sourceObject = source.getSourceObjectIfItStillExists(game);
- return sourceObject != null
- && game.getState().getZone(source.getSourceId()) == Zone.EXILED
- && sourceObject instanceof Card
- && ((Card) sourceObject).getMainCard().getCounters(game).getCount(CounterType.SCREAM) > 0;
- }
-}
-
class AllHallowsEveEffect extends OneShotEffect {
AllHallowsEveEffect() {
super(Outcome.PutCreatureInPlay);
+ staticText = "If there are no more scream counters on it, put it into your graveyard " +
+ "and each player returns all creature cards from their graveyard to the battlefield.";
}
private AllHallowsEveEffect(final AllHallowsEveEffect effect) {
@@ -80,13 +78,15 @@ class AllHallowsEveEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Card card = (Card) source.getSourceObject(game);
+ Card allHallowsEveCard = (Card) source.getSourceObject(game);
+ if (allHallowsEveCard == null) { return false; }
Player controller = game.getPlayer(source.getControllerId());
- if (card == null || controller == null) {
- return false;
- }
- controller.moveCards(card, Zone.GRAVEYARD, source, game);
- Cards cards = new CardsImpl();
+ if (controller == null) { return false; }
+
+ if (allHallowsEveCard.getCounters(game).getCount(CounterType.SCREAM) > 0) { return false; }
+
+ controller.moveCards(allHallowsEveCard, Zone.GRAVEYARD, source, game);
+ Cards allCreatureCardsInGraveyards = new CardsImpl();
game.getState()
.getPlayersInRange(source.getControllerId(), game)
.stream()
@@ -96,8 +96,9 @@ class AllHallowsEveEffect extends OneShotEffect {
.map(g -> g.getCards(game))
.flatMap(Collection::stream)
.filter(card1 -> card1.isCreature(game))
- .forEach(cards::add);
- controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
+ .forEach(allCreatureCardsInGraveyards::add);
+
+ controller.moveCards(allCreatureCardsInGraveyards.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null);
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AllSeeingArbiter.java b/Mage.Sets/src/mage/cards/a/AllSeeingArbiter.java
new file mode 100644
index 00000000000..009e012464f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AllSeeingArbiter.java
@@ -0,0 +1,95 @@
+package mage.cards.a;
+
+import java.util.HashSet;
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DiscardCardControllerTriggeredAbility;
+import mage.abilities.effects.common.DrawDiscardControllerEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.Card;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetOpponentsCreaturePermanent;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class AllSeeingArbiter extends CardImpl {
+
+ public AllSeeingArbiter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}");
+
+ this.subtype.add(SubType.AVATAR);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever All-Seeing Arbiter enters the battlefield or attacks, draw two cards, then discard a card.
+ this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DrawDiscardControllerEffect(2, 1)));
+
+ // Whenever you discard a card, target creature an opponent controls gets -X/-0 until your next turn, where X is the number of different mana values among cards in your graveyard.
+ Ability ability = new DiscardCardControllerTriggeredAbility(new BoostTargetEffect(
+ AllSeeingArbiterValue.instance, StaticValue.get(0), Duration.UntilYourNextTurn, true
+ ), false);
+ ability.addTarget(new TargetOpponentsCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private AllSeeingArbiter(final AllSeeingArbiter card) {
+ super(card);
+ }
+
+ @Override
+ public AllSeeingArbiter copy() {
+ return new AllSeeingArbiter(this);
+ }
+}
+
+enum AllSeeingArbiterValue implements DynamicValue {
+ instance;
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ Player controller = game.getPlayer(sourceAbility.getControllerId());
+ if (controller == null) {
+ return 0;
+ }
+ HashSet manaValues = new HashSet<>();
+ for (UUID cardId : controller.getGraveyard()) {
+ Card card = game.getCard(cardId);
+ if (card != null) {
+ manaValues.add(card.getManaValue());
+ }
+ }
+ return -manaValues.size();
+ }
+
+ @Override
+ public AllSeeingArbiterValue copy() {
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "-X";
+ }
+
+ @Override
+ public String getMessage() {
+ return "the number of different mana values among cards in your graveyard";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AlleyEvasion.java b/Mage.Sets/src/mage/cards/a/AlleyEvasion.java
index d7a65af78d6..af4449fefb0 100644
--- a/Mage.Sets/src/mage/cards/a/AlleyEvasion.java
+++ b/Mage.Sets/src/mage/cards/a/AlleyEvasion.java
@@ -26,8 +26,7 @@ public final class AlleyEvasion extends CardImpl {
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
// Return target creature you control to its owner's hand.
- Mode mode = new Mode();
- mode.addEffect(new ReturnToHandTargetEffect());
+ Mode mode = new Mode(new ReturnToHandTargetEffect());
mode.addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java
index c91c6d71cf6..b7aa8b37b59 100644
--- a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java
+++ b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java
@@ -21,7 +21,7 @@ public final class AlliedStrategies extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}");
// Domain - Target player draws a card for each basic land type among lands they control.
- this.getSpellAbility().addEffect(new DrawCardTargetEffect(new DomainValue(true)));
+ this.getSpellAbility().addEffect(new DrawCardTargetEffect(DomainValue.TARGET));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN);
this.getSpellAbility().addHint(DomainHint.instance);
diff --git a/Mage.Sets/src/mage/cards/a/AllureOfTheUnknown.java b/Mage.Sets/src/mage/cards/a/AllureOfTheUnknown.java
index ec7bd69d8f7..662e298721f 100644
--- a/Mage.Sets/src/mage/cards/a/AllureOfTheUnknown.java
+++ b/Mage.Sets/src/mage/cards/a/AllureOfTheUnknown.java
@@ -12,9 +12,9 @@ import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetOpponent;
+import mage.util.CardUtil;
import java.util.UUID;
-import mage.ApprovingObject;
/**
* @author TheElk801
@@ -69,7 +69,7 @@ class AllureOfTheUnknownEffect extends OneShotEffect {
return player.moveCards(cards, Zone.HAND, source, game);
}
TargetOpponent targetOpponent = new TargetOpponent(true);
- if (!player.choose(outcome, targetOpponent, source.getSourceId(), game)) {
+ if (!player.choose(outcome, targetOpponent, source, game)) {
return false;
}
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
@@ -85,12 +85,7 @@ class AllureOfTheUnknownEffect extends OneShotEffect {
cards.remove(card);
}
player.moveCards(cards, Zone.HAND, source, game);
- if (opponent.chooseUse(outcome, "Cast the exiled card without paying its mana cost?", source, game)) {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- opponent.cast(opponent.chooseAbilityForCast(card, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- }
+ CardUtil.castSpellWithAttributesForFree(opponent, source, game, card);
return true;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/a/Alms.java b/Mage.Sets/src/mage/cards/a/Alms.java
index db16df42257..bf6b4c84e4e 100644
--- a/Mage.Sets/src/mage/cards/a/Alms.java
+++ b/Mage.Sets/src/mage/cards/a/Alms.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileTopCardOfGraveyardCost;
@@ -11,21 +9,23 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class Alms extends CardImpl {
public Alms(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
// {1}, Exile the top card of your graveyard: Prevent the next 1 damage that would be dealt to target creature this turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageToTargetEffect(Duration.EndOfTurn, 1), new GenericManaCost(1));
- ability.addCost(new ExileTopCardOfGraveyardCost(1));
+ Ability ability = new SimpleActivatedAbility(
+ new PreventDamageToTargetEffect(Duration.EndOfTurn, 1), new GenericManaCost(1)
+ );
+ ability.addCost(new ExileTopCardOfGraveyardCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AlmsOfTheVein.java b/Mage.Sets/src/mage/cards/a/AlmsOfTheVein.java
index 4a8a016a147..54136ba48d3 100644
--- a/Mage.Sets/src/mage/cards/a/AlmsOfTheVein.java
+++ b/Mage.Sets/src/mage/cards/a/AlmsOfTheVein.java
@@ -25,7 +25,7 @@ public final class AlmsOfTheVein extends CardImpl {
this.getSpellAbility().addTarget(new TargetOpponent());
// Madness {B}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{B}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{B}")));
}
private AlmsOfTheVein(final AlmsOfTheVein card) {
diff --git a/Mage.Sets/src/mage/cards/a/AlpineHoundmaster.java b/Mage.Sets/src/mage/cards/a/AlpineHoundmaster.java
index fa9269902e5..13cab130e38 100644
--- a/Mage.Sets/src/mage/cards/a/AlpineHoundmaster.java
+++ b/Mage.Sets/src/mage/cards/a/AlpineHoundmaster.java
@@ -1,25 +1,24 @@
package mage.cards.a;
import mage.MageInt;
-import mage.MageObject;
-import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.dynamicvalue.common.StaticValue;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
-import mage.cards.*;
-import mage.constants.*;
+import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterAttackingCreature;
import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.mageobject.AnotherPredicate;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.common.TargetCardInLibrary;
+import mage.filter.predicate.mageobject.NamePredicate;
+import mage.target.common.TargetCardWithDifferentNameInLibrary;
import java.util.UUID;
@@ -29,9 +28,15 @@ import java.util.UUID;
public final class AlpineHoundmaster extends CardImpl {
private static final FilterAttackingCreature filter = new FilterAttackingCreature("other attacking creatures");
+ private static final FilterCard filter2
+ = new FilterCard("card named Alpine Watchdog and/or a card named Igneous Cur");
static {
filter.add(AnotherPredicate.instance);
+ filter2.add(Predicates.or(
+ new NamePredicate("Alpine Watchdog"),
+ new NamePredicate("Igneous Cur")
+ ));
}
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter, null);
@@ -45,10 +50,14 @@ public final class AlpineHoundmaster extends CardImpl {
this.toughness = new MageInt(2);
// When Alpine Houndmaster enters the battlefield, you may search your library for a card named Alpine Watchdog and/or a card named Igneous Cur, reveal them, put them into your hand, then shuffle your library.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new AlpineHoundmasterEffect(), true));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(
+ new TargetCardWithDifferentNameInLibrary(0, 2, filter2), true, true
+ ).setText("search your library for a card named Alpine Watchdog and/or a card named Igneous Cur, reveal them, put them into your hand, then shuffle"), true));
// Whenever Alpine Houndmaster attacks, it gets +X/+0 until end of turn, where X is the number of other attacking creatures.
- this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(xValue, StaticValue.get(0), Duration.EndOfTurn, true, "it"), false));
+ this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(
+ xValue, StaticValue.get(0), Duration.EndOfTurn, true, "it"
+ ), false));
}
private AlpineHoundmaster(final AlpineHoundmaster card) {
@@ -60,78 +69,3 @@ public final class AlpineHoundmaster extends CardImpl {
return new AlpineHoundmaster(this);
}
}
-
-class AlpineHoundmasterEffect extends OneShotEffect {
-
- AlpineHoundmasterEffect() {
- super(Outcome.Benefit);
- staticText = "search your library for a card named Alpine Watchdog and/or a card named Igneous Cur, " +
- "reveal them, put them into your hand, then shuffle";
- }
-
- private AlpineHoundmasterEffect(final AlpineHoundmasterEffect effect) {
- super(effect);
- }
-
- @Override
- public AlpineHoundmasterEffect copy() {
- return new AlpineHoundmasterEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
- if (player == null) {
- return false;
- }
- TargetCardInLibrary target = new AlpineHoundmasterTarget();
- player.searchLibrary(target, source, game);
- Cards cards = new CardsImpl(target.getTargets());
- player.revealCards(source, cards, game);
- player.moveCards(cards, Zone.HAND, source, game);
- player.shuffleLibrary(source, game);
- return true;
- }
-}
-
-class AlpineHoundmasterTarget extends TargetCardInLibrary {
-
- private static final FilterCard filter
- = new FilterCard("card named Alpine Watchdog and/or a card named Igneous Cur");
-
- static {
- filter.add(Predicates.or(
- new NamePredicate("Alpine Watchdog"),
- new NamePredicate("Igneous Cur")
- ));
- }
-
- AlpineHoundmasterTarget() {
- super(0, 2, filter);
- }
-
- private AlpineHoundmasterTarget(final AlpineHoundmasterTarget target) {
- super(target);
- }
-
- @Override
- public AlpineHoundmasterTarget copy() {
- return new AlpineHoundmasterTarget(this);
- }
-
- @Override
- public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
- if (!super.canTarget(controllerId, id, source, game)) {
- return false;
- }
- Card card = game.getCard(id);
- if (card == null) {
- return false;
- }
- return this.getTargets()
- .stream()
- .map(game::getCard)
- .map(MageObject::getName)
- .noneMatch(card.getName()::equals);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/a/AlrundGodOfTheCosmos.java b/Mage.Sets/src/mage/cards/a/AlrundGodOfTheCosmos.java
index 35b4748f591..73f77296623 100644
--- a/Mage.Sets/src/mage/cards/a/AlrundGodOfTheCosmos.java
+++ b/Mage.Sets/src/mage/cards/a/AlrundGodOfTheCosmos.java
@@ -50,7 +50,7 @@ public final class AlrundGodOfTheCosmos extends ModalDoubleFacesCard {
// Alrund gets +1/+1 for each card in your hand and each foretold card you own in exile.
Effect effect = new BoostSourceEffect(AlrundGodOfTheCosmosValue.instance, AlrundGodOfTheCosmosValue.instance, Duration.EndOfGame);
- effect.setText("Alrund gets +1/+1 for each card in your hand and each foretold card you own in exile.");
+ effect.setText("{this} gets +1/+1 for each card in your hand and each foretold card you own in exile.");
Ability ability = new SimpleStaticAbility(effect);
this.getLeftHalfCard().addAbility(ability);
@@ -89,7 +89,7 @@ class AlrundGodOfTheCosmosEffect extends OneShotEffect {
public AlrundGodOfTheCosmosEffect() {
super(Outcome.Neutral);
- staticText = ", then reveal the top two cards of your library. Put all cards revealed this way of the chosen type into your hand and the rest on the bottom of your library in any order";
+ staticText = ", then reveal the top two cards of your library. Put all cards of the chosen type revealed this way into your hand and the rest on the bottom of your library in any order";
}
public AlrundGodOfTheCosmosEffect(final AlrundGodOfTheCosmosEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/a/AlrundsEpiphany.java b/Mage.Sets/src/mage/cards/a/AlrundsEpiphany.java
index 9a3b9216d56..bf9a33a0930 100644
--- a/Mage.Sets/src/mage/cards/a/AlrundsEpiphany.java
+++ b/Mage.Sets/src/mage/cards/a/AlrundsEpiphany.java
@@ -7,7 +7,7 @@ import mage.abilities.keyword.ForetellAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.game.permanent.token.OwlToken;
+import mage.game.permanent.token.BlueBirdToken;
import java.util.UUID;
@@ -20,7 +20,7 @@ public final class AlrundsEpiphany extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}{U}");
// Create two 1/1 blue Bird creature tokens with flying. Take an extra turn after this one. Exile Alrund's Epiphany.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new OwlToken(), 2));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new BlueBirdToken(), 2));
this.getSpellAbility().addEffect(new AddExtraTurnControllerEffect());
this.getSpellAbility().addEffect(new ExileSpellEffect());
diff --git a/Mage.Sets/src/mage/cards/a/AltarOfTheGoyf.java b/Mage.Sets/src/mage/cards/a/AltarOfTheGoyf.java
index a590ba3de37..35d094861fc 100644
--- a/Mage.Sets/src/mage/cards/a/AltarOfTheGoyf.java
+++ b/Mage.Sets/src/mage/cards/a/AltarOfTheGoyf.java
@@ -36,7 +36,7 @@ public final class AltarOfTheGoyf extends CardImpl {
CardTypesInGraveyardCount.ALL,
Duration.EndOfTurn, true
).setText("it gets +X/+X until end of turn, where X is " +
- "the number of card types among cards in all graveyards.")).addHint(CardTypesInGraveyardHint.ALL));
+ "the number of card types among cards in all graveyards."), true, false).addHint(CardTypesInGraveyardHint.ALL));
// Lhurgoyf creatures you control have trample.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
diff --git a/Mage.Sets/src/mage/cards/a/AltarOfTheLost.java b/Mage.Sets/src/mage/cards/a/AltarOfTheLost.java
index 8b674e5c8e1..a014e2343e6 100644
--- a/Mage.Sets/src/mage/cards/a/AltarOfTheLost.java
+++ b/Mage.Sets/src/mage/cards/a/AltarOfTheLost.java
@@ -71,8 +71,8 @@ class AltarOfTheLostManaCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
MageObject object = game.getObject(source.getSourceId());
- if (game != null && game.inCheckPlayableState()) {
- if (object instanceof Card && game.getState().getZone(source.getSourceId()).equals(Zone.GRAVEYARD)) {
+ if (game.inCheckPlayableState()) {
+ if (object instanceof Card && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
for (Ability ability : ((Card) object).getAbilities(game)) {
if (ability instanceof FlashbackAbility) {
return true;
diff --git a/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java b/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java
index 65390caee24..5fe3acac163 100644
--- a/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java
+++ b/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java
@@ -35,7 +35,7 @@ public final class AmbuscadeShaman extends CardImpl {
));
// Dash {3}{B} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.));
- this.addAbility(new DashAbility(this, "{3}{B}"));
+ this.addAbility(new DashAbility("{3}{B}"));
}
private AmbuscadeShaman(final AmbuscadeShaman card) {
diff --git a/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java
index 9125e8fc0f8..6d346dc5f56 100644
--- a/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java
+++ b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.CanBeYourCommanderAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetForSourceEffect;
@@ -46,7 +45,7 @@ public class AminatouTheFateshifter extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AMINATOU);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: Draw a card, then put a card from your hand on top of your library.
Ability ability = new LoyaltyAbility(new AminatouPlusEffect(), +1);
@@ -106,7 +105,7 @@ class AminatouPlusEffect extends OneShotEffect {
private boolean putOnLibrary(Player player, Ability source, Game game) {
TargetCardInHand target = new TargetCardInHand();
- if (target.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.ReturnToHand, target, source, game);
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/a/AminatousAugury.java b/Mage.Sets/src/mage/cards/a/AminatousAugury.java
index 53f6bb3a638..25cb90a5c7a 100644
--- a/Mage.Sets/src/mage/cards/a/AminatousAugury.java
+++ b/Mage.Sets/src/mage/cards/a/AminatousAugury.java
@@ -37,7 +37,8 @@ public class AminatousAugury extends CardImpl {
public AminatousAugury(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{U}{U}");
- // Exile the top eight cards of your library. You may put a land card from among them onto the battlefield.
+ // Exile the top eight cards of your library.
+ // You may put a land card from among them onto the battlefield.
// Until end of turn, for each nonland card type, you may cast a card of that type from among the exiled cards
// without paying its mana cost.
this.getSpellAbility().addEffect(new AminatousAuguryEffect());
@@ -58,9 +59,10 @@ class AminatousAuguryEffect extends OneShotEffect {
public AminatousAuguryEffect() {
super(Outcome.PlayForFree);
- staticText = "Exile the top eight cards of your library. You may put a land card from among them onto the"
- + " battlefield. Until end of turn, for each nonland card type, you may cast a card of that type from"
- + " among the exiled cards without paying its mana cost.";
+ staticText = "Exile the top eight cards of your library. " +
+ "You may put a land card from among them onto the battlefield. " +
+ "Until end of turn, for each nonland card type, " +
+ "you may cast a card of that type from among the exiled cards without paying its mana cost.";
}
public AminatousAuguryEffect(final AminatousAuguryEffect effect) {
@@ -74,41 +76,42 @@ class AminatousAuguryEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
-
Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false; }
+
MageObject sourceObject = source.getSourceObject(game);
- if (controller != null && sourceObject != null) {
- // move cards from library to exile
- controller.moveCardsToExile(controller.getLibrary().getTopCards(game, 8), source, game, true, source.getSourceId(), CardUtil.createObjectRealtedWindowTitle(source, game, null));
- ExileZone auguryExileZone = game.getExile().getExileZone(source.getSourceId());
- if (auguryExileZone == null) {
- return true;
- }
- Cards cardsToCast = new CardsImpl();
- cardsToCast.addAll(auguryExileZone.getCards(game));
- // put a land card from among them onto the battlefield
- TargetCard target = new TargetCard(
- Zone.EXILED,
- StaticFilters.FILTER_CARD_LAND_A
- );
- if (cardsToCast.count(StaticFilters.FILTER_CARD_LAND, game) > 0) {
- if (controller.chooseUse(Outcome.PutLandInPlay, "Put a land from among the exiled cards into play?", source, game)) {
- if (controller.choose(Outcome.PutLandInPlay, cardsToCast, target, game)) {
- Card card = cardsToCast.get(target.getFirstTarget(), game);
- if (card != null) {
- cardsToCast.remove(card);
- controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
- }
- }
+ if (sourceObject == null) { return false; }
+
+ // move cards from library to exile
+ controller.moveCardsToExile(controller.getLibrary().getTopCards(game, 8), source, game, true, source.getSourceId(), CardUtil.createObjectRealtedWindowTitle(source, game, null));
+ ExileZone auguryExileZone = game.getExile().getExileZone(source.getSourceId());
+ if (auguryExileZone == null) { return true; }
+
+ Cards cardsToCast = new CardsImpl();
+ cardsToCast.addAll(auguryExileZone.getCards(game));
+
+ // put a land card from among them onto the battlefield
+ TargetCard target = new TargetCard(Zone.EXILED, StaticFilters.FILTER_CARD_LAND_A);
+
+ if (cardsToCast.count(StaticFilters.FILTER_CARD_LAND, game) == 0) { return true; }
+
+ if (controller.chooseUse(Outcome.PutLandInPlay, "Put a land from among the exiled cards into play?", source, game)) {
+ if (controller.choose(Outcome.PutLandInPlay, cardsToCast, target, game)) {
+ Card card = cardsToCast.get(target.getFirstTarget(), game);
+ if (card != null) {
+ cardsToCast.remove(card);
+ controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
}
}
- for (Card card : cardsToCast.getCards(StaticFilters.FILTER_CARD_NON_LAND, game)) {
- AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect();
- effect.setTargetPointer(new FixedTarget(card, game));
- game.addEffect(effect, source);
- }
}
- return false;
+
+ for (Card card : cardsToCast.getCards(StaticFilters.FILTER_CARD_NON_LAND, game)) {
+ AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect();
+ effect.setTargetPointer(new FixedTarget(card, game));
+ game.addEffect(effect, source);
+ }
+ // TODO: I think this should be returning true
+ return true;
}
}
@@ -136,51 +139,54 @@ class AminatousAuguryCastFromExileEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Player player = game.getPlayer(affectedControllerId);
- EnumSet usedCardTypes = EnumSet.noneOf(CardType.class);
+ if (player == null) { return false; }
- if (game.getState().getValue(source.getSourceId().toString() + "cardTypes") != null) {
+ if (!affectedControllerId.equals(source.getControllerId())) { return false; }
+
+ EnumSet usedCardTypes;
+ if (game.getState().getValue(source.getSourceId().toString() + "cardTypes") == null) {
+ // The effect has not been applied fully yet, so there are no previously cast times
+ usedCardTypes = EnumSet.noneOf(CardType.class);
+ } else {
usedCardTypes = (EnumSet) game.getState().getValue(source.getSourceId().toString() + "cardTypes");
}
- if (player != null
- && objectId != null
- && objectId.equals(getTargetPointer().getFirst(game, source))
- && affectedControllerId.equals(source.getControllerId())) {
- Card card = game.getCard(objectId);
- if (card != null
- && game.getState().getZone(objectId) == Zone.EXILED) {
- EnumSet unusedCardTypes = EnumSet.noneOf(CardType.class);
- for (CardType cardT : card.getCardType(game)) {
- if (!usedCardTypes.contains(cardT)) {
- unusedCardTypes.add(cardT);
- }
- }
- if (!unusedCardTypes.isEmpty()) {
- if (!game.inCheckPlayableState()) { // some actions may not be done while the game only checks if a card can be cast
- // Select the card type to consume and remove all not seleczted card types
- if (unusedCardTypes.size() > 1) {
- Choice choice = new ChoiceImpl(true);
- choice.setMessage("Which card type do you want to consume?");
- Set choices = choice.getChoices();
- for (CardType cardType : unusedCardTypes) {
- choices.add(cardType.toString());
- }
- player.choose(Outcome.Detriment, choice, game);
- for (Iterator iterator = unusedCardTypes.iterator(); iterator.hasNext();) {
- CardType next = iterator.next();
- if (!next.toString().equals(choice.getChoice())) {
- iterator.remove();
- }
- }
- usedCardTypes.add(CardType.fromString(choice.getChoice()));
- }
- usedCardTypes.addAll(unusedCardTypes);
- game.getState().setValue(source.getSourceId().toString() + "cardTypes", usedCardTypes);
- }
- player.setCastSourceIdWithAlternateMana(objectId, null, card.getSpellAbility().getCosts());
- return true;
- }
+
+ if (objectId == null || !objectId.equals(getTargetPointer().getFirst(game, source))) { return false; }
+
+ if (game.getState().getZone(objectId) != Zone.EXILED) { return false; }
+
+ Card card = game.getCard(objectId);
+ if (card == null) { return false; }
+
+ // Figure out which of the current card's types have not been cast before
+ EnumSet unusedCardTypes = EnumSet.noneOf(CardType.class);
+ for (CardType cardT : card.getCardType(game)) {
+ if (!usedCardTypes.contains(cardT)) {
+ unusedCardTypes.add(cardT);
}
}
- return false;
+
+ // The current card has only card types that have been cast before, so it can't be cast
+ if (unusedCardTypes.isEmpty()) { return false; }
+
+ // some actions may not be done while the game only checks if a card can be cast
+ if (!game.inCheckPlayableState()) {
+ // Select the card type to consume and remove all not selected card types
+ if (unusedCardTypes.size() > 1) {
+ Choice choice = new ChoiceImpl(true);
+ choice.setMessage("Which card type do you want to consume?");
+ Set choices = choice.getChoices();
+ for (CardType cardType : unusedCardTypes) {
+ choices.add(cardType.toString());
+ }
+ player.choose(Outcome.Detriment, choice, game);
+ unusedCardTypes.removeIf(next -> !next.toString().equals(choice.getChoice()));
+ usedCardTypes.add(CardType.fromString(choice.getChoice()));
+ }
+ usedCardTypes.addAll(unusedCardTypes);
+ game.getState().setValue(source.getSourceId().toString() + "cardTypes", usedCardTypes);
+ }
+ player.setCastSourceIdWithAlternateMana(objectId, null, card.getSpellAbility().getCosts());
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java b/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java
index 00e7a996f11..92ff67533d3 100644
--- a/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java
+++ b/Mage.Sets/src/mage/cards/a/AmuletOfSafekeeping.java
@@ -82,7 +82,7 @@ class AmuletOfSafekeepingTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
if (event.getTargetId().equals(getControllerId())
- && filter.match(stackObject, getSourceId(), getControllerId(), game)) {
+ && filter.match(stackObject, getControllerId(), this, game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(stackObject.getId(), game));
}
diff --git a/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java b/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java
index 03058860c26..383366fa4f1 100644
--- a/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java
+++ b/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java
@@ -13,6 +13,7 @@ import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.GameLog;
+import java.util.Optional;
import java.util.UUID;
/**
@@ -75,10 +76,12 @@ class AmuletOfVigorTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
// that triggers depends on stack order, so make each trigger unique with extra info
- String triggeredInfo = "";
- if (this.getEffects().get(0).getTargetPointer() != null) {
- triggeredInfo = " Triggered permanent: " + this.getEffects().get(0).getTargetPointer().getData("triggeredName") + ".";
- }
- return "Whenever a permanent enters the battlefield tapped and under your control, untap it." + triggeredInfo;
+ return "Whenever a permanent enters the battlefield tapped and under your control, untap it."
+ + Optional
+ .of(this.getEffects().get(0).getTargetPointer())
+ .map(targetPointer -> targetPointer.getData("triggeredName"))
+ .filter(s -> s != null && !s.isEmpty())
+ .map(s -> " Triggered permanent: " + s)
+ .orElse("");
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AnHavvaConstable.java b/Mage.Sets/src/mage/cards/a/AnHavvaConstable.java
index 1daa50c5130..98d3da2f8a6 100644
--- a/Mage.Sets/src/mage/cards/a/AnHavvaConstable.java
+++ b/Mage.Sets/src/mage/cards/a/AnHavvaConstable.java
@@ -61,16 +61,17 @@ class AnHavvaConstableEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- MageObject mageObject = game.getObject(source.getSourceId());
- if (mageObject != null) {
- FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
- filter.add(new ColorPredicate(ObjectColor.GREEN));
- int number = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
- mageObject.getToughness().setValue(number + 1);
- return true;
- }
- }
- return false;
+ if (controller == null) { return false; }
+
+ MageObject mageObject = game.getObject(source.getSourceId());
+ if (mageObject == null) { return false; }
+
+ FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
+ filter.add(new ColorPredicate(ObjectColor.GREEN));
+ int numberOfGreenCreatures = game.getBattlefield().count(filter, source.getSourceId(), source, game);
+
+ mageObject.getToughness().setValue(1 + numberOfGreenCreatures);
+
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AnHavvaInn.java b/Mage.Sets/src/mage/cards/a/AnHavvaInn.java
index 0d81cc7e55a..ffab9055d57 100644
--- a/Mage.Sets/src/mage/cards/a/AnHavvaInn.java
+++ b/Mage.Sets/src/mage/cards/a/AnHavvaInn.java
@@ -59,7 +59,7 @@ class AnHavvaInnEffect extends OneShotEffect {
if (player != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
filter.add(new ColorPredicate(ObjectColor.GREEN));
- int greenCreatures = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ int greenCreatures = game.getBattlefield().count(filter, source.getControllerId(), source, game);
player.gainLife(greenCreatures+1, game, source);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/a/AnOfferYouCantRefuse.java b/Mage.Sets/src/mage/cards/a/AnOfferYouCantRefuse.java
new file mode 100644
index 00000000000..37ee35918ea
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AnOfferYouCantRefuse.java
@@ -0,0 +1,66 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.token.TreasureToken;
+import mage.game.stack.Spell;
+import mage.target.TargetSpell;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AnOfferYouCantRefuse extends CardImpl {
+
+ public AnOfferYouCantRefuse(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
+
+ // Counter target noncreature spell. Its controller creates two Treasure tokens.
+ this.getSpellAbility().addEffect(new AnOfferYouCantRefuseEffect());
+ this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_NON_CREATURE));
+ }
+
+ private AnOfferYouCantRefuse(final AnOfferYouCantRefuse card) {
+ super(card);
+ }
+
+ @Override
+ public AnOfferYouCantRefuse copy() {
+ return new AnOfferYouCantRefuse(this);
+ }
+}
+
+class AnOfferYouCantRefuseEffect extends OneShotEffect {
+
+ AnOfferYouCantRefuseEffect() {
+ super(Outcome.Benefit);
+ staticText = "counter target noncreature spell. Its controller creates two Treasure tokens";
+ }
+
+ private AnOfferYouCantRefuseEffect(final AnOfferYouCantRefuseEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AnOfferYouCantRefuseEffect copy() {
+ return new AnOfferYouCantRefuseEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Spell spell = game.getSpell(getTargetPointer().getFirst(game, source));
+ if (spell == null) {
+ return false;
+ }
+ game.getStack().counter(spell.getId(), source, game);;
+ new TreasureToken().putOntoBattlefield(2, game, source, spell.getControllerId());
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/Anathemancer.java b/Mage.Sets/src/mage/cards/a/Anathemancer.java
index be2db64c8e7..5785ab161bc 100644
--- a/Mage.Sets/src/mage/cards/a/Anathemancer.java
+++ b/Mage.Sets/src/mage/cards/a/Anathemancer.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -14,33 +12,35 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.SuperType;
-import mage.filter.common.FilterLandPermanent;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.permanent.ControllerIdPredicate;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.target.TargetPlayer;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class Anathemancer extends CardImpl {
public Anathemancer(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}");
this.subtype.add(SubType.ZOMBIE);
this.subtype.add(SubType.WIZARD);
-
+
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Anathemancer enters the battlefield, it deals damage to target player equal to the number of nonbasic lands that player controls.
- EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(new AnathemancerCount(), "it"));
+ EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(
+ new DamageTargetEffect(AnathemancerCount.instance, "it")
+ .setText("it deals damage to target player equal to the number of nonbasic lands that player controls")
+ );
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
+
// Unearth {5}{B}{R}
- this.addAbility(new UnearthAbility(new ManaCostsImpl("{5}{B}{R}")));
+ this.addAbility(new UnearthAbility(new ManaCostsImpl<>("{5}{B}{R}")));
}
private Anathemancer(final Anathemancer card) {
@@ -53,29 +53,29 @@ public final class Anathemancer extends CardImpl {
}
}
-class AnathemancerCount implements DynamicValue {
+enum AnathemancerCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
if (sourceAbility.getFirstTarget() == null) {
return 0;
}
-
- FilterLandPermanent filter = new FilterLandPermanent();
- filter.add(Predicates.not(SuperType.BASIC.getPredicate()));
- filter.add(new ControllerIdPredicate(sourceAbility.getFirstTarget()));
-
- return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game);
+ return game.getBattlefield().count(
+ StaticFilters.FILTER_LANDS_NONBASIC,
+ sourceAbility.getControllerId(),
+ sourceAbility, game
+ );
}
@Override
public AnathemancerCount copy() {
- return new AnathemancerCount();
+ return this;
}
@Override
public String toString() {
- return "1";
+ return "";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AncestralMemories.java b/Mage.Sets/src/mage/cards/a/AncestralMemories.java
index 031b0d8afdc..74f1b83ba39 100644
--- a/Mage.Sets/src/mage/cards/a/AncestralMemories.java
+++ b/Mage.Sets/src/mage/cards/a/AncestralMemories.java
@@ -1,12 +1,10 @@
package mage.cards.a;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.filter.StaticFilters;
import java.util.UUID;
@@ -19,8 +17,7 @@ public final class AncestralMemories extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}{U}");
// Look at the top seven cards of your library. Put two of them into your hand and the rest into your graveyard.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(StaticValue.get(7), false, StaticValue.get(2),
- StaticFilters.FILTER_CARD, Zone.GRAVEYARD, false, false, false, Zone.HAND, false));
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(7, 2, PutCards.HAND, PutCards.GRAVEYARD));
}
private AncestralMemories(final AncestralMemories card) {
@@ -31,4 +28,4 @@ public final class AncestralMemories extends CardImpl {
public AncestralMemories copy() {
return new AncestralMemories(this);
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/a/AncestralVision.java b/Mage.Sets/src/mage/cards/a/AncestralVision.java
index a87862eb530..ee92ec5bb4a 100644
--- a/Mage.Sets/src/mage/cards/a/AncestralVision.java
+++ b/Mage.Sets/src/mage/cards/a/AncestralVision.java
@@ -22,7 +22,7 @@ public final class AncestralVision extends CardImpl {
this.color.setBlue(true);
// Suspend 4-{U}
- this.addAbility(new SuspendAbility(4, new ManaCostsImpl("U"), this));
+ this.addAbility(new SuspendAbility(4, new ManaCostsImpl<>("{U}"), this));
// Target player draws three cards.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DrawCardTargetEffect(3));
diff --git a/Mage.Sets/src/mage/cards/a/AncientBrassDragon.java b/Mage.Sets/src/mage/cards/a/AncientBrassDragon.java
new file mode 100644
index 00000000000..78fd2a68fdd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AncientBrassDragon.java
@@ -0,0 +1,88 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.common.FilterCreatureCard;
+import mage.filter.predicate.mageobject.ManaValuePredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetCardInGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AncientBrassDragon extends CardImpl {
+
+ public AncientBrassDragon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}");
+
+ this.subtype.add(SubType.ELDER);
+ this.subtype.add(SubType.DRAGON);
+ this.power = new MageInt(7);
+ this.toughness = new MageInt(6);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Ancient Brass Dragon deals combat damage to a player, roll a d20. When you do, put any number of target creature cards with mana value X or less from graveyards onto the battlefield under your control, where X is the result.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new AncientBrassDragonEffect(), false));
+ }
+
+ private AncientBrassDragon(final AncientBrassDragon card) {
+ super(card);
+ }
+
+ @Override
+ public AncientBrassDragon copy() {
+ return new AncientBrassDragon(this);
+ }
+}
+
+class AncientBrassDragonEffect extends OneShotEffect {
+
+ AncientBrassDragonEffect() {
+ super(Outcome.Benefit);
+ staticText = "roll a d20. When you do, put any number of target creature cards with mana value X " +
+ "or less from graveyards onto the battlefield under your control, where X is the result";
+ }
+
+ private AncientBrassDragonEffect(final AncientBrassDragonEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AncientBrassDragonEffect copy() {
+ return new AncientBrassDragonEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ int result = player.rollDice(outcome, source, game, 20);
+ FilterCard filter = new FilterCreatureCard("creature cards with mana value " + result + " or less");
+ filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, result));
+ ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
+ new ReturnFromGraveyardToBattlefieldTargetEffect(), false
+ );
+ ability.addTarget(new TargetCardInGraveyard(0, Integer.MAX_VALUE, filter));
+ game.fireReflexiveTriggeredAbility(ability, source);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AncientStirrings.java b/Mage.Sets/src/mage/cards/a/AncientStirrings.java
index b3ca0d48bec..137ad672c1b 100644
--- a/Mage.Sets/src/mage/cards/a/AncientStirrings.java
+++ b/Mage.Sets/src/mage/cards/a/AncientStirrings.java
@@ -1,14 +1,11 @@
-
-
package mage.cards.a;
import java.util.UUID;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorlessPredicate;
@@ -23,15 +20,12 @@ public final class AncientStirrings extends CardImpl {
filter.add(ColorlessPredicate.instance);
}
-
public AncientStirrings(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{G}");
// Look at the top five cards of your library. You may reveal a colorless card from among them and put it into your hand.
// Then put the rest on the bottom of your library in any order. (Cards with no colored mana in their mana costs are colorless. Lands are also colorless.)
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(StaticValue.get(5), false, StaticValue.get(1), filter, Zone.LIBRARY,
- false, true, false, Zone.HAND, true));
-
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(5, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY));
}
private AncientStirrings(final AncientStirrings card) {
@@ -42,5 +36,4 @@ public final class AncientStirrings extends CardImpl {
public AncientStirrings copy() {
return new AncientStirrings(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java
index d1740013eb4..37f3d1bdce0 100644
--- a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java
+++ b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java
@@ -8,7 +8,6 @@ import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.costs.common.ExertSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
@@ -56,15 +55,19 @@ public final class AngelOfCondemnation extends CardImpl {
this.addAbility(VigilanceAbility.getInstance());
// {2}{W}, {T}: Exile another target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AngelOfCondemnationExileUntilEOTEffect(), new ManaCostsImpl<>("{2}{W}"));
+ Ability ability = new SimpleActivatedAbility(
+ new AngelOfCondemnationExileUntilEOTEffect(), new ManaCostsImpl<>("{2}{W}")
+ );
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
// {2}{W}, {T}, Exert Angel of Condemnation: Exile another target creature until Angel of Condemnation leaves the battlefield.
- Effect effect = new ExileUntilSourceLeavesEffect("");
- effect.setText("Exile another target creature until {this} leaves the battlefield");
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{2}{W}"));
+ ability = new SimpleActivatedAbility(
+ new ExileUntilSourceLeavesEffect("")
+ .setText("Exile another target creature until {this} leaves the battlefield"),
+ new ManaCostsImpl<>("{2}{W}")
+ );
ability.addCost(new TapSourceCost());
ability.addCost(new ExertSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
@@ -86,10 +89,11 @@ class AngelOfCondemnationExileUntilEOTEffect extends OneShotEffect {
AngelOfCondemnationExileUntilEOTEffect() {
super(Outcome.Detriment);
- staticText = "exile another target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step";
+ staticText = "exile another target creature. Return that card to the battlefield " +
+ "under its owner's control at the beginning of the next end step";
}
- AngelOfCondemnationExileUntilEOTEffect(final AngelOfCondemnationExileUntilEOTEffect effect) {
+ private AngelOfCondemnationExileUntilEOTEffect(final AngelOfCondemnationExileUntilEOTEffect effect) {
super(effect);
}
@@ -97,18 +101,17 @@ class AngelOfCondemnationExileUntilEOTEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
- Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (controller != null && permanent != null && sourcePermanent != null) {
- if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source, game, Zone.BATTLEFIELD, true)) {
- //create delayed triggered ability
- Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
- effect.setText("return that card to the battlefield under its owner's control");
- effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
- game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
- return true;
- }
+ if (controller == null || permanent == null) {
+ return false;
}
- return false;
+ controller.moveCards(permanent, Zone.EXILED, source, game);
+ //create delayed triggered ability
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false)
+ .setText("return that card to the battlefield under its owner's control")
+ .setTargetPointer(new FixedTarget(source.getFirstTarget(), game))
+ ), source);
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java b/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java
index c8df87128b5..0b663bb191c 100644
--- a/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java
+++ b/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java
@@ -72,7 +72,7 @@ class AngelOfGlorysRiseEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Set toExile = new HashSet<>(game.getBattlefield()
- .getActivePermanents(new FilterCreaturePermanent(SubType.ZOMBIE, "Zombie"), source.getControllerId(), source.getSourceId(), game));
+ .getActivePermanents(new FilterCreaturePermanent(SubType.ZOMBIE, "Zombie"), source.getControllerId(), source, game));
controller.moveCards(toExile, Zone.EXILED, source, game);
FilterCreatureCard filterHuman = new FilterCreatureCard();
filterHuman.add(SubType.HUMAN.getPredicate());
diff --git a/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java b/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java
index 57d4f570450..f57e5744962 100644
--- a/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java
+++ b/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java
@@ -13,7 +13,7 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.predicate.mageobject.AnotherPredicate;
-import mage.target.common.TargetCardInGraveyardOrBattlefield;
+import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
import java.util.UUID;
import mage.filter.common.FilterCreatureCard;
@@ -49,7 +49,7 @@ public final class AngelOfSerenity extends CardImpl {
Ability ability = new EntersBattlefieldTriggeredAbility(
new ExileTargetForSourceEffect().setText(rule), true
);
- ability.addTarget(new TargetCardInGraveyardOrBattlefield(
+ ability.addTarget(new TargetCardInGraveyardBattlefieldOrStack(
0, 3, filterCreatureCard, filterCreaturePermanent
));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AngelOfSuffering.java b/Mage.Sets/src/mage/cards/a/AngelOfSuffering.java
new file mode 100644
index 00000000000..f9e1a194ec9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AngelOfSuffering.java
@@ -0,0 +1,86 @@
+package mage.cards.a;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.players.Player;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class AngelOfSuffering extends CardImpl {
+
+ public AngelOfSuffering(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
+
+ this.subtype.add(SubType.NIGHTMARE);
+ this.subtype.add(SubType.ANGEL);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // If damage would be dealt to you, prevent that damage and mill twice that many cards.
+ this.addAbility(new SimpleStaticAbility(new AngelOfSufferingEffect()));
+ }
+
+ private AngelOfSuffering(final AngelOfSuffering card) {
+ super(card);
+ }
+
+ @Override
+ public AngelOfSuffering copy() {
+ return new AngelOfSuffering(this);
+ }
+}
+
+class AngelOfSufferingEffect extends ReplacementEffectImpl {
+
+ public AngelOfSufferingEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.PreventDamage);
+ this.staticText = "If damage would be dealt to you, prevent that damage and mill twice that many cards";
+ }
+
+ private AngelOfSufferingEffect(final AngelOfSufferingEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AngelOfSufferingEffect copy() {
+ return new AngelOfSufferingEffect(this);
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ int cardsToMill = event.getAmount() * 2;
+ game.preventDamage(event, source, game, Integer.MAX_VALUE);
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null) {
+ controller.millCards(cardsToMill, source, game);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ return event.getTargetId().equals(source.getControllerId());
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AngelheartVial.java b/Mage.Sets/src/mage/cards/a/AngelheartVial.java
index e3dd5ea119e..c02b3c43049 100644
--- a/Mage.Sets/src/mage/cards/a/AngelheartVial.java
+++ b/Mage.Sets/src/mage/cards/a/AngelheartVial.java
@@ -1,7 +1,6 @@
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility;
@@ -21,14 +20,15 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class AngelheartVial extends CardImpl {
public AngelheartVial(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
// Whenever you're dealt damage, you may put that many charge counters on Angelheart Vial.
this.addAbility(new AngelheartVialTriggeredAbility());
@@ -36,8 +36,8 @@ public final class AngelheartVial extends CardImpl {
// {2}, {tap}, Remove four charge counters from Angelheart Vial: You gain 2 life and draw a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
- ability.addCost(new RemoveCountersSourceCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(4))));
- ability.addEffect(new DrawCardSourceControllerEffect(1));
+ ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(4)));
+ ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and"));
this.addAbility(ability);
}
@@ -82,7 +82,7 @@ class AngelheartVialTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever you are dealt damage, you may put that many charge counters on {this}.";
+ return "Whenever you're dealt damage, you may put that many charge counters on {this}.";
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AngelicExaltation.java b/Mage.Sets/src/mage/cards/a/AngelicExaltation.java
index ef1494214ff..fa1459097ca 100644
--- a/Mage.Sets/src/mage/cards/a/AngelicExaltation.java
+++ b/Mage.Sets/src/mage/cards/a/AngelicExaltation.java
@@ -24,7 +24,7 @@ public final class AngelicExaltation extends CardImpl {
CreaturesYouControlCount.instance,
CreaturesYouControlCount.instance,
Duration.EndOfTurn, true
- ).setText("it gets +X/+X until end of turn, where X is the number of creatures you control")).addHint(CreaturesYouControlHint.instance));
+ ).setText("it gets +X/+X until end of turn, where X is the number of creatures you control"), true, false).addHint(CreaturesYouControlHint.instance));
}
private AngelicExaltation(final AngelicExaltation card) {
diff --git a/Mage.Sets/src/mage/cards/a/AngelicObserver.java b/Mage.Sets/src/mage/cards/a/AngelicObserver.java
new file mode 100644
index 00000000000..b2722037366
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AngelicObserver.java
@@ -0,0 +1,57 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AngelicObserver extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent(SubType.CITIZEN, "Citizen you control");
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
+ private static final Hint hint = new ValueHint("Citizens you control", xValue);
+
+ public AngelicObserver(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}");
+
+ this.subtype.add(SubType.ANGEL);
+ this.subtype.add(SubType.ADVISOR);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // This spell costs {1} less to cast for each Citizen you control.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL,
+ new SpellCostReductionForEachSourceEffect(1, xValue).setCanWorksOnStackOnly(true)
+ ).setRuleAtTheTop(true).addHint(hint));
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+ }
+
+ private AngelicObserver(final AngelicObserver card) {
+ super(card);
+ }
+
+ @Override
+ public AngelicObserver copy() {
+ return new AngelicObserver(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AngelicSleuth.java b/Mage.Sets/src/mage/cards/a/AngelicSleuth.java
new file mode 100644
index 00000000000..a67e6ce6b3c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AngelicSleuth.java
@@ -0,0 +1,55 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility;
+import mage.abilities.effects.keyword.InvestigateEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.mageobject.AnotherPredicate;
+import mage.filter.predicate.permanent.CounterAnyPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AngelicSleuth extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent("another permanent you control");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(CounterAnyPredicate.instance);
+ }
+
+ public AngelicSleuth(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
+
+ this.subtype.add(SubType.ANGEL);
+ this.subtype.add(SubType.ADVISOR);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever another permanent you control leaves the battlefield, if it had counters on it, investigate.
+ this.addAbility(new LeavesBattlefieldAllTriggeredAbility(
+ new InvestigateEffect().setText("if it had counters on it, investigate"), filter, false
+ ));
+ }
+
+ private AngelicSleuth(final AngelicSleuth card) {
+ super(card);
+ }
+
+ @Override
+ public AngelicSleuth copy() {
+ return new AngelicSleuth(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AnglerTurtle.java b/Mage.Sets/src/mage/cards/a/AnglerTurtle.java
index dc12033da69..88ff0c06993 100644
--- a/Mage.Sets/src/mage/cards/a/AnglerTurtle.java
+++ b/Mage.Sets/src/mage/cards/a/AnglerTurtle.java
@@ -6,9 +6,9 @@ import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.common.FilterCreaturePermanent;
-import mage.watchers.common.AttackedThisTurnWatcher;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
import java.util.UUID;
@@ -17,12 +17,6 @@ import java.util.UUID;
*/
public final class AnglerTurtle extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public AnglerTurtle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
this.subtype.add(SubType.TURTLE);
@@ -33,8 +27,7 @@ public final class AnglerTurtle extends CardImpl {
this.addAbility(HexproofAbility.getInstance());
// Creatures your opponents control attack each combat if able
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AttacksIfAbleAllEffect(filter, Duration.WhileOnBattlefield)),
- new AttackedThisTurnWatcher());
+ this.addAbility(new SimpleStaticAbility(new AttacksIfAbleAllEffect(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES)));
}
private AnglerTurtle(final AnglerTurtle card) {
diff --git a/Mage.Sets/src/mage/cards/a/AngrathCaptainOfChaos.java b/Mage.Sets/src/mage/cards/a/AngrathCaptainOfChaos.java
index 9827fa66844..57c302b73f5 100644
--- a/Mage.Sets/src/mage/cards/a/AngrathCaptainOfChaos.java
+++ b/Mage.Sets/src/mage/cards/a/AngrathCaptainOfChaos.java
@@ -1,7 +1,6 @@
package mage.cards.a;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.keyword.AmassEffect;
@@ -26,7 +25,7 @@ public final class AngrathCaptainOfChaos extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGRATH);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// Creatures you control have menace.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
diff --git a/Mage.Sets/src/mage/cards/a/AngrathMinotaurPirate.java b/Mage.Sets/src/mage/cards/a/AngrathMinotaurPirate.java
index 69a0669e360..33a1590efc4 100644
--- a/Mage.Sets/src/mage/cards/a/AngrathMinotaurPirate.java
+++ b/Mage.Sets/src/mage/cards/a/AngrathMinotaurPirate.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
@@ -37,7 +36,7 @@ public final class AngrathMinotaurPirate extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGRATH);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +2: Angrath, Minotaur Pirate deals 1 damage to target opponent and each creature that player controls.
Effects effects1 = new Effects();
diff --git a/Mage.Sets/src/mage/cards/a/AngrathTheFlameChained.java b/Mage.Sets/src/mage/cards/a/AngrathTheFlameChained.java
index 294fdd7e7aa..b9de629fde2 100644
--- a/Mage.Sets/src/mage/cards/a/AngrathTheFlameChained.java
+++ b/Mage.Sets/src/mage/cards/a/AngrathTheFlameChained.java
@@ -5,7 +5,6 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
@@ -41,7 +40,7 @@ public final class AngrathTheFlameChained extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGRATH);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Each opponent discards a card and loses 2 life.
LoyaltyAbility ability = new LoyaltyAbility(new DiscardEachPlayerEffect(TargetController.OPPONENT), 1);
diff --git a/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java b/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java
index 87bb6c250f6..8fba5e3f25f 100644
--- a/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java
+++ b/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java
@@ -57,7 +57,7 @@ class AnimalMagnetismEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject != null && controller != null) {
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
if (!cards.isEmpty()) {
diff --git a/Mage.Sets/src/mage/cards/a/AnimateDead.java b/Mage.Sets/src/mage/cards/a/AnimateDead.java
index 8094e7da870..7398061be83 100644
--- a/Mage.Sets/src/mage/cards/a/AnimateDead.java
+++ b/Mage.Sets/src/mage/cards/a/AnimateDead.java
@@ -94,7 +94,7 @@ class AnimateDeadReAttachEffect extends OneShotEffect {
if (controller != null && animateDead != null) {
Card cardInGraveyard = game.getCard(animateDead.getAttachedTo());
- if (cardInGraveyard == null) {
+ if (cardInGraveyard == null || game.getState().getZone(cardInGraveyard.getId()) != Zone.GRAVEYARD) {
return true;
}
// put card into play from Graveyard
@@ -105,6 +105,7 @@ class AnimateDeadReAttachEffect extends OneShotEffect {
FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead");
filter.add(new PermanentIdPredicate(cardInGraveyard.getId()));
Target target = new TargetCreaturePermanent(filter);
+ target.setNotTarget(true); // Bug #7772
target.addTarget(enchantedCreature.getId(), source, game);
animateDead.getSpellAbility().getTargets().clear();
animateDead.getSpellAbility().getTargets().add(target);
@@ -225,6 +226,7 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou
for (Ability ability : permanent.getAbilities()) {
if (ability instanceof EnchantAbility) {
abilityToRemove = ability;
+ ability.getTargets().clear();
}
}
permanent.removeAbility(abilityToRemove, source.getSourceId(), game);
@@ -258,6 +260,7 @@ class AnimateDeadAttachToPermanentEffect extends ContinuousEffectImpl {
FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead");
filter.add(new PermanentIdPredicate(getTargetPointer().getFirst(game, source)));
Target target = new TargetCreaturePermanent(filter);
+ target.setNotTarget(true); // Bug #7772
target.addTarget(((FixedTarget) getTargetPointer()).getTarget(), source, game);
animateDead.getSpellAbility().getTargets().clear();
animateDead.getSpellAbility().getTargets().add(target);
diff --git a/Mage.Sets/src/mage/cards/a/AnimistsAwakening.java b/Mage.Sets/src/mage/cards/a/AnimistsAwakening.java
index 840b92bf263..911a2f264d6 100644
--- a/Mage.Sets/src/mage/cards/a/AnimistsAwakening.java
+++ b/Mage.Sets/src/mage/cards/a/AnimistsAwakening.java
@@ -56,7 +56,7 @@ class AnimistsAwakeningEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller == null || sourceObject == null) {
return false;
}
@@ -66,7 +66,7 @@ class AnimistsAwakeningEffect extends OneShotEffect {
if (!cards.isEmpty()) {
controller.revealCards(sourceObject.getIdName(), cards, game);
Set toBattlefield = new LinkedHashSet<>();
- for (Card card : cards.getCards(new FilterLandCard(), source.getSourceId(), source.getControllerId(), game)) {
+ for (Card card : cards.getCards(new FilterLandCard(), source.getControllerId(), source, game)) {
cards.remove(card);
toBattlefield.add(card);
}
diff --git a/Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java b/Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java
index e6126818263..fae6c4995c3 100644
--- a/Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java
+++ b/Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java
@@ -52,8 +52,8 @@ public final class AnimusOfNightsReach extends CardImpl {
// Whenever Animus of Night's Reach attacks, it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard.
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(
- xValue, StaticValue.get(0), Duration.EndOfTurn, true)
- ).addHint(AnimusOfNightsReachHint.instance));
+ xValue, StaticValue.get(0), Duration.EndOfTurn, true
+ ).setText("it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard")).addHint(AnimusOfNightsReachHint.instance));
}
private AnimusOfNightsReach(final AnimusOfNightsReach card) {
diff --git a/Mage.Sets/src/mage/cards/a/AnjesRavager.java b/Mage.Sets/src/mage/cards/a/AnjesRavager.java
index 72ef6d7bbbe..c9c7d416c4f 100644
--- a/Mage.Sets/src/mage/cards/a/AnjesRavager.java
+++ b/Mage.Sets/src/mage/cards/a/AnjesRavager.java
@@ -39,7 +39,7 @@ public final class AnjesRavager extends CardImpl {
this.addAbility(ability);
// Madness {1}{R}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{1}{R}")));
}
private AnjesRavager(final AnjesRavager card) {
diff --git a/Mage.Sets/src/mage/cards/a/Antagonize.java b/Mage.Sets/src/mage/cards/a/Antagonize.java
new file mode 100644
index 00000000000..464f5854ad5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/Antagonize.java
@@ -0,0 +1,33 @@
+package mage.cards.a;
+
+import java.util.UUID;
+
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class Antagonize extends CardImpl {
+
+ public Antagonize(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
+
+ // Target creature gets +4/+3 until end of turn.
+ this.getSpellAbility().addEffect(new BoostTargetEffect(4, 3));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private Antagonize(final Antagonize card) {
+ super(card);
+ }
+
+ @Override
+ public Antagonize copy() {
+ return new Antagonize(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/Anticipate.java b/Mage.Sets/src/mage/cards/a/Anticipate.java
index 5883d7eef07..3e3bc99c5d3 100644
--- a/Mage.Sets/src/mage/cards/a/Anticipate.java
+++ b/Mage.Sets/src/mage/cards/a/Anticipate.java
@@ -1,12 +1,10 @@
package mage.cards.a;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.filter.StaticFilters;
import java.util.UUID;
@@ -19,11 +17,7 @@ public final class Anticipate extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(3), false, StaticValue.get(1),
- StaticFilters.FILTER_CARD, Zone.LIBRARY, false, false
- ).setText("look at the top three cards of your library. " +
- "Put one of them into your hand and the rest on the bottom of your library in any order"));
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(3, 1, PutCards.HAND, PutCards.BOTTOM_ANY));
}
private Anticipate(final Anticipate card) {
diff --git a/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java b/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java
index 1668edee293..c509e050fa2 100644
--- a/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java
+++ b/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java
@@ -29,7 +29,7 @@ public final class AnuridBrushhopper extends CardImpl {
// Discard two cards: Exile Anurid Brushhopper. Return it to the battlefield under its owner's control at the beginning of the next end step.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true),
+ new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(),
new DiscardTargetCost(new TargetCardInHand(2, new FilterCard("two cards")))));
}
diff --git a/Mage.Sets/src/mage/cards/a/AnuridScavenger.java b/Mage.Sets/src/mage/cards/a/AnuridScavenger.java
index e72f7b67e57..5f4c455c57d 100644
--- a/Mage.Sets/src/mage/cards/a/AnuridScavenger.java
+++ b/Mage.Sets/src/mage/cards/a/AnuridScavenger.java
@@ -69,7 +69,7 @@ class AnuridScavengerCost extends CostImpl {
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
if (controller != null) {
- if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), game)) {
+ if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), source, game)) {
for (UUID targetId: targets.get(0).getTargets()) {
Card card = game.getCard(targetId);
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
@@ -85,7 +85,7 @@ class AnuridScavengerCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return targets.canChoose(source.getSourceId(), controllerId, game);
+ return targets.canChoose(controllerId, source, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AphettoAlchemist.java b/Mage.Sets/src/mage/cards/a/AphettoAlchemist.java
index 2ae8d0bdefb..aee72367d65 100644
--- a/Mage.Sets/src/mage/cards/a/AphettoAlchemist.java
+++ b/Mage.Sets/src/mage/cards/a/AphettoAlchemist.java
@@ -45,7 +45,7 @@ public final class AphettoAlchemist extends CardImpl {
this.addAbility(ability);
// Morph {U}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{U}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{U}")));
}
private AphettoAlchemist(final AphettoAlchemist card) {
diff --git a/Mage.Sets/src/mage/cards/a/AphettoExterminator.java b/Mage.Sets/src/mage/cards/a/AphettoExterminator.java
index 1ba67e66b23..36b883b4286 100644
--- a/Mage.Sets/src/mage/cards/a/AphettoExterminator.java
+++ b/Mage.Sets/src/mage/cards/a/AphettoExterminator.java
@@ -30,7 +30,7 @@ public final class AphettoExterminator extends CardImpl {
this.toughness = new MageInt(1);
// Morph {3}{B}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{B}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{3}{B}")));
// When Aphetto Exterminator is turned face up, target creature gets -3/-3 until end of turn.
Ability ability = new TurnedFaceUpSourceTriggeredAbility(new BoostTargetEffect(-3,-3,Duration.EndOfTurn));
diff --git a/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java b/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java
index 210ad5e4cdd..bdca251a3ff 100644
--- a/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java
+++ b/Mage.Sets/src/mage/cards/a/ApocalypseHydra.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import mage.MageInt;
@@ -16,7 +15,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -40,7 +38,9 @@ public final class ApocalypseHydra extends CardImpl {
this.addAbility(new EntersBattlefieldAbility(new ApocalypseHydraEffect()));
// {1}{R}, Remove a +1/+1 counter from Apocalypse Hydra: Apocalypse Hydra deals 1 damage to any target.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{1}{R}"));
+ Ability ability = new SimpleActivatedAbility(
+ new DamageTargetEffect(1, "it"), new ManaCostsImpl<>("{1}{R}")
+ );
ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AppealAuthority.java b/Mage.Sets/src/mage/cards/a/AppealAuthority.java
index a87b598f0a5..5b357e366c6 100644
--- a/Mage.Sets/src/mage/cards/a/AppealAuthority.java
+++ b/Mage.Sets/src/mage/cards/a/AppealAuthority.java
@@ -14,10 +14,9 @@ import mage.cards.SplitCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SpellAbilityType;
-import mage.constants.TargetController;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
+import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
@@ -43,11 +42,9 @@ public final class AppealAuthority extends SplitCard {
getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true));
// Tap up to two target creatures your opponents control. Creatures you control gain vigilance until end of turn.
getRightHalfCard().getSpellAbility().addEffect(new TapTargetEffect());
- FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control");
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- getRightHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2, filter, false));
+ getRightHalfCard().getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent(0, 2));
getRightHalfCard().getSpellAbility().addEffect(new GainAbilityControlledEffect(VigilanceAbility.getInstance(),
- Duration.EndOfTurn, new FilterControlledCreaturePermanent("creatures")));
+ Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES));
}
diff --git a/Mage.Sets/src/mage/cards/a/AquamorphEntity.java b/Mage.Sets/src/mage/cards/a/AquamorphEntity.java
index 0eddd538a38..87f34fe9c98 100644
--- a/Mage.Sets/src/mage/cards/a/AquamorphEntity.java
+++ b/Mage.Sets/src/mage/cards/a/AquamorphEntity.java
@@ -16,7 +16,6 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -39,7 +38,7 @@ public final class AquamorphEntity extends CardImpl {
this.addAbility(ability);
// Morph {2}{U}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{U}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{2}{U}")));
}
private AquamorphEntity(final AquamorphEntity card) {
@@ -128,7 +127,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl {
break;
}
game.addEffect(new SetPowerToughnessSourceEffect(power, toughness, Duration.Custom, SubLayer.SetPT_7b), source);
- return true;
+ return false;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AquitectsWill.java b/Mage.Sets/src/mage/cards/a/AquitectsWill.java
index 2076f905aba..c1f9df1e485 100644
--- a/Mage.Sets/src/mage/cards/a/AquitectsWill.java
+++ b/Mage.Sets/src/mage/cards/a/AquitectsWill.java
@@ -4,12 +4,9 @@ import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
-import mage.abilities.effects.ContinuousEffect;
-import mage.abilities.effects.ContinuousEffectImpl;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
-import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@@ -19,10 +16,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetLandPermanent;
-import java.util.List;
-import java.util.Set;
import java.util.UUID;
-import java.util.stream.Collectors;
/**
* @author ilcartographer
@@ -60,10 +54,10 @@ public final class AquitectsWill extends CardImpl {
}
}
-class AquitectsWillEffect extends ContinuousEffectImpl {
+class AquitectsWillEffect extends BecomesBasicLandTargetEffect {
AquitectsWillEffect() {
- super(Duration.EndOfGame, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
+ super(Duration.Custom, false, false, SubType.ISLAND);
staticText = "That land is an Island in addition to its other types for as long as it has a flood counter on it";
}
@@ -79,25 +73,10 @@ class AquitectsWillEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Permanent land = game.getPermanent(this.targetPointer.getFirst(game, source));
- if (land == null
- || land.getCounters(game).getCount(CounterType.FLOOD) < 1) {
+ if (land == null || land.getCounters(game).getCount(CounterType.FLOOD) < 1) {
discard();
return false;
}
- // The land is an island intrinsically so the ability is added at layer 4, not layer 6
- land.addSubType(game, SubType.ISLAND);
- if (!land.getAbilities(game).containsClass(BlueManaAbility.class)) {
- land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
- }
- return true;
- }
-
- @Override
- public Set isDependentTo(List allEffectsInLayer) {
- return allEffectsInLayer
- .stream()
- .filter(effect -> effect.getDependencyTypes().contains(DependencyType.BecomeIsland))
- .map(Effect::getId)
- .collect(Collectors.toSet());
+ return super.apply(game, source);
}
}
diff --git a/Mage.Sets/src/mage/cards/a/ArashinWarBeast.java b/Mage.Sets/src/mage/cards/a/ArashinWarBeast.java
index e4b1b4f351c..21fe3683bf5 100644
--- a/Mage.Sets/src/mage/cards/a/ArashinWarBeast.java
+++ b/Mage.Sets/src/mage/cards/a/ArashinWarBeast.java
@@ -82,7 +82,7 @@ class ArashinWarBeastTriggeredAbility extends TriggeredAbilityImpl {
((DamagedEvent) event).isCombatDamage() &&
!usedForCombatDamageStep) {
Permanent creature = game.getPermanentOrLKIBattlefield(event.getTargetId());
- if (creature == null || !filter.match(creature, getSourceId(), getControllerId(), game)) {
+ if (creature == null || !filter.match(creature, getControllerId(), this, game)) {
return false;
}
// trigger only once per combat damage step
diff --git a/Mage.Sets/src/mage/cards/a/AraumiOfTheDeadTide.java b/Mage.Sets/src/mage/cards/a/AraumiOfTheDeadTide.java
index 2a54189e348..3bdd5b9c706 100644
--- a/Mage.Sets/src/mage/cards/a/AraumiOfTheDeadTide.java
+++ b/Mage.Sets/src/mage/cards/a/AraumiOfTheDeadTide.java
@@ -96,7 +96,7 @@ class AraumiOfTheDeadTideCost extends CostImpl {
int oppCount = game.getOpponents(controllerId).size();
TargetCard target = new TargetCardInYourGraveyard(oppCount, StaticFilters.FILTER_CARD);
target.setNotTarget(true);
- player.choose(Outcome.Exile, target, source.getSourceId(), game);
+ player.choose(Outcome.Exile, target, source, game);
Cards cards = new CardsImpl(target.getTargets());
if (cards.size() < oppCount) {
return paid;
diff --git a/Mage.Sets/src/mage/cards/a/ArcSpitter.java b/Mage.Sets/src/mage/cards/a/ArcSpitter.java
new file mode 100644
index 00000000000..ebae0b59be8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ArcSpitter.java
@@ -0,0 +1,57 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ArcSpitter extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("creature that's blocking it");
+
+ static {
+ filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
+ }
+
+ public ArcSpitter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature has "{1}: This creature deals 1 damage to target creature that's blocking it."
+ Ability ability = new SimpleActivatedAbility(
+ new DamageTargetEffect(1, "this creature"), new GenericManaCost(1)
+ );
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect(ability, AttachmentType.EQUIPMENT)));
+
+ // Equip {1}
+ this.addAbility(new EquipAbility(1));
+ }
+
+ private ArcSpitter(final ArcSpitter card) {
+ super(card);
+ }
+
+ @Override
+ public ArcSpitter copy() {
+ return new ArcSpitter(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java
index 5b054570126..f9a6967e801 100644
--- a/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java
+++ b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java
@@ -102,13 +102,14 @@ class ArcaneAdaptationEffect extends ContinuousEffectImpl {
// commander in command zone
for (CommandObject commandObject : game.getState().getCommand()) {
if (commandObject instanceof Commander) {
- Card card = game.getCard(((Commander) commandObject).getId());
+ Card card = game.getCard((commandObject).getId());
if (card != null && card.isOwnedBy(controller.getId())
&& card.isCreature(game) && !card.hasSubtype(subType, game)) {
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
}
}
}
+ // TODO: Why is this not using the for-in loop like all the others?
// creature spells you control
for (Iterator iterator = game.getStack().iterator(); iterator.hasNext(); ) {
StackObject stackObject = iterator.next();
diff --git a/Mage.Sets/src/mage/cards/a/ArcaneBombardment.java b/Mage.Sets/src/mage/cards/a/ArcaneBombardment.java
new file mode 100644
index 00000000000..b20f51a8923
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ArcaneBombardment.java
@@ -0,0 +1,158 @@
+package mage.cards.a;
+
+import mage.ApprovingObject;
+import mage.abilities.Ability;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.WatcherScope;
+import mage.constants.Zone;
+import mage.filter.FilterSpell;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterInstantOrSorcerySpell;
+import mage.game.ExileZone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.stack.Spell;
+import mage.game.stack.StackObject;
+import mage.players.Player;
+import mage.util.CardUtil;
+import mage.util.RandomUtil;
+import mage.watchers.Watcher;
+import org.apache.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ArcaneBombardment extends CardImpl {
+
+ private static final FilterSpell filter
+ = new FilterInstantOrSorcerySpell("your first instant or sorcery spell each turn");
+
+ static {
+ filter.add(ArcaneBombardmentWatcher::checkSpell);
+ }
+
+ public ArcaneBombardment(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{R}{R}");
+
+ // Whenever you cast your first instant or sorcery spell each turn, exile an instant or sorcery card at random from your graveyard. Then copy each card exiled with Arcane Bombardment. You may cast any number of the copies without paying their mana costs.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new ArcaneBombardmentEffect(), filter, false
+ ), new ArcaneBombardmentWatcher());
+ }
+
+ private ArcaneBombardment(final ArcaneBombardment card) {
+ super(card);
+ }
+
+ @Override
+ public ArcaneBombardment copy() {
+ return new ArcaneBombardment(this);
+ }
+}
+
+class ArcaneBombardmentEffect extends OneShotEffect {
+
+ ArcaneBombardmentEffect() {
+ super(Outcome.Benefit);
+ staticText = "exile an instant or sorcery card at random from your graveyard. Then copy each " +
+ "card exiled with {this}. You may cast any number of the copies without paying their mana costs";
+ }
+
+ private ArcaneBombardmentEffect(final ArcaneBombardmentEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ArcaneBombardmentEffect copy() {
+ return new ArcaneBombardmentEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ UUID exileId = CardUtil.getExileZoneId(game, source);
+ Card toExile = RandomUtil.randomFromCollection(
+ player.getGraveyard().getCards(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, game)
+ );
+ if (toExile != null) {
+ player.moveCardsToExile(
+ toExile, source, game, true,
+ exileId, CardUtil.getSourceName(game, source)
+ );
+ }
+ ExileZone exileZone = game.getExile().getExileZone(exileId);
+ if (exileZone == null || exileZone.isEmpty()) {
+ return false;
+ }
+
+ Cards copies = new CardsImpl();
+ for (Card card : exileZone.getCards(game)) {
+ Card copiedCard = game.copyCard(card, source, source.getControllerId());
+ game.getExile().add(source.getSourceId(), "", copiedCard);
+ game.getState().setZone(copiedCard.getId(), Zone.EXILED);
+ copies.add(copiedCard);
+ }
+ for (Card copiedCard : copies.getCards(game)) {
+ if (!player.chooseUse(outcome, "Cast the copied card?", source, game)) {
+ continue;
+ }
+ if (copiedCard.getSpellAbility() != null) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ player.cast(
+ player.chooseAbilityForCast(copiedCard, game, true),
+ game, true, new ApprovingObject(source, game)
+ );
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
+ } else {
+ Logger.getLogger(ArcaneBombardmentEffect.class).error("Arcane Bombardment: "
+ + "spell ability == null " + copiedCard.getName());
+ }
+ }
+ return true;
+ }
+}
+
+class ArcaneBombardmentWatcher extends Watcher {
+
+ private final Map playerMap = new HashMap<>();
+
+ ArcaneBombardmentWatcher() {
+ super(WatcherScope.GAME);
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() != GameEvent.EventType.SPELL_CAST) {
+ return;
+ }
+ Spell spell = game.getSpell(event.getTargetId());
+ if (spell != null && spell.isInstantOrSorcery(game)) {
+ playerMap.compute(spell.getControllerId(), CardUtil::setOrIncrementValue);
+ }
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ playerMap.clear();
+ }
+
+ static boolean checkSpell(StackObject input, Game game) {
+ return game
+ .getState()
+ .getWatcher(ArcaneBombardmentWatcher.class)
+ .playerMap
+ .getOrDefault(input.getControllerId(), 0) < 2;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/ArcaneEndeavor.java b/Mage.Sets/src/mage/cards/a/ArcaneEndeavor.java
index 70f26c348c8..2d2cd938152 100644
--- a/Mage.Sets/src/mage/cards/a/ArcaneEndeavor.java
+++ b/Mage.Sets/src/mage/cards/a/ArcaneEndeavor.java
@@ -1,17 +1,19 @@
package mage.cards.a;
import mage.abilities.Ability;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.cost.CastWithoutPayingManaCostEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
+import mage.cards.CardsImpl;
import mage.constants.CardType;
+import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.filter.FilterCard;
import mage.filter.common.FilterInstantOrSorceryCard;
+import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.players.Player;
+import mage.util.CardUtil;
import java.util.List;
import java.util.UUID;
@@ -40,10 +42,6 @@ public final class ArcaneEndeavor extends CardImpl {
class ArcaneEndeavorEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterInstantOrSorceryCard(
- "instant or sorcery card with mana value %mv or less from your hand"
- );
-
ArcaneEndeavorEffect() {
super(Outcome.Benefit);
staticText = "roll two d8 and choose one result. Draw cards equal to that result. " +
@@ -82,7 +80,9 @@ class ArcaneEndeavorEffect extends OneShotEffect {
second = firstResult;
}
player.drawCards(first, source, game);
- new CastWithoutPayingManaCostEffect(StaticValue.get(second), filter).apply(game, source);
+ FilterCard filter = new FilterInstantOrSorceryCard();
+ filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, second + 1));
+ CardUtil.castSpellWithAttributesForFree(player, source, game, new CardsImpl(player.getHand()), filter);
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/ArcaneInfusion.java b/Mage.Sets/src/mage/cards/a/ArcaneInfusion.java
index 33cb5d8ca39..e8ab05a63a6 100644
--- a/Mage.Sets/src/mage/cards/a/ArcaneInfusion.java
+++ b/Mage.Sets/src/mage/cards/a/ArcaneInfusion.java
@@ -1,14 +1,12 @@
package mage.cards.a;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.TimingRule;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
import java.util.UUID;
@@ -23,13 +21,7 @@ public final class ArcaneInfusion extends CardImpl {
// Look at the top four cards of your library. You may reveal an instant or sorcery card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(4), false, StaticValue.get(1),
- StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, Zone.LIBRARY,
- false, true, false, Zone.HAND,
- true, false, false
- ).setBackInRandomOrder(true).setText("Look at the top four cards of your library. " +
- "You may reveal an instant or sorcery card from among them and put it into your hand. " +
- "Put the rest on the bottom of your library in a random order."));
+ 4, 1, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, PutCards.HAND, PutCards.BOTTOM_RANDOM));
// Flashback {3}{U}{R}
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{3}{U}{R}")));
diff --git a/Mage.Sets/src/mage/cards/a/ArcaneInvestigator.java b/Mage.Sets/src/mage/cards/a/ArcaneInvestigator.java
index e863a6de6f2..4c499ef1578 100644
--- a/Mage.Sets/src/mage/cards/a/ArcaneInvestigator.java
+++ b/Mage.Sets/src/mage/cards/a/ArcaneInvestigator.java
@@ -3,16 +3,14 @@ package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.RollDieWithResultTableEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
-import mage.filter.StaticFilters;
import java.util.UUID;
@@ -39,11 +37,7 @@ public final class ArcaneInvestigator extends CardImpl {
effect.addTableEntry(1, 9, new DrawCardSourceControllerEffect(1));
// 10-20 | Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
- effect.addTableEntry(10, 20, new LookLibraryAndPickControllerEffect(
- StaticValue.get(3), false, StaticValue.get(1),
- StaticFilters.FILTER_CARD, Zone.LIBRARY, false, false
- ).setText("look at the top three cards of your library. Put one of them " +
- "into your hand and the rest on the bottom of your library in any order"));
+ effect.addTableEntry(10, 20, new LookLibraryAndPickControllerEffect(3, 1, PutCards.HAND, PutCards.BOTTOM_ANY));
}
private ArcaneInvestigator(final ArcaneInvestigator card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArcaneLighthouse.java b/Mage.Sets/src/mage/cards/a/ArcaneLighthouse.java
index 9a675800525..4e6d558320c 100644
--- a/Mage.Sets/src/mage/cards/a/ArcaneLighthouse.java
+++ b/Mage.Sets/src/mage/cards/a/ArcaneLighthouse.java
@@ -15,9 +15,6 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.TargetController;
-import mage.constants.Zone;
-import mage.filter.common.FilterCreaturePermanent;
/**
*
@@ -25,13 +22,6 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class ArcaneLighthouse extends CardImpl {
-
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public ArcaneLighthouse(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
@@ -39,11 +29,11 @@ public final class ArcaneLighthouse extends CardImpl {
this.addAbility(new ColorlessManaAbility());
// {1}, {tap}: Until end of turn, creatures your opponents control lose hexproof and shroud and can't have hexproof or shroud.
- Effect effect = new CreaturesCantGetOrHaveAbilityEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, filter);
+ Effect effect = new CreaturesCantGetOrHaveAbilityEffect(HexproofAbility.getInstance(), Duration.EndOfTurn);
effect.setText("Until end of turn, creatures your opponents control lose hexproof");
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1));
+ Ability ability = new SimpleActivatedAbility(effect, new GenericManaCost(1));
ability.addCost(new TapSourceCost());
- effect = new CreaturesCantGetOrHaveAbilityEffect(ShroudAbility.getInstance(), Duration.EndOfTurn, filter);
+ effect = new CreaturesCantGetOrHaveAbilityEffect(ShroudAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and shroud and can't have hexproof or shroud");
ability.addEffect(effect);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/ArcanistsOwl.java b/Mage.Sets/src/mage/cards/a/ArcanistsOwl.java
index cd73ab26557..66b1f2b7c19 100644
--- a/Mage.Sets/src/mage/cards/a/ArcanistsOwl.java
+++ b/Mage.Sets/src/mage/cards/a/ArcanistsOwl.java
@@ -2,14 +2,13 @@ package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterArtifactOrEnchantmentCard;
@@ -32,16 +31,11 @@ public final class ArcanistsOwl extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // When Arcanist's Owl enters the battlefield, look at the top four cards of your library. You may reveal an artifact or enchantment card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+ // When Arcanist's Owl enters the battlefield, look at the top four cards of your library.
+ // You may reveal an artifact or enchantment card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in a random order.
this.addAbility(new EntersBattlefieldTriggeredAbility(
- new LookLibraryAndPickControllerEffect(
- StaticValue.get(4), false, StaticValue.get(1), filter,
- Zone.LIBRARY, false, true, false, Zone.HAND,
- true, false, false
- ).setBackInRandomOrder(true).setText("look at the top four cards of your library. " +
- "You may reveal an artifact or enchantment card from among them and put it into your hand. " +
- "Put the rest on the bottom of your library in a random order.")
- ));
+ new LookLibraryAndPickControllerEffect(4, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM)));
}
private ArcanistsOwl(final ArcanistsOwl card) {
diff --git a/Mage.Sets/src/mage/cards/a/Arcbond.java b/Mage.Sets/src/mage/cards/a/Arcbond.java
index 8e3f19ea1bf..06ae06950e5 100644
--- a/Mage.Sets/src/mage/cards/a/Arcbond.java
+++ b/Mage.Sets/src/mage/cards/a/Arcbond.java
@@ -130,7 +130,7 @@ class ArcbondEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
int damage = (Integer) this.getValue("damage");
UUID sourceId = (UUID) this.getValue("sourceId");
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject != null && damage > 0 && sourceId != null) {
Permanent targetObject = game.getPermanentOrLKIBattlefield(sourceId);
if (targetObject != null) {
diff --git a/Mage.Sets/src/mage/cards/a/ArcboundReclaimer.java b/Mage.Sets/src/mage/cards/a/ArcboundReclaimer.java
index 67511908118..d1908d6da0f 100644
--- a/Mage.Sets/src/mage/cards/a/ArcboundReclaimer.java
+++ b/Mage.Sets/src/mage/cards/a/ArcboundReclaimer.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -14,24 +12,25 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.common.FilterArtifactCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ArcboundReclaimer extends CardImpl {
public ArcboundReclaimer(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}");
this.subtype.add(SubType.GOLEM);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// Remove a +1/+1 counter from Arcbound Reclaimer: Put target artifact card from your graveyard on top of your library.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibraryTargetEffect(true),new RemoveCountersSourceCost(CounterType.P1P1.createInstance()));
- ability.addTarget(new TargetCardInYourGraveyard(new FilterArtifactCard("artifact card from your graveyard")));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibraryTargetEffect(true), new RemoveCountersSourceCost(CounterType.P1P1.createInstance()));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
// Modular 2
diff --git a/Mage.Sets/src/mage/cards/a/ArchaeomancersMap.java b/Mage.Sets/src/mage/cards/a/ArchaeomancersMap.java
index 39918d13917..9f97adf0fab 100644
--- a/Mage.Sets/src/mage/cards/a/ArchaeomancersMap.java
+++ b/Mage.Sets/src/mage/cards/a/ArchaeomancersMap.java
@@ -72,10 +72,10 @@ enum ArchaeomancersMapCondition implements Condition {
UUID playerId = (UUID) source.getEffects().get(0).getValue("permanentEnteringControllerId");
return playerId != null && game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
- source.getSourceId(), playerId, game
+ playerId, source, game
) > game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
- source.getSourceId(), source.getControllerId(), game
+ source.getControllerId(), source, game
);
}
}
diff --git a/Mage.Sets/src/mage/cards/a/Archaeomender.java b/Mage.Sets/src/mage/cards/a/Archaeomender.java
index 7d796a45047..5b26300f4ad 100644
--- a/Mage.Sets/src/mage/cards/a/Archaeomender.java
+++ b/Mage.Sets/src/mage/cards/a/Archaeomender.java
@@ -8,8 +8,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.filter.FilterCard;
-import mage.filter.common.FilterArtifactCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
@@ -19,9 +18,6 @@ import java.util.UUID;
*/
public final class Archaeomender extends CardImpl {
- private static final FilterCard filter
- = new FilterArtifactCard("artifact card from your graveyard");
-
public Archaeomender(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
@@ -32,7 +28,7 @@ public final class Archaeomender extends CardImpl {
// When Archaeomender enters the battlefield, return target artifact card from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
- ability.addTarget(new TargetCardInYourGraveyard(filter));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java b/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java
index b8127b27631..6fcb910e12a 100644
--- a/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java
+++ b/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java
@@ -84,8 +84,8 @@ public final class ArchdemonOfGreed extends CardImpl {
if (player != null) {
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false);
// if they can pay the cost, then they must pay
- if (target.canChoose(source.getSourceId(), player.getId(), game)) {
- player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
+ if (target.canChoose(player.getId(), source, game)) {
+ player.choose(Outcome.Sacrifice, target, source, game);
Permanent humanSacrifice = game.getPermanent(target.getFirstTarget());
if (humanSacrifice != null) {
// sacrifice the chosen card
diff --git a/Mage.Sets/src/mage/cards/a/ArchdemonOfUnx.java b/Mage.Sets/src/mage/cards/a/ArchdemonOfUnx.java
index 1738f21e67a..5c6d7df33f2 100644
--- a/Mage.Sets/src/mage/cards/a/ArchdemonOfUnx.java
+++ b/Mage.Sets/src/mage/cards/a/ArchdemonOfUnx.java
@@ -43,7 +43,7 @@ public final class ArchdemonOfUnx extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// At the beginning of your upkeep, sacrifice a non-Zombie creature, then create a 2/2 black Zombie creature token.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new SacrificeControllerEffect(filter, 1, ""), TargetController.YOU, false);
- ability.addEffect(new CreateTokenEffect(new ZombieToken()));
+ ability.addEffect(new CreateTokenEffect(new ZombieToken()).concatBy(", then"));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/ArchetypeOfAggression.java b/Mage.Sets/src/mage/cards/a/ArchetypeOfAggression.java
index fec03ff2bfe..b4f43b9eb7a 100644
--- a/Mage.Sets/src/mage/cards/a/ArchetypeOfAggression.java
+++ b/Mage.Sets/src/mage/cards/a/ArchetypeOfAggression.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -9,9 +8,10 @@ import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreaturePermanent;
/**
*
@@ -19,12 +19,6 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class ArchetypeOfAggression extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public ArchetypeOfAggression(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{1}{R}{R}");
this.subtype.add(SubType.HUMAN);
@@ -34,10 +28,9 @@ public final class ArchetypeOfAggression extends CardImpl {
this.toughness = new MageInt(2);
// Creatures you control have trample.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
// Creatures your opponents control lose trample and can't have or gain trample.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CreaturesCantGetOrHaveAbilityEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter)));
-
+ this.addAbility(new SimpleStaticAbility(new CreaturesCantGetOrHaveAbilityEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)));
}
private ArchetypeOfAggression(final ArchetypeOfAggression card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArchetypeOfCourage.java b/Mage.Sets/src/mage/cards/a/ArchetypeOfCourage.java
index b3cd4e35725..fbd8f744448 100644
--- a/Mage.Sets/src/mage/cards/a/ArchetypeOfCourage.java
+++ b/Mage.Sets/src/mage/cards/a/ArchetypeOfCourage.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -9,9 +8,10 @@ import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreaturePermanent;
/**
*
@@ -19,11 +19,6 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class ArchetypeOfCourage extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public ArchetypeOfCourage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{1}{W}{W}");
this.subtype.add(SubType.HUMAN);
@@ -33,9 +28,9 @@ public final class ArchetypeOfCourage extends CardImpl {
this.toughness = new MageInt(2);
// Creatures you control have first strike.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
// Creatures your opponents control lose first strike and can't have or gain first strike.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CreaturesCantGetOrHaveAbilityEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield, filter)));
+ this.addAbility(new SimpleStaticAbility(new CreaturesCantGetOrHaveAbilityEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield)));
}
private ArchetypeOfCourage(final ArchetypeOfCourage card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArchetypeOfEndurance.java b/Mage.Sets/src/mage/cards/a/ArchetypeOfEndurance.java
index 96ba77e85b2..450ddc74333 100644
--- a/Mage.Sets/src/mage/cards/a/ArchetypeOfEndurance.java
+++ b/Mage.Sets/src/mage/cards/a/ArchetypeOfEndurance.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -9,9 +8,10 @@ import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreaturePermanent;
/**
*
@@ -19,12 +19,6 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class ArchetypeOfEndurance extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public ArchetypeOfEndurance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{6}{G}{G}");
this.subtype.add(SubType.BOAR);
@@ -33,11 +27,9 @@ public final class ArchetypeOfEndurance extends CardImpl {
this.toughness = new MageInt(5);
// Creatures you control have hexproof.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(HexproofAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
-
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(HexproofAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
// Creatures your opponents control lose hexproof and can't have or gain hexproof.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CreaturesCantGetOrHaveAbilityEffect(HexproofAbility.getInstance(), Duration.WhileOnBattlefield, filter)));
-
+ this.addAbility(new SimpleStaticAbility(new CreaturesCantGetOrHaveAbilityEffect(HexproofAbility.getInstance(), Duration.WhileOnBattlefield)));
}
private ArchetypeOfEndurance(final ArchetypeOfEndurance card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArchetypeOfFinality.java b/Mage.Sets/src/mage/cards/a/ArchetypeOfFinality.java
index 19fcf7cb95a..2fdb4edfd69 100644
--- a/Mage.Sets/src/mage/cards/a/ArchetypeOfFinality.java
+++ b/Mage.Sets/src/mage/cards/a/ArchetypeOfFinality.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -9,9 +8,10 @@ import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreaturePermanent;
/**
*
@@ -19,12 +19,6 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class ArchetypeOfFinality extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public ArchetypeOfFinality(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{4}{B}{B}");
this.subtype.add(SubType.GORGON);
@@ -33,10 +27,9 @@ public final class ArchetypeOfFinality extends CardImpl {
this.toughness = new MageInt(3);
// Creatures you control have deathtouch.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
// Creatures your opponents control lose deathtouch and can't have or gain deathtouch.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CreaturesCantGetOrHaveAbilityEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield, filter)));
-
+ this.addAbility(new SimpleStaticAbility(new CreaturesCantGetOrHaveAbilityEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield)));
}
private ArchetypeOfFinality(final ArchetypeOfFinality card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArchetypeOfImagination.java b/Mage.Sets/src/mage/cards/a/ArchetypeOfImagination.java
index 69081991faa..2dab503b87e 100644
--- a/Mage.Sets/src/mage/cards/a/ArchetypeOfImagination.java
+++ b/Mage.Sets/src/mage/cards/a/ArchetypeOfImagination.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -9,9 +8,10 @@ import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreaturePermanent;
/**
*
@@ -19,11 +19,6 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class ArchetypeOfImagination extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public ArchetypeOfImagination(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{4}{U}{U}");
this.subtype.add(SubType.HUMAN);
@@ -33,10 +28,9 @@ public final class ArchetypeOfImagination extends CardImpl {
this.toughness = new MageInt(2);
// Creatures you control have flying.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
// Creatures your opponents control lose flying and can't have or gain flying.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CreaturesCantGetOrHaveAbilityEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter)));
-
+ this.addAbility(new SimpleStaticAbility(new CreaturesCantGetOrHaveAbilityEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)));
}
private ArchetypeOfImagination(final ArchetypeOfImagination card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java b/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java
index 76864cb6176..52b712d9714 100644
--- a/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java
+++ b/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java
@@ -73,7 +73,7 @@ class ArchfiendOfDepravityEffect extends OneShotEffect {
List creaturesToSacrifice = new ArrayList<>();
TargetControlledPermanent target = new TargetControlledPermanent(0, 2, new FilterControlledCreaturePermanent("creatures to keep"), true);
if (opponent.chooseTarget(outcome, target, source, game)) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), opponent.getId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), opponent.getId(), source, game)) {
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
creaturesToSacrifice.add(permanent);
}
diff --git a/Mage.Sets/src/mage/cards/a/ArchfiendOfSorrows.java b/Mage.Sets/src/mage/cards/a/ArchfiendOfSorrows.java
index 3a9433eb44d..1f1d41839bd 100644
--- a/Mage.Sets/src/mage/cards/a/ArchfiendOfSorrows.java
+++ b/Mage.Sets/src/mage/cards/a/ArchfiendOfSorrows.java
@@ -11,8 +11,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.common.FilterOpponentsCreaturePermanent;
+import mage.filter.StaticFilters;
import java.util.UUID;
@@ -21,9 +20,6 @@ import java.util.UUID;
*/
public final class ArchfiendOfSorrows extends CardImpl {
- private static final FilterCreaturePermanent filter
- = new FilterOpponentsCreaturePermanent("creatures your opponents control");
-
public ArchfiendOfSorrows(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}");
@@ -36,7 +32,7 @@ public final class ArchfiendOfSorrows extends CardImpl {
// When Archfiend of Sorrows enters the battlefield, creatures your opponents control get -2/-2 until end of turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostAllEffect(
- -2, -2, Duration.EndOfTurn, filter, false
+ -2, -2, Duration.EndOfTurn, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES, false
)));
// Unearth {3}{B}{B}
diff --git a/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java b/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java
index a25c3ab7d03..6ff9b34ee2a 100644
--- a/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java
+++ b/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java
@@ -42,7 +42,7 @@ public final class ArchfiendOfSpite extends CardImpl {
this.addAbility(new ArchfiendOfSpiteAbility());
// Madness {3}{B}{B}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{3}{B}{B}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{3}{B}{B}")));
}
diff --git a/Mage.Sets/src/mage/cards/a/Archipelagore.java b/Mage.Sets/src/mage/cards/a/Archipelagore.java
index 55a15bdb0db..276ce4a252b 100644
--- a/Mage.Sets/src/mage/cards/a/Archipelagore.java
+++ b/Mage.Sets/src/mage/cards/a/Archipelagore.java
@@ -34,7 +34,7 @@ public final class Archipelagore extends CardImpl {
// Whenever this creature mutates, tap up to X target creatures, where X is the number of times this creature has mutated. Those creatures don't untap during their controller's next untap step.
Ability ability = new MutatesSourceTriggeredAbility(new TapTargetEffect(
- "up to X target creatures, where X is the number of times this creature has mutated."
+ "tap up to X target creatures, where X is the number of times this creature has mutated."
));
ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures"));
ability.setTargetAdjuster(ArchipelagoreAdjuster.instance);
diff --git a/Mage.Sets/src/mage/cards/a/ArchmagesCharm.java b/Mage.Sets/src/mage/cards/a/ArchmagesCharm.java
index 51509613010..d74e8e6f61a 100644
--- a/Mage.Sets/src/mage/cards/a/ArchmagesCharm.java
+++ b/Mage.Sets/src/mage/cards/a/ArchmagesCharm.java
@@ -44,7 +44,7 @@ public final class ArchmagesCharm extends CardImpl {
this.getSpellAbility().addMode(mode);
// • Gain control of target nonland permanent with converted mana cost 1 or less.
- mode = new Mode(new GainControlTargetEffect(Duration.EndOfGame, true));
+ mode = new Mode(new GainControlTargetEffect(Duration.Custom, true));
mode.addTarget(new TargetPermanent(filter));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/ArcticFoxes.java b/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
index d6b86a7d425..c75d0b58019 100644
--- a/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
+++ b/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
@@ -68,6 +68,6 @@ enum ArcticFoxesCondition implements Condition {
if (defenderId == null) {
return false;
}
- return game.getBattlefield().contains(filter, source.getSourceId(), defenderId, game, 1);
+ return game.getBattlefield().contains(filter, source.getSourceId(), defenderId, source, game, 1);
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/ArcticNishoba.java b/Mage.Sets/src/mage/cards/a/ArcticNishoba.java
index 72f96426914..873ae4e4690 100644
--- a/Mage.Sets/src/mage/cards/a/ArcticNishoba.java
+++ b/Mage.Sets/src/mage/cards/a/ArcticNishoba.java
@@ -37,9 +37,8 @@ public final class ArcticNishoba extends CardImpl {
// Cumulative upkeep {G} or {W}
this.addAbility(new CumulativeUpkeepAbility(new OrCost(
- new ManaCostsImpl("{G}"),
- new ManaCostsImpl("{W}"),
- "{G} or {W}"
+ "{G} or {W}", new ManaCostsImpl("{G}"),
+ new ManaCostsImpl("{W}")
)));
// When Arctic Nishoba dies, you gain 2 life for each age counter on it.
diff --git a/Mage.Sets/src/mage/cards/a/ArdennIntrepidArchaeologist.java b/Mage.Sets/src/mage/cards/a/ArdennIntrepidArchaeologist.java
index fbd5b292ad1..4f8f9e25d32 100644
--- a/Mage.Sets/src/mage/cards/a/ArdennIntrepidArchaeologist.java
+++ b/Mage.Sets/src/mage/cards/a/ArdennIntrepidArchaeologist.java
@@ -88,7 +88,7 @@ class ArdennIntrepidArchaeologistEffect extends OneShotEffect {
return false;
}
TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
for (UUID targetId : target.getTargets()) {
if (player != null) {
player.addAttachment(targetId, source, game);
diff --git a/Mage.Sets/src/mage/cards/a/ArdentDustspeaker.java b/Mage.Sets/src/mage/cards/a/ArdentDustspeaker.java
index 1d8f14d44ba..a5317238953 100644
--- a/Mage.Sets/src/mage/cards/a/ArdentDustspeaker.java
+++ b/Mage.Sets/src/mage/cards/a/ArdentDustspeaker.java
@@ -79,7 +79,7 @@ class ArdentDustspeakerCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return targets.canChoose(source.getSourceId(), controllerId, game);
+ return targets.canChoose(controllerId, source, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/ArgivianArchaeologist.java b/Mage.Sets/src/mage/cards/a/ArgivianArchaeologist.java
index 11f24f71e17..2c9f9b63623 100644
--- a/Mage.Sets/src/mage/cards/a/ArgivianArchaeologist.java
+++ b/Mage.Sets/src/mage/cards/a/ArgivianArchaeologist.java
@@ -1,41 +1,37 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
-import mage.filter.common.FilterArtifactCard;
+import mage.filter.StaticFilters;
import mage.target.Target;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class ArgivianArchaeologist extends CardImpl {
-
- private static final FilterArtifactCard filter = new FilterArtifactCard("artifact card from your graveyard");
public ArgivianArchaeologist(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ARTIFICER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {W}{W}, {tap}: Return target artifact card from your graveyard to your hand.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{W}{W}"));
+ Ability ability = new SimpleActivatedAbility(new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{W}{W}"));
ability.addCost(new TapSourceCost());
- Target target = new TargetCardInYourGraveyard(filter);
+ Target target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD);
ability.addTarget(target);
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/ArgivianRestoration.java b/Mage.Sets/src/mage/cards/a/ArgivianRestoration.java
index 9b555630301..81fa3ecb752 100644
--- a/Mage.Sets/src/mage/cards/a/ArgivianRestoration.java
+++ b/Mage.Sets/src/mage/cards/a/ArgivianRestoration.java
@@ -4,7 +4,7 @@ import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffec
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterArtifactCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
@@ -19,7 +19,7 @@ public final class ArgivianRestoration extends CardImpl {
// Return target artifact card from your graveyard to the battlefield.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect());
- this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterArtifactCard("artifact card from your graveyard")));
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD));
}
private ArgivianRestoration(final ArgivianRestoration card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArlinnKord.java b/Mage.Sets/src/mage/cards/a/ArlinnKord.java
index 96f3e33cc21..1c9db9b355a 100644
--- a/Mage.Sets/src/mage/cards/a/ArlinnKord.java
+++ b/Mage.Sets/src/mage/cards/a/ArlinnKord.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TransformSourceEffect;
@@ -34,7 +33,7 @@ public final class ArlinnKord extends CardImpl {
this.secondSideCardClazz = ArlinnEmbracedByTheMoon.class;
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: Until end of turn, up to one target creature gets +2/+2 and gains vigilance and haste.
Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn);
diff --git a/Mage.Sets/src/mage/cards/a/ArlinnTheMoonsFury.java b/Mage.Sets/src/mage/cards/a/ArlinnTheMoonsFury.java
index f6ce1f507a5..3488bbb9a9c 100644
--- a/Mage.Sets/src/mage/cards/a/ArlinnTheMoonsFury.java
+++ b/Mage.Sets/src/mage/cards/a/ArlinnTheMoonsFury.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.keyword.HasteAbility;
@@ -28,7 +27,7 @@ public final class ArlinnTheMoonsFury extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ARLINN);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
this.color.setRed(true);
this.color.setGreen(true);
this.nightCard = true;
diff --git a/Mage.Sets/src/mage/cards/a/ArlinnThePacksHope.java b/Mage.Sets/src/mage/cards/a/ArlinnThePacksHope.java
index 7a7a2ccf999..14d73c31ae3 100644
--- a/Mage.Sets/src/mage/cards/a/ArlinnThePacksHope.java
+++ b/Mage.Sets/src/mage/cards/a/ArlinnThePacksHope.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect;
@@ -33,7 +32,7 @@ public final class ArlinnThePacksHope extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ARLINN);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
this.secondSideCardClazz = mage.cards.a.ArlinnTheMoonsFury.class;
// Daybound
diff --git a/Mage.Sets/src/mage/cards/a/ArlinnVoiceOfThePack.java b/Mage.Sets/src/mage/cards/a/ArlinnVoiceOfThePack.java
index 0f671dc4c70..3b7defc7915 100644
--- a/Mage.Sets/src/mage/cards/a/ArlinnVoiceOfThePack.java
+++ b/Mage.Sets/src/mage/cards/a/ArlinnVoiceOfThePack.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.CreateTokenEffect;
@@ -28,7 +27,7 @@ public final class ArlinnVoiceOfThePack extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ARLINN);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(7));
+ this.setStartingLoyalty(7);
// Each creature you control that's a Wolf or Werewolf enters the battlefield with an additional +1/+1 counter on it.
this.addAbility(new SimpleStaticAbility(new ArlinnVoiceOfThePackReplacementEffect()));
@@ -51,7 +50,7 @@ class ArlinnVoiceOfThePackReplacementEffect extends ReplacementEffectImpl {
ArlinnVoiceOfThePackReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.BoostCreature);
- staticText = "Each creature you control that's a Wolf or Werewolf " +
+ staticText = "Each creature you control that's a Wolf or a Werewolf " +
"enters the battlefield with an additional +1/+1 counter on it";
}
diff --git a/Mage.Sets/src/mage/cards/a/ArmadilloCloak.java b/Mage.Sets/src/mage/cards/a/ArmadilloCloak.java
index c3b369eba50..90fdb9290ac 100644
--- a/Mage.Sets/src/mage/cards/a/ArmadilloCloak.java
+++ b/Mage.Sets/src/mage/cards/a/ArmadilloCloak.java
@@ -5,7 +5,7 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.DealsDamageAttachedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.dynamicvalue.common.NumericSetToEffectValues;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.GainLifeEffect;
@@ -44,7 +44,7 @@ public final class ArmadilloCloak extends CardImpl {
this.addAbility(ability);
// Whenever enchanted creature deals damage, you gain that much life.
- this.addAbility(new DealsDamageAttachedTriggeredAbility(Zone.BATTLEFIELD, new GainLifeEffect(new NumericSetToEffectValues("that much", "damage")), false));
+ this.addAbility(new DealsDamageAttachedTriggeredAbility(Zone.BATTLEFIELD, new GainLifeEffect(SavedDamageValue.MUCH), false));
}
diff --git a/Mage.Sets/src/mage/cards/a/ArmedAndArmored.java b/Mage.Sets/src/mage/cards/a/ArmedAndArmored.java
index 29e95ca5bef..d101a746b06 100644
--- a/Mage.Sets/src/mage/cards/a/ArmedAndArmored.java
+++ b/Mage.Sets/src/mage/cards/a/ArmedAndArmored.java
@@ -108,12 +108,12 @@ class ArmedAndArmoredEquipEffect extends OneShotEffect {
if (!dwarves.isEmpty() && !equipment.isEmpty()) {
TargetPermanent target = new TargetPermanent(0, 1, dwarfFilter, true);
target.withChooseHint("dwarf to be equipped");
- controller.choose(outcome, target, source.getId(), game);
+ controller.choose(outcome, target, source, game);
Permanent dwarf = game.getPermanent(target.getFirstTarget());
if (dwarf != null) {
target = new TargetPermanent(0, Integer.MAX_VALUE, equipmentFilter, true);
target.withChooseHint("equip to " + dwarf.getLogName());
- controller.choose(outcome, target, source.getId(), game);
+ controller.choose(outcome, target, source, game);
for (UUID targetId : target.getTargets()) {
dwarf.addAttachment(targetId, source, game);
game.informPlayers(game.getPermanent(targetId).getLogName() + " was attached to " + dwarf.getLogName());
diff --git a/Mage.Sets/src/mage/cards/a/ArmguardFamiliar.java b/Mage.Sets/src/mage/cards/a/ArmguardFamiliar.java
index baf092ccf72..33a58c83abe 100644
--- a/Mage.Sets/src/mage/cards/a/ArmguardFamiliar.java
+++ b/Mage.Sets/src/mage/cards/a/ArmguardFamiliar.java
@@ -37,6 +37,7 @@ public final class ArmguardFamiliar extends CardImpl {
ability.addEffect(new GainAbilityAttachedEffect(
new WardAbility(new GenericManaCost(2)), AttachmentType.EQUIPMENT
).setText("and has ward {2}"));
+ this.addAbility(ability);
// Reconfigure {4}
this.addAbility(new ReconfigureAbility("{4}"));
diff --git a/Mage.Sets/src/mage/cards/a/ArmixFiligreeThrasher.java b/Mage.Sets/src/mage/cards/a/ArmixFiligreeThrasher.java
index 705e4b4a35f..4e1745fe5de 100644
--- a/Mage.Sets/src/mage/cards/a/ArmixFiligreeThrasher.java
+++ b/Mage.Sets/src/mage/cards/a/ArmixFiligreeThrasher.java
@@ -1,12 +1,14 @@
package mage.cards.a;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.dynamicvalue.AdditiveDynamicValue;
import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.effects.Effect;
+import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.dynamicvalue.common.SignInversionDynamicValue;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.PartnerAbility;
@@ -19,8 +21,6 @@ import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
-import mage.game.Game;
-import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.UUID;
@@ -36,6 +36,11 @@ public final class ArmixFiligreeThrasher extends CardImpl {
filter.add(DefendingPlayerControlsPredicate.instance);
}
+ private static final DynamicValue xValue = new SignInversionDynamicValue(new AdditiveDynamicValue(
+ new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACTS),
+ new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_ARTIFACT)
+ ));
+
public ArmixFiligreeThrasher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{B}");
@@ -46,11 +51,8 @@ public final class ArmixFiligreeThrasher extends CardImpl {
// Whenever Armix, Filigree Thrasher attacks, you may discard a card. When you do, target creature defending player controls gets -X/-X until end of turn, where X is the number of artifacts you control plus the number of artifact cards in your graveyard.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
- new BoostTargetEffect(
- ArmixFiligreeThrasherValue.instance,
- ArmixFiligreeThrasherValue.instance,
- Duration.EndOfTurn, true
- ), false, "target creature defending player controls gets -X/-X until end of turn, " +
+ new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn, true), false,
+ "target creature defending player controls gets -X/-X until end of turn, " +
"where X is the number of artifacts you control plus the number of artifact cards in your graveyard"
);
ability.addTarget(new TargetPermanent(filter));
@@ -71,32 +73,3 @@ public final class ArmixFiligreeThrasher extends CardImpl {
return new ArmixFiligreeThrasher(this);
}
}
-
-enum ArmixFiligreeThrasherValue implements DynamicValue {
- instance;
-
- @Override
- public int calculate(Game game, Ability sourceAbility, Effect effect) {
- Player player = game.getPlayer(sourceAbility.getControllerId());
- if (player == null) {
- return 0;
- }
- return -(player.getGraveyard().count(
- StaticFilters.FILTER_CARD_ARTIFACT, player.getId(), game
- ) + game.getBattlefield().count(
- StaticFilters.FILTER_PERMANENT_ARTIFACT,
- sourceAbility.getSourceId(),
- sourceAbility.getControllerId(), game
- ));
- }
-
- @Override
- public ArmixFiligreeThrasherValue copy() {
- return instance;
- }
-
- @Override
- public String getMessage() {
- return "";
- }
-}
diff --git a/Mage.Sets/src/mage/cards/a/ArmorSliver.java b/Mage.Sets/src/mage/cards/a/ArmorSliver.java
index 51b621bb65f..d3b81dcb084 100644
--- a/Mage.Sets/src/mage/cards/a/ArmorSliver.java
+++ b/Mage.Sets/src/mage/cards/a/ArmorSliver.java
@@ -30,7 +30,7 @@ public final class ArmorSliver extends CardImpl {
this.toughness = new MageInt(2);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(
new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(0, 1, Duration.EndOfTurn).setText("this creature gets +0/+1 until end of turn"),
- new GenericManaCost(2)), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, false)));
+ new GenericManaCost(2)), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS, false)));
}
private ArmorSliver(final ArmorSliver card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArmoredAscension.java b/Mage.Sets/src/mage/cards/a/ArmoredAscension.java
index 01bcb46fc69..dbef7ce772a 100644
--- a/Mage.Sets/src/mage/cards/a/ArmoredAscension.java
+++ b/Mage.Sets/src/mage/cards/a/ArmoredAscension.java
@@ -1,12 +1,13 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@@ -16,8 +17,9 @@ import mage.filter.common.FilterLandPermanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward_at_googlemail.com, North
*/
public final class ArmoredAscension extends CardImpl {
@@ -29,8 +31,11 @@ public final class ArmoredAscension extends CardImpl {
filter.add(TargetController.YOU.getControllerPredicate());
}
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
+ private static final Hint hint = new ValueHint("Plains you control", xValue);
+
public ArmoredAscension(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
this.subtype.add(SubType.AURA);
@@ -41,10 +46,13 @@ public final class ArmoredAscension extends CardImpl {
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// Enchanted creature gets +1/+1 for each Plains you control and has flying.
- PermanentsOnBattlefieldCount amount = new PermanentsOnBattlefieldCount(filter, 1);
- SimpleStaticAbility ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield));
- ability.addEffect(new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA));
- this.addAbility(ability);
+ SimpleStaticAbility ability = new SimpleStaticAbility(
+ new BoostEnchantedEffect(xValue, xValue, Duration.WhileOnBattlefield)
+ );
+ ability.addEffect(new GainAbilityAttachedEffect(
+ FlyingAbility.getInstance(), AttachmentType.AURA
+ ).setText("and has flying"));
+ this.addAbility(ability.addHint(hint));
}
private ArmoredAscension(final ArmoredAscension card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArmoredSkyhunter.java b/Mage.Sets/src/mage/cards/a/ArmoredSkyhunter.java
index a4d57dfa177..9c20073645b 100644
--- a/Mage.Sets/src/mage/cards/a/ArmoredSkyhunter.java
+++ b/Mage.Sets/src/mage/cards/a/ArmoredSkyhunter.java
@@ -100,7 +100,7 @@ class ArmoredSkyhunterEffect extends OneShotEffect {
}
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
targetCard.setNotTarget(true);
- player.choose(outcome, targetPermanent, source.getSourceId(), game);
+ player.choose(outcome, targetPermanent, source, game);
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
if (permanent != null) {
permanent.addAttachment(equipment.getId(), source, game);
diff --git a/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java b/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java
index db3852831e7..8ea11d805a0 100644
--- a/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java
+++ b/Mage.Sets/src/mage/cards/a/ArmoryAutomaton.java
@@ -88,7 +88,7 @@ class ArmoryAutomatonEffect extends OneShotEffect {
while (player.canRespond() && countBattlefield > 0 && player.chooseUse(Outcome.Benefit, "Select and attach a target Equipment?", source, game)) {
Target targetEquipment = new TargetPermanent(currentFilter);
targetEquipment.setRequired(false);
- if (player.choose(Outcome.Benefit, targetEquipment, source.getSourceId(), game) && targetEquipment.getFirstTarget() != null) {
+ if (player.choose(Outcome.Benefit, targetEquipment, source, game) && targetEquipment.getFirstTarget() != null) {
currentFilter.add(Predicates.not(new PermanentIdPredicate(targetEquipment.getFirstTarget()))); // exclude selected for next time
Permanent aura = game.getPermanent(targetEquipment.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java b/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java
index b7531af26b7..c930da96a01 100644
--- a/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java
+++ b/Mage.Sets/src/mage/cards/a/ArniBrokenbrow.java
@@ -69,7 +69,7 @@ class ArniBrokenbrowEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (controller == null || mageObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/a/ArrogantWurm.java b/Mage.Sets/src/mage/cards/a/ArrogantWurm.java
index 4ca3d3b0482..19c1cc99d18 100644
--- a/Mage.Sets/src/mage/cards/a/ArrogantWurm.java
+++ b/Mage.Sets/src/mage/cards/a/ArrogantWurm.java
@@ -28,7 +28,7 @@ public final class ArrogantWurm extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// Madness {2}{G}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl<>("{2}{G}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{2}{G}")));
}
private ArrogantWurm(final ArrogantWurm card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArsenalThresher.java b/Mage.Sets/src/mage/cards/a/ArsenalThresher.java
index 168f8b8e264..a9d3f5eb3ae 100644
--- a/Mage.Sets/src/mage/cards/a/ArsenalThresher.java
+++ b/Mage.Sets/src/mage/cards/a/ArsenalThresher.java
@@ -14,7 +14,7 @@ import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.common.FilterArtifactCard;
-import mage.filter.predicate.mageobject.AnotherCardPredicate;
+import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -75,12 +75,12 @@ class ArsenalThresherEffect extends OneShotEffect {
}
Permanent arsenalThresher = game.getPermanentEntering(source.getSourceId());
FilterArtifactCard filter = new FilterArtifactCard();
- filter.add(new AnotherCardPredicate());
+ filter.add(AnotherPredicate.instance);
if (controller.chooseUse(Outcome.Benefit, "Reveal other artifacts in your hand?", source, game)) {
Cards cards = new CardsImpl();
- if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
+ if (controller.getHand().count(filter, source.getControllerId(), source, game) > 0) {
TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
- if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
+ if (controller.choose(Outcome.Benefit, target, source, game)) {
for (UUID uuid : target.getTargets()) {
cards.add(controller.getHand().get(uuid, game));
}
diff --git a/Mage.Sets/src/mage/cards/a/ArterialAlchemy.java b/Mage.Sets/src/mage/cards/a/ArterialAlchemy.java
index 9fc51df6f9d..0750354b54e 100644
--- a/Mage.Sets/src/mage/cards/a/ArterialAlchemy.java
+++ b/Mage.Sets/src/mage/cards/a/ArterialAlchemy.java
@@ -74,7 +74,7 @@ class ArterialAlchemyEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(
- filter, source.getControllerId(), source.getSourceId(), game
+ filter, source.getControllerId(), source, game
)) {
switch (layer) {
case TypeChangingEffects_4:
diff --git a/Mage.Sets/src/mage/cards/m/MindFlayerTheShadow.java b/Mage.Sets/src/mage/cards/a/ArvinoxTheMindFlail.java
similarity index 80%
rename from Mage.Sets/src/mage/cards/m/MindFlayerTheShadow.java
rename to Mage.Sets/src/mage/cards/a/ArvinoxTheMindFlail.java
index a409f0d1d69..8b84f951fa8 100644
--- a/Mage.Sets/src/mage/cards/m/MindFlayerTheShadow.java
+++ b/Mage.Sets/src/mage/cards/a/ArvinoxTheMindFlail.java
@@ -1,4 +1,4 @@
-package mage.cards.m;
+package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
@@ -27,7 +27,7 @@ import java.util.UUID;
/**
* @author TheElk801 plus everyone who worked on Gonti
*/
-public final class MindFlayerTheShadow extends CardImpl {
+public final class ArvinoxTheMindFlail extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent();
@@ -38,7 +38,7 @@ public final class MindFlayerTheShadow extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
private static final Hint hint = new ValueHint("Permanents you control but don't own", xValue);
- public MindFlayerTheShadow(UUID ownerId, CardSetInfo setInfo) {
+ public ArvinoxTheMindFlail(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{4}{B}{B}{B}");
this.addSuperType(SuperType.LEGENDARY);
@@ -53,23 +53,23 @@ public final class MindFlayerTheShadow extends CardImpl {
// At the beginning of your end step, exile the bottom card of each opponent's library face down. For as long as those cards remain exiled, you may look at them, you may cast permanent spells from among them, and you may spend mana as though it were mana of any color to cast those spells.
this.addAbility(new BeginningOfEndStepTriggeredAbility(
- new MindFlayerTheShadowExileEffect(), TargetController.YOU, false
+ new ArvinoxTheMindFlailExileEffect(), TargetController.YOU, false
));
}
- private MindFlayerTheShadow(final MindFlayerTheShadow card) {
+ private ArvinoxTheMindFlail(final ArvinoxTheMindFlail card) {
super(card);
}
@Override
- public MindFlayerTheShadow copy() {
- return new MindFlayerTheShadow(this);
+ public ArvinoxTheMindFlail copy() {
+ return new ArvinoxTheMindFlail(this);
}
}
-class MindFlayerTheShadowExileEffect extends OneShotEffect {
+class ArvinoxTheMindFlailExileEffect extends OneShotEffect {
- MindFlayerTheShadowExileEffect() {
+ ArvinoxTheMindFlailExileEffect() {
super(Outcome.Benefit);
staticText = "exile the bottom card of each opponent's library face down. "
+ "For as long as those cards remain exiled, you may look at them, "
@@ -77,13 +77,13 @@ class MindFlayerTheShadowExileEffect extends OneShotEffect {
+ "and you may spend mana as though it were mana of any color to cast those spells";
}
- private MindFlayerTheShadowExileEffect(final MindFlayerTheShadowExileEffect effect) {
+ private ArvinoxTheMindFlailExileEffect(final ArvinoxTheMindFlailExileEffect effect) {
super(effect);
}
@Override
- public MindFlayerTheShadowExileEffect copy() {
- return new MindFlayerTheShadowExileEffect(this);
+ public ArvinoxTheMindFlailExileEffect copy() {
+ return new ArvinoxTheMindFlailExileEffect(this);
}
@Override
@@ -108,21 +108,21 @@ class MindFlayerTheShadowExileEffect extends OneShotEffect {
cards.getCards(game).stream().forEach(card -> card.setFaceDown(true, game));
for (Card card : cards.getCards(game)) {
card.setFaceDown(true, game);
- game.addEffect(new MindFlayerTheShadowCastFromExileEffect().setTargetPointer(new FixedTarget(card, game)), source);
- game.addEffect(new MindFlayerTheShadowSpendAnyManaEffect().setTargetPointer(new FixedTarget(card, game)), source);
- game.addEffect(new MindFlayerTheShadowLookEffect(source.getControllerId()).setTargetPointer(new FixedTarget(card, game)), source);
+ game.addEffect(new ArvinoxTheMindFlailCastFromExileEffect().setTargetPointer(new FixedTarget(card, game)), source);
+ game.addEffect(new ArvinoxTheMindFlailSpendAnyManaEffect().setTargetPointer(new FixedTarget(card, game)), source);
+ game.addEffect(new ArvinoxTheMindFlailLookEffect(source.getControllerId()).setTargetPointer(new FixedTarget(card, game)), source);
}
return true;
}
}
-class MindFlayerTheShadowCastFromExileEffect extends AsThoughEffectImpl {
+class ArvinoxTheMindFlailCastFromExileEffect extends AsThoughEffectImpl {
- public MindFlayerTheShadowCastFromExileEffect() {
+ public ArvinoxTheMindFlailCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
}
- private MindFlayerTheShadowCastFromExileEffect(final MindFlayerTheShadowCastFromExileEffect effect) {
+ private ArvinoxTheMindFlailCastFromExileEffect(final ArvinoxTheMindFlailCastFromExileEffect effect) {
super(effect);
}
@@ -132,8 +132,8 @@ class MindFlayerTheShadowCastFromExileEffect extends AsThoughEffectImpl {
}
@Override
- public MindFlayerTheShadowCastFromExileEffect copy() {
- return new MindFlayerTheShadowCastFromExileEffect(this);
+ public ArvinoxTheMindFlailCastFromExileEffect copy() {
+ return new ArvinoxTheMindFlailCastFromExileEffect(this);
}
@Override
@@ -161,14 +161,14 @@ class MindFlayerTheShadowCastFromExileEffect extends AsThoughEffectImpl {
}
}
-class MindFlayerTheShadowSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
+class ArvinoxTheMindFlailSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
- public MindFlayerTheShadowSpendAnyManaEffect() {
+ public ArvinoxTheMindFlailSpendAnyManaEffect() {
super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit);
staticText = "you may spend mana as though it were mana of any color to cast it";
}
- private MindFlayerTheShadowSpendAnyManaEffect(final MindFlayerTheShadowSpendAnyManaEffect effect) {
+ private ArvinoxTheMindFlailSpendAnyManaEffect(final ArvinoxTheMindFlailSpendAnyManaEffect effect) {
super(effect);
}
@@ -178,8 +178,8 @@ class MindFlayerTheShadowSpendAnyManaEffect extends AsThoughEffectImpl implement
}
@Override
- public MindFlayerTheShadowSpendAnyManaEffect copy() {
- return new MindFlayerTheShadowSpendAnyManaEffect(this);
+ public ArvinoxTheMindFlailSpendAnyManaEffect copy() {
+ return new ArvinoxTheMindFlailSpendAnyManaEffect(this);
}
@Override
@@ -206,17 +206,17 @@ class MindFlayerTheShadowSpendAnyManaEffect extends AsThoughEffectImpl implement
}
}
-class MindFlayerTheShadowLookEffect extends AsThoughEffectImpl {
+class ArvinoxTheMindFlailLookEffect extends AsThoughEffectImpl {
private final UUID authorizedPlayerId;
- public MindFlayerTheShadowLookEffect(UUID authorizedPlayerId) {
+ public ArvinoxTheMindFlailLookEffect(UUID authorizedPlayerId) {
super(AsThoughEffectType.LOOK_AT_FACE_DOWN, Duration.EndOfGame, Outcome.Benefit);
this.authorizedPlayerId = authorizedPlayerId;
staticText = "You may look at the cards exiled with {this}";
}
- private MindFlayerTheShadowLookEffect(final MindFlayerTheShadowLookEffect effect) {
+ private ArvinoxTheMindFlailLookEffect(final ArvinoxTheMindFlailLookEffect effect) {
super(effect);
this.authorizedPlayerId = effect.authorizedPlayerId;
}
@@ -227,8 +227,8 @@ class MindFlayerTheShadowLookEffect extends AsThoughEffectImpl {
}
@Override
- public MindFlayerTheShadowLookEffect copy() {
- return new MindFlayerTheShadowLookEffect(this);
+ public ArvinoxTheMindFlailLookEffect copy() {
+ return new ArvinoxTheMindFlailLookEffect(this);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java b/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java
index 5c493e33179..59d17c42819 100644
--- a/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java
+++ b/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java
@@ -95,7 +95,7 @@ class AryelTapXTargetCost extends VariableCostImpl {
@Override
public int getMaxValue(Ability source, Game game) {
- return game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ return game.getBattlefield().count(filter, source.getControllerId(), source, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AsForetold.java b/Mage.Sets/src/mage/cards/a/AsForetold.java
index d80d0d64748..e4b281fa86d 100644
--- a/Mage.Sets/src/mage/cards/a/AsForetold.java
+++ b/Mage.Sets/src/mage/cards/a/AsForetold.java
@@ -69,7 +69,7 @@ class SpellWithManaCostLessThanOrEqualToCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
return object != null
&& !object.isLand(game)
&& object.getManaValue() <= counters;
diff --git a/Mage.Sets/src/mage/cards/a/AscendantAcolyte.java b/Mage.Sets/src/mage/cards/a/AscendantAcolyte.java
new file mode 100644
index 00000000000..464c364c675
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AscendantAcolyte.java
@@ -0,0 +1,89 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DoubleCountersSourceEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AscendantAcolyte extends CardImpl {
+
+ public AscendantAcolyte(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.MONK);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Ascendant Acolyte enters the battlefield with a +1/+1 counter on it for each +1/+1 counter among other creatures you control.
+ this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(
+ CounterType.P1P1.createInstance(), AscendantAcolyteValue.instance, true
+ ), "with a +1/+1 counter on it for each +1/+1 counter among other creatures you control").addHint(AscendantAcolyteValue.getHint()));
+
+ // At the beginning of your upkeep, double the number of +1/+1 counters on Ascendant Acolyte.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new DoubleCountersSourceEffect(CounterType.P1P1), TargetController.YOU, false
+ ));
+ }
+
+ private AscendantAcolyte(final AscendantAcolyte card) {
+ super(card);
+ }
+
+ @Override
+ public AscendantAcolyte copy() {
+ return new AscendantAcolyte(this);
+ }
+}
+
+enum AscendantAcolyteValue implements DynamicValue {
+ instance;
+ private static final Hint hint = new ValueHint(
+ "Total +1/+1 counters on other creatures you control", instance
+ );
+
+ public static Hint getHint() {
+ return hint;
+ }
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ return game.getBattlefield()
+ .getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
+ sourceAbility.getControllerId(),
+ sourceAbility, game
+ ).stream()
+ .mapToInt(permanent -> permanent.getCounters(game).getCount(CounterType.P1P1))
+ .sum();
+ }
+
+ @Override
+ public AscendantAcolyteValue copy() {
+ return this;
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/AscendingAven.java b/Mage.Sets/src/mage/cards/a/AscendingAven.java
index 2122b9be66a..1770a937c28 100644
--- a/Mage.Sets/src/mage/cards/a/AscendingAven.java
+++ b/Mage.Sets/src/mage/cards/a/AscendingAven.java
@@ -30,7 +30,7 @@ public final class AscendingAven extends CardImpl {
// Ascending Aven can block only creatures with flying.
this.addAbility(new CanBlockOnlyFlyingAbility());
// Morph {2}{U}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{U}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{2}{U}")));
}
private AscendingAven(final AscendingAven card) {
diff --git a/Mage.Sets/src/mage/cards/a/AscentOfTheWorthy.java b/Mage.Sets/src/mage/cards/a/AscentOfTheWorthy.java
index c8c9b689e43..60d61305991 100644
--- a/Mage.Sets/src/mage/cards/a/AscentOfTheWorthy.java
+++ b/Mage.Sets/src/mage/cards/a/AscentOfTheWorthy.java
@@ -87,10 +87,10 @@ class AscentOfTheWorthyEffect extends OneShotEffect {
}
TargetPermanent target = new TargetControlledCreaturePermanent();
target.setNotTarget(true);
- if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
+ if (!target.canChoose(source.getControllerId(), source, game)) {
return false;
}
- player.choose(outcome, target, source.getControllerId(), game);
+ player.choose(outcome, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/a/AshasFavor.java b/Mage.Sets/src/mage/cards/a/AshasFavor.java
index 7962eeda7fb..29895a32691 100644
--- a/Mage.Sets/src/mage/cards/a/AshasFavor.java
+++ b/Mage.Sets/src/mage/cards/a/AshasFavor.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
@@ -13,33 +10,42 @@ import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class AshasFavor extends CardImpl {
- public AshasFavor (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}");
+ public AshasFavor(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
this.subtype.add(SubType.AURA);
-
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA)));
+ Ability ability = new SimpleStaticAbility(new GainAbilityAttachedEffect(
+ FlyingAbility.getInstance(), AttachmentType.AURA
+ ));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ FirstStrikeAbility.getInstance(), AttachmentType.AURA
+ ).setText(", first strike"));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ VigilanceAbility.getInstance(), AttachmentType.AURA
+ ).setText(", and vigilance"));
+ this.addAbility(ability);
}
- public AshasFavor (final AshasFavor card) {
+ public AshasFavor(final AshasFavor card) {
super(card);
}
@@ -47,5 +53,4 @@ public final class AshasFavor extends CardImpl {
public AshasFavor copy() {
return new AshasFavor(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/a/AshayaSoulOfTheWild.java b/Mage.Sets/src/mage/cards/a/AshayaSoulOfTheWild.java
index 010985ee806..64bf0edd602 100644
--- a/Mage.Sets/src/mage/cards/a/AshayaSoulOfTheWild.java
+++ b/Mage.Sets/src/mage/cards/a/AshayaSoulOfTheWild.java
@@ -77,7 +77,7 @@ class AshayaSoulOfTheWildEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(
- filter, source.getControllerId(), source.getSourceId(), game
+ filter, source.getControllerId(), source, game
)) {
if (!permanent.isLand(game)) {
permanent.addCardType(game, CardType.LAND);
diff --git a/Mage.Sets/src/mage/cards/a/AshcloudPhoenix.java b/Mage.Sets/src/mage/cards/a/AshcloudPhoenix.java
index 6ec21a04e2a..988585ad7bc 100644
--- a/Mage.Sets/src/mage/cards/a/AshcloudPhoenix.java
+++ b/Mage.Sets/src/mage/cards/a/AshcloudPhoenix.java
@@ -39,7 +39,7 @@ public final class AshcloudPhoenix extends CardImpl {
this.addAbility(new DiesSourceTriggeredAbility(new AshcloudPhoenixEffect()));
// Morph {4}{R}{R}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{4}{R}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl<>("{4}{R}{R}")));
// When Ashcloud Phoenix is turned face up, it deals 2 damage to each player.
Effect effect = new DamagePlayersEffect(2, TargetController.ANY);
diff --git a/Mage.Sets/src/mage/cards/a/AshesOfTheFallen.java b/Mage.Sets/src/mage/cards/a/AshesOfTheFallen.java
index 0dfd2a82906..2f90d505899 100644
--- a/Mage.Sets/src/mage/cards/a/AshesOfTheFallen.java
+++ b/Mage.Sets/src/mage/cards/a/AshesOfTheFallen.java
@@ -66,7 +66,7 @@ class AshesOfTheFallenEffect extends ContinuousEffectImpl {
}
}
} else {
- discard();;
+ discard();
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/a/AshiokDreamRender.java b/Mage.Sets/src/mage/cards/a/AshiokDreamRender.java
index ac680020c0d..abfd27ec50e 100644
--- a/Mage.Sets/src/mage/cards/a/AshiokDreamRender.java
+++ b/Mage.Sets/src/mage/cards/a/AshiokDreamRender.java
@@ -3,7 +3,6 @@ package mage.cards.a;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect;
@@ -29,7 +28,7 @@ public final class AshiokDreamRender extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ASHIOK);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// Spells and abilities your opponents control can't cause their controller to search their library.
this.addAbility(new SimpleStaticAbility(new AshiokDreamRenderEffect()));
@@ -74,7 +73,7 @@ class AshiokDreamRenderEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't search libraries (" + mageObject.getLogName() + " in play).";
}
diff --git a/Mage.Sets/src/mage/cards/a/AshiokNightmareMuse.java b/Mage.Sets/src/mage/cards/a/AshiokNightmareMuse.java
index 6c783fb101d..1260aad0644 100644
--- a/Mage.Sets/src/mage/cards/a/AshiokNightmareMuse.java
+++ b/Mage.Sets/src/mage/cards/a/AshiokNightmareMuse.java
@@ -1,24 +1,26 @@
package mage.cards.a;
-import java.util.UUID;
-import mage.ApprovingObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
+import mage.cards.CardsImpl;
import mage.constants.*;
import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.card.FaceDownPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.AshiokNightmareMuseToken;
import mage.players.Player;
-import mage.target.common.TargetCardInExile;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetNonlandPermanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
/**
* @author TheElk801
@@ -30,7 +32,7 @@ public final class AshiokNightmareMuse extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ASHIOK);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +1: Create a 2/3 blue and black Nightmare creature token with "Whenever this creature attacks or blocks, each opponent exiles the top two cards of their library."
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new AshiokNightmareMuseToken()), 1));
@@ -96,6 +98,7 @@ class AshiokNightmareMuseCastEffect extends OneShotEffect {
static {
filter.add(TargetController.OPPONENT.getOwnerPredicate());
+ filter.add(Predicates.not(FaceDownPredicate.instance));
}
AshiokNightmareMuseCastEffect() {
@@ -118,25 +121,10 @@ class AshiokNightmareMuseCastEffect extends OneShotEffect {
if (controller == null) {
return false;
}
- TargetCardInExile target = new TargetCardInExile(0, 3, filter, null);
- target.setNotTarget(true);
- if (!controller.chooseTarget(outcome, target, source, game)) { // method is fine, controller is still choosing the card
- return false;
- }
- for (UUID targetId : target.getTargets()) {
- if (targetId != null) {
- Card chosenCard = game.getCard(targetId);
- if (chosenCard != null
- && game.getState().getZone(chosenCard.getId()) == Zone.EXILED // must be exiled
- && game.getOpponents(controller.getId()).contains(chosenCard.getOwnerId()) // must be owned by an opponent
- && controller.chooseUse(outcome, "Cast " + chosenCard.getName() + " without paying its mana cost?", source, game)) {
- game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), Boolean.TRUE);
- controller.cast(controller.chooseAbilityForCast(chosenCard, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), null);
- }
- }
- }
+ CardUtil.castMultipleWithAttributeForFree(
+ controller, source, game, new CardsImpl(game.getExile().getCards(filter, game)),
+ StaticFilters.FILTER_CARD, 3
+ );
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java b/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java
index e52d6911130..eb4fd3b2afd 100644
--- a/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java
+++ b/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java
@@ -1,14 +1,11 @@
-
package mage.cards.a;
-import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
-import mage.abilities.costs.Cost;
+import mage.abilities.costs.VariableCostImpl;
import mage.abilities.costs.common.PayVariableLoyaltyCost;
-import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect;
import mage.cards.*;
import mage.constants.*;
import mage.filter.FilterCard;
@@ -35,7 +32,7 @@ public final class AshiokNightmareWeaver extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ASHIOK);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +2: Exile the top three cards of target opponent's library.
LoyaltyAbility ability = new LoyaltyAbility(new AshiokNightmareWeaverExileEffect(), 2);
@@ -80,15 +77,14 @@ class AshiokNightmareWeaverExileEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = source.getSourceObject(game);
- if (sourceObject != null && opponent != null && controller != null) {
- UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
- if (exileZone != null) {
- controller.moveCardsToExile(opponent.getLibrary().getTopCards(game, 3), source, game, true, exileZone, sourceObject.getIdName());
- return true;
- }
+ if (opponent == null || controller == null) {
+ return false;
}
- return false;
+ controller.moveCardsToExile(
+ opponent.getLibrary().getTopCards(game, 3), source, game, true,
+ CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source)
+ );
+ return true;
}
}
@@ -111,65 +107,34 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = source.getSourceObject(game);
- if (sourceObject == null || controller == null) {
+ if (controller == null) {
return false;
}
- int cmc = 0;
- for (Cost cost : source.getCosts()) {
- if (cost instanceof PayVariableLoyaltyCost) {
- cmc = ((PayVariableLoyaltyCost) cost).getAmount();
- }
- }
+ int cmc = CardUtil.castStream(
+ source.getCosts().stream(), PayVariableLoyaltyCost.class
+ ).mapToInt(VariableCostImpl::getAmount).sum();
- FilterCard filter = new FilterCreatureCard("creature card with mana value {" + cmc + "} exiled with " + sourceObject.getIdName());
+ FilterCard filter = new FilterCreatureCard("creature card with mana value " + cmc);
filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, cmc));
- Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()));
+ Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source));
- if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
- if (controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game)) {
- Card card = game.getCard(target.getFirstTarget());
- if (card != null
- && controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
- Permanent permanent = game.getPermanent(card.getId());
- if (permanent != null) {
- ContinuousEffectImpl effect = new AshiokNightmareWeaverAddTypeEffect();
- effect.setTargetPointer(new FixedTarget(permanent, game));
- game.addEffect(effect, source);
- }
- }
- }
- }
- return true;
- }
-}
-
-class AshiokNightmareWeaverAddTypeEffect extends ContinuousEffectImpl {
-
- public AshiokNightmareWeaverAddTypeEffect() {
- super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
- staticText = "That creature is a Nightmare in addition to its other types";
- }
-
- public AshiokNightmareWeaverAddTypeEffect(final AshiokNightmareWeaverAddTypeEffect effect) {
- super(effect);
- }
-
- @Override
- public AshiokNightmareWeaverAddTypeEffect copy() {
- return new AshiokNightmareWeaverAddTypeEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source));
- if (creature == null) {
- this.used = true;
+ if (!target.canChoose(controller.getId(), source, game)) {
return false;
}
- creature.addSubType(game, SubType.NIGHTMARE);
+ controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game);
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null) {
+ return true;
+ }
+ controller.moveCards(card, Zone.BATTLEFIELD, source, game);
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent != null) {
+ game.addEffect(new AddCardSubTypeTargetEffect(
+ SubType.NIGHTMARE, Duration.EndOfTurn
+ ).setTargetPointer(new FixedTarget(permanent, game)), source);
+ }
return true;
}
}
@@ -193,34 +158,23 @@ class AshiokNightmareWeaverExileAllEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = source.getSourceObject(game);
- if (sourceObject == null || controller == null) {
- return false;
- }
- UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
- if (exileId == null) {
+ if (controller == null) {
return false;
}
+ Cards cards = new CardsImpl();
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
- if (opponent != null) {
- Cards cards = new CardsImpl(opponent.getHand());
- for (UUID cardId : cards) {
- Card card = game.getCard(cardId);
- if (card != null) {
- controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source, game, Zone.HAND, true);
- }
- }
- cards.clear();
- cards.addAll(opponent.getGraveyard());
- for (UUID cardId : cards) {
- Card card = game.getCard(cardId);
- if (card != null) {
- controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source, game, Zone.GRAVEYARD, true);
- }
- }
+ if (opponent == null) {
+ continue;
}
+ cards.addAll(opponent.getHand());
+ cards.addAll(opponent.getGraveyard());
}
+ controller.moveCardsToExile(
+ cards.getCards(game), source, game, true,
+ CardUtil.getExileZoneId(game, source),
+ CardUtil.getSourceName(game, source)
+ );
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AshiokSculptorOfFears.java b/Mage.Sets/src/mage/cards/a/AshiokSculptorOfFears.java
index ec9e24c8fd1..a2feb015812 100644
--- a/Mage.Sets/src/mage/cards/a/AshiokSculptorOfFears.java
+++ b/Mage.Sets/src/mage/cards/a/AshiokSculptorOfFears.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.MillCardsEachPlayerEffect;
@@ -34,7 +33,7 @@ public final class AshiokSculptorOfFears extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ASHIOK);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +2: Draw a card. Each player puts the top two cards of their library into their graveyard.
Ability ability = new LoyaltyAbility(
diff --git a/Mage.Sets/src/mage/cards/a/AspectOfWolf.java b/Mage.Sets/src/mage/cards/a/AspectOfWolf.java
index 8eb1359d2d1..3c1326272b9 100644
--- a/Mage.Sets/src/mage/cards/a/AspectOfWolf.java
+++ b/Mage.Sets/src/mage/cards/a/AspectOfWolf.java
@@ -66,7 +66,7 @@ enum AspectOfWolfValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int forestCount = game.getBattlefield().count(
- filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game
+ filter, sourceAbility.getControllerId(), sourceAbility, game
);
return forestCount / 2 + (up ? forestCount % 2 : 0);
}
diff --git a/Mage.Sets/src/mage/cards/a/AssembleTheLegion.java b/Mage.Sets/src/mage/cards/a/AssembleTheLegion.java
index d996c592ef6..a1cb98ada51 100644
--- a/Mage.Sets/src/mage/cards/a/AssembleTheLegion.java
+++ b/Mage.Sets/src/mage/cards/a/AssembleTheLegion.java
@@ -25,7 +25,7 @@ public final class AssembleTheLegion extends CardImpl {
// At the beginning of your upkeep, put a muster counter on Assemble the Legion. Then create a 1/1 red and white Soldier creature token with haste for each muster counter on Assemble the Legion.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.MUSTER.createInstance()), TargetController.YOU, false);
- ability.addEffect(new CreateTokenEffect(new SoldierTokenWithHaste(), new CountersSourceCount(CounterType.MUSTER)));
+ ability.addEffect(new CreateTokenEffect(new SoldierTokenWithHaste(), new CountersSourceCount(CounterType.MUSTER)).concatBy("Then"));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AssemblyHall.java b/Mage.Sets/src/mage/cards/a/AssemblyHall.java
index 83960e895e8..b9a5055a3a3 100644
--- a/Mage.Sets/src/mage/cards/a/AssemblyHall.java
+++ b/Mage.Sets/src/mage/cards/a/AssemblyHall.java
@@ -70,7 +70,7 @@ class AssemblyHallEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller == null || controller.getHand().isEmpty() || sourceObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/a/AsylumVisitor.java b/Mage.Sets/src/mage/cards/a/AsylumVisitor.java
index f2b1087ce34..b2011832780 100644
--- a/Mage.Sets/src/mage/cards/a/AsylumVisitor.java
+++ b/Mage.Sets/src/mage/cards/a/AsylumVisitor.java
@@ -41,7 +41,7 @@ public final class AsylumVisitor extends CardImpl {
this.addAbility(ability);
// Madness {1}{B}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{B}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{1}{B}")));
}
private AsylumVisitor(final AsylumVisitor card) {
diff --git a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java
index a86d36f13c0..473912b2e47 100644
--- a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java
+++ b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java
@@ -54,8 +54,7 @@ public final class AtalyaSamiteMaster extends CardImpl {
ability.addTarget(new TargetCreaturePermanent());
// or you gain X life
- Mode mode = new Mode();
- mode.addEffect(new GainLifeEffect(ManacostVariableValue.REGULAR).setText("You gain X life. Spend only white mana on X."));
+ Mode mode = new Mode(new GainLifeEffect(ManacostVariableValue.REGULAR).setText("You gain X life. Spend only white mana on X."));
ability.addMode(mode);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AtarkaEfreet.java b/Mage.Sets/src/mage/cards/a/AtarkaEfreet.java
index d639798fdf8..94b2ee5a42a 100644
--- a/Mage.Sets/src/mage/cards/a/AtarkaEfreet.java
+++ b/Mage.Sets/src/mage/cards/a/AtarkaEfreet.java
@@ -29,7 +29,7 @@ public final class AtarkaEfreet extends CardImpl {
this.toughness = new MageInt(1);
// Megamorph {2}{R}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{R}"), true));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{2}{R}"), true));
// When Atarka Efreet is turned face up, it deals 1 damage to any target.
Effect effect = new DamageTargetEffect(1, "it");
diff --git a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java
index 4eb29bcf77f..219303f4980 100644
--- a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java
+++ b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java
@@ -82,7 +82,7 @@ class AtarkaWorldRenderEffect extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
Permanent attacker = game.getPermanent(event.getSourceId());
if (attacker != null
- && filter.match(attacker, sourceId, controllerId, game)) {
+ && filter.match(attacker, controllerId, this, game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(attacker.getId(), game));
}
diff --git a/Mage.Sets/src/mage/cards/a/AtarkasCommand.java b/Mage.Sets/src/mage/cards/a/AtarkasCommand.java
index 5b999d8b3da..066aec87c35 100644
--- a/Mage.Sets/src/mage/cards/a/AtarkasCommand.java
+++ b/Mage.Sets/src/mage/cards/a/AtarkasCommand.java
@@ -34,20 +34,17 @@ public final class AtarkasCommand extends CardImpl {
this.getSpellAbility().addEffect(new CantGainLifeAllEffect(Duration.EndOfTurn, TargetController.OPPONENT));
// or Atarka's Command deals 3 damage to each opponent;
- Mode mode = new Mode();
- mode.addEffect(new DamagePlayersEffect(3, TargetController.OPPONENT));
+ Mode mode = new Mode(new DamagePlayersEffect(3, TargetController.OPPONENT));
this.getSpellAbility().addMode(mode);
// or You may put a land card from your hand onto the battlefield;
- mode = new Mode();
- mode.addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A));
+ mode = new Mode(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A));
this.getSpellAbility().addMode(mode);
// or Creatures you control get +1/+1 and gain reach until the end of turn.
- mode = new Mode();
Effect effect = new BoostControlledEffect(1, 1, Duration.EndOfTurn);
effect.setText("Creatures you control get +1/+1");
- mode.addEffect(effect);
+ mode = new Mode(effect);
effect = new GainAbilityControlledEffect(ReachAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gain reach until the end of turn");
mode.addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/a/AtemsisAllSeeing.java b/Mage.Sets/src/mage/cards/a/AtemsisAllSeeing.java
index 7f110b7c056..465e9eca161 100644
--- a/Mage.Sets/src/mage/cards/a/AtemsisAllSeeing.java
+++ b/Mage.Sets/src/mage/cards/a/AtemsisAllSeeing.java
@@ -1,6 +1,7 @@
package mage.cards.a;
import mage.MageInt;
+import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToOpponentTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@@ -38,7 +39,7 @@ public final class AtemsisAllSeeing extends CardImpl {
// {2}{U}, {T}: Draw two cards, then discard a card.
Ability ability = new SimpleActivatedAbility(
- new DrawDiscardControllerEffect(2, 1), new ManaCostsImpl("{2}{U}")
+ new DrawDiscardControllerEffect(2, 1), new ManaCostsImpl<>("{2}{U}")
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
@@ -88,7 +89,7 @@ class AtemsisAllSeeingEffect extends OneShotEffect {
.getHand()
.getCards(game)
.stream()
- .map(card -> card.getManaValue())
+ .map(MageObject::getManaValue)
.distinct()
.count() > 5) {
opponent.lost(game);
diff --git a/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java b/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java
index d7fc7e9a137..10764d4ef63 100644
--- a/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java
+++ b/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java
@@ -144,7 +144,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
if (!zEvent.isDiesEvent()) {
return false;
}
- if (zEvent.getTarget() == null || !filter.match(zEvent.getTarget(), sourceId, controllerId, game)) {
+ if (zEvent.getTarget() == null || !filter.match(zEvent.getTarget(), controllerId, this, game)) {
return false;
}
for (Effect effect : this.getEffects()) {
diff --git a/Mage.Sets/src/mage/cards/a/AtsushiTheBlazingSky.java b/Mage.Sets/src/mage/cards/a/AtsushiTheBlazingSky.java
index 803b7100895..84c2e721ca4 100644
--- a/Mage.Sets/src/mage/cards/a/AtsushiTheBlazingSky.java
+++ b/Mage.Sets/src/mage/cards/a/AtsushiTheBlazingSky.java
@@ -41,7 +41,7 @@ public final class AtsushiTheBlazingSky extends CardImpl {
// When Atsushi, the Blazing Sky dies, choose one —
// • Exile the top two cards of your library. Until the end of your next turn, you may play those cards.
Ability ability = new DiesSourceTriggeredAbility(new ExileTopXMayPlayUntilEndOfTurnEffect(
- 3, false, Duration.UntilEndOfYourNextTurn
+ 2, false, Duration.UntilEndOfYourNextTurn
), false);
// • Create three Treasure tokens.
diff --git a/Mage.Sets/src/mage/cards/a/AttendedSocialite.java b/Mage.Sets/src/mage/cards/a/AttendedSocialite.java
new file mode 100644
index 00000000000..a224987a1a7
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AttendedSocialite.java
@@ -0,0 +1,39 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.common.AllianceAbility;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AttendedSocialite extends CardImpl {
+
+ public AttendedSocialite(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.DRUID);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Alliance — Whenever another creature enters the battlefield under your control, Attended Socialite gets +1/+1 until end of turn.
+ this.addAbility(new AllianceAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn)));
+ }
+
+ private AttendedSocialite(final AttendedSocialite card) {
+ super(card);
+ }
+
+ @Override
+ public AttendedSocialite copy() {
+ return new AttendedSocialite(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AudaciousSwap.java b/Mage.Sets/src/mage/cards/a/AudaciousSwap.java
new file mode 100644
index 00000000000..73e6e205f88
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AudaciousSwap.java
@@ -0,0 +1,98 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.CasualtyAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.Predicates;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AudaciousSwap extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterPermanent("nonenchantment permanent");
+
+ static {
+ filter.add(Predicates.not(CardType.ENCHANTMENT.getPredicate()));
+ }
+
+ public AudaciousSwap(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}");
+
+ // Casualty 2
+ this.addAbility(new CasualtyAbility(this, 2));
+
+ // The owner of target nonenchantment permanent shuffles it into their library, then exiles the top card of their library. If it's a land card, they put it onto the battlefield. Otherwise, they may cast it without paying its mana cost.
+ this.getSpellAbility().addEffect(new AudaciousSwapEffect());
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private AudaciousSwap(final AudaciousSwap card) {
+ super(card);
+ }
+
+ @Override
+ public AudaciousSwap copy() {
+ return new AudaciousSwap(this);
+ }
+}
+
+class AudaciousSwapEffect extends OneShotEffect {
+
+ AudaciousSwapEffect() {
+ super(Outcome.Benefit);
+ staticText = "the owner of target nonenchantment permanent shuffles it into their library, then " +
+ "exiles the top card of their library. If it's a land card, they put it onto the battlefield. " +
+ "Otherwise, they may cast it without paying its mana cost";
+ }
+
+ private AudaciousSwapEffect(final AudaciousSwapEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AudaciousSwapEffect copy() {
+ return new AudaciousSwapEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (permanent == null) {
+ return false;
+ }
+ Player player = game.getPlayer(permanent.getOwnerId());
+ if (player == null) {
+ return false;
+ }
+ player.putCardsOnTopOfLibrary(permanent, game, source, false);
+ player.shuffleLibrary(source, game);
+ Card card = player.getLibrary().getFromTop(game);
+ if (card == null) {
+ return true;
+ }
+ player.moveCards(card, Zone.EXILED, source, game);
+ if (!card.isLand(game)) {
+ CardUtil.castSpellWithAttributesForFree(player, source, game, card);
+ return true;
+ }
+ if (player.chooseUse(Outcome.PutLandInPlay, "Put " + card.getName() + " onto the battlefield?", source, game)) {
+ player.moveCards(card, Zone.BATTLEFIELD, source, game);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AugurOfBolas.java b/Mage.Sets/src/mage/cards/a/AugurOfBolas.java
index ded15a1cb91..61f0f9e82b7 100644
--- a/Mage.Sets/src/mage/cards/a/AugurOfBolas.java
+++ b/Mage.Sets/src/mage/cards/a/AugurOfBolas.java
@@ -1,36 +1,22 @@
package mage.cards.a;
import mage.MageInt;
-import mage.MageObject;
-import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
-import mage.cards.*;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
-import mage.filter.common.FilterInstantOrSorceryCard;
-import mage.filter.predicate.Predicates;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.TargetCard;
+import mage.filter.StaticFilters;
-import java.util.Set;
import java.util.UUID;
/**
- * @author jeffwadsworth
+ * @author awjackson
*/
public final class AugurOfBolas extends CardImpl {
- private static final FilterCard filter = new FilterCard("an instant or sorcery card");
-
- static {
- filter.add(Predicates.or(CardType.INSTANT.getPredicate(), CardType.SORCERY.getPredicate()));
- }
-
public AugurOfBolas(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.MERFOLK);
@@ -39,8 +25,11 @@ public final class AugurOfBolas extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(3);
- // When Augur of Bolas enters the battlefield, look at the top three cards of your library. You may reveal an instant or sorcery card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new AugurOfBolasEffect()));
+ // When Augur of Bolas enters the battlefield, look at the top three cards of your library.
+ // You may reveal an instant or sorcery card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in any order.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
+ 3, 1, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, PutCards.HAND, PutCards.BOTTOM_ANY)));
}
private AugurOfBolas(final AugurOfBolas card) {
@@ -52,57 +41,3 @@ public final class AugurOfBolas extends CardImpl {
return new AugurOfBolas(this);
}
}
-
-class AugurOfBolasEffect extends OneShotEffect {
-
- public AugurOfBolasEffect() {
- super(Outcome.DrawCard);
- this.staticText = "look at the top three cards of your library. You may reveal an instant or sorcery card from among them and put it into your hand. Put the rest on the bottom of your library in any order";
- }
-
- public AugurOfBolasEffect(final AugurOfBolasEffect effect) {
- super(effect);
- }
-
- @Override
- public AugurOfBolasEffect copy() {
- return new AugurOfBolasEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
- if (controller != null && sourceObject != null) {
- Cards topCards = new CardsImpl();
- topCards.addAll(controller.getLibrary().getTopCards(game, 3));
- if (!topCards.isEmpty()) {
- controller.lookAtCards(sourceObject.getIdName(), topCards, game);
- int number = topCards.count(new FilterInstantOrSorceryCard(), source.getSourceId(), source.getControllerId(), game);
- if (number > 0) {
- if (controller.chooseUse(outcome, "Reveal an instant or sorcery card from the looked at cards and put it into your hand?", source, game)) {
- Card card = null;
- if (number == 1) {
- Set cards = topCards.getCards(new FilterInstantOrSorceryCard(), source.getSourceId(), source.getControllerId(), game);
- if (!cards.isEmpty()) {
- card = cards.iterator().next();
- }
- } else {
- TargetCard target = new TargetCard(Zone.LIBRARY, new FilterInstantOrSorceryCard());
- controller.chooseTarget(outcome, topCards, target, source, game);
- card = topCards.get(target.getFirstTarget(), game);
- }
- if (card != null) {
- controller.moveCards(card, Zone.HAND, source, game);
- controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game);
- topCards.remove(card);
- }
- }
- }
- controller.putCardsOnBottomOfLibrary(topCards, game, source, true);
- }
- return true;
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/a/AuntiesSnitch.java b/Mage.Sets/src/mage/cards/a/AuntiesSnitch.java
index 7432bd05b7c..a57287ace22 100644
--- a/Mage.Sets/src/mage/cards/a/AuntiesSnitch.java
+++ b/Mage.Sets/src/mage/cards/a/AuntiesSnitch.java
@@ -18,7 +18,6 @@ import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
/**
@@ -83,7 +82,7 @@ class AuntiesSnitchTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event;
Permanent p = game.getPermanent(event.getSourceId());
- return damageEvent.isCombatDamage() && filter.match(p, getSourceId(), getControllerId(), game);
+ return damageEvent.isCombatDamage() && filter.match(p, getControllerId(), this, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AuraBarbs.java b/Mage.Sets/src/mage/cards/a/AuraBarbs.java
index 9fc5d9157e6..175efc7aad2 100644
--- a/Mage.Sets/src/mage/cards/a/AuraBarbs.java
+++ b/Mage.Sets/src/mage/cards/a/AuraBarbs.java
@@ -54,7 +54,7 @@ public final class AuraBarbs extends CardImpl {
FilterPermanent filterEnchantments = new FilterPermanent();
filterEnchantments.add(CardType.ENCHANTMENT.getPredicate());
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source, game)) {
Player controller = game.getPlayer(permanent.getControllerId());
if (controller != null) {
controller.damage(2, permanent.getId(), source, game);
@@ -63,7 +63,7 @@ public final class AuraBarbs extends CardImpl {
}
filterEnchantments.add(SubType.AURA.getPredicate());
- for (Permanent auraEnchantment : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent auraEnchantment : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source, game)) {
if (auraEnchantment.getAttachedTo() != null) {
Permanent attachedToCreature = game.getPermanent(auraEnchantment.getAttachedTo());
if (attachedToCreature != null && attachedToCreature.isCreature(game)) {
diff --git a/Mage.Sets/src/mage/cards/a/AuraFinesse.java b/Mage.Sets/src/mage/cards/a/AuraFinesse.java
index 6322a94a769..8e5416f8c0c 100644
--- a/Mage.Sets/src/mage/cards/a/AuraFinesse.java
+++ b/Mage.Sets/src/mage/cards/a/AuraFinesse.java
@@ -35,13 +35,13 @@ public final class AuraFinesse extends CardImpl {
public AuraFinesse(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}");
-
// Attach target Aura you control to target creature.
this.getSpellAbility().addEffect(new AuraFinesseEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+
// Draw a card.
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
"));
}
private AuraFinesse(final AuraFinesse card) {
@@ -70,26 +70,28 @@ class AuraFinesseEffect extends OneShotEffect {
return new AuraFinesseEffect(this);
}
+ // 15/06/2010 As Aura Finesse resolves, if either target is illegal,
+ // the spell resolves but the Aura doesn’t move. You still draw a card.
+ // If both targets are illegal, Aura Finesse doesn’t resolve and you don’t draw a card.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Permanent aura = game.getPermanent(source.getFirstTarget());
- Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
- if (aura != null && creature != null) {
- Permanent oldCreature = game.getPermanent(aura.getAttachedTo());
- if (oldCreature != null && !oldCreature.equals(creature)) {
- Target auraTarget = aura.getSpellAbility().getTargets().get(0);
- if (!auraTarget.canTarget(creature.getId(), game)) {
- game.informPlayers(aura.getLogName() + " was not attched to " +creature.getLogName() + " because it's no legal target for the aura" );
- } else if (oldCreature.removeAttachment(aura.getId(), source, game)) {
- game.informPlayers(aura.getLogName() + " was unattached from " + oldCreature.getLogName() + " and attached to " + creature.getLogName());
- creature.addAttachment(aura.getId(), source, game);
- }
+ if (controller == null) { return false; }
+
+ Permanent aura = game.getPermanent(source.getFirstTarget());
+ Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
+ if (aura != null && creature != null) {
+ Permanent oldCreature = game.getPermanent(aura.getAttachedTo());
+ if (oldCreature != null && !oldCreature.equals(creature)) {
+ Target auraTarget = aura.getSpellAbility().getTargets().get(0);
+ if (!auraTarget.canTarget(creature.getId(), game)) {
+ game.informPlayers(aura.getLogName() + " was not attched to " +creature.getLogName() + " because it's no legal target for the aura" );
+ } else if (oldCreature.removeAttachment(aura.getId(), source, game)) {
+ game.informPlayers(aura.getLogName() + " was unattached from " + oldCreature.getLogName() + " and attached to " + creature.getLogName());
+ creature.addAttachment(aura.getId(), source, game);
}
}
- return true;
}
- return false;
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AuraGraft.java b/Mage.Sets/src/mage/cards/a/AuraGraft.java
index 27fad23790d..82397b57a6e 100644
--- a/Mage.Sets/src/mage/cards/a/AuraGraft.java
+++ b/Mage.Sets/src/mage/cards/a/AuraGraft.java
@@ -123,8 +123,8 @@ class MoveTargetAuraEffect extends OneShotEffect {
filter.add(new PermanentCanBeAttachedToPredicate(enchantment));
Target target = new TargetPermanent(filter);
target.setNotTarget(true);
- if (target.canChoose(oldAttachment.getId(), controller.getId(), game)
- && controller.choose(outcome, target, oldAttachment.getId(), game)) {
+ if (target.canChoose(controller.getId(), source, game)
+ && controller.choose(outcome, target, source, game)) {
Permanent newAttachment = game.getPermanent(target.getFirstTarget());
if (newAttachment != null
&& oldAttachment.removeAttachment(enchantment.getId(), source, game)) {
diff --git a/Mage.Sets/src/mage/cards/a/AuraThief.java b/Mage.Sets/src/mage/cards/a/AuraThief.java
index 792ea8b9874..90026e5f609 100644
--- a/Mage.Sets/src/mage/cards/a/AuraThief.java
+++ b/Mage.Sets/src/mage/cards/a/AuraThief.java
@@ -71,7 +71,7 @@ class AuraThiefDiesTriggeredEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
boolean ret = false;
- for(Permanent enchantment : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_ENCHANTMENT, source.getControllerId(), source.getControllerId(), game)) {
+ for(Permanent enchantment : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_ENCHANTMENT, source.getControllerId(), source, game)) {
ContinuousEffect gainControl = new GainControlTargetEffect(Duration.EndOfGame);
gainControl.setTargetPointer(new FixedTarget(enchantment.getId(), game));
game.addEffect(gainControl, source);
diff --git a/Mage.Sets/src/mage/cards/a/Auramancer.java b/Mage.Sets/src/mage/cards/a/Auramancer.java
index 6b1d939754c..9319cadce9d 100644
--- a/Mage.Sets/src/mage/cards/a/Auramancer.java
+++ b/Mage.Sets/src/mage/cards/a/Auramancer.java
@@ -1,12 +1,9 @@
-
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -14,6 +11,8 @@ import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
* @author Loki
*/
@@ -26,13 +25,13 @@ public final class Auramancer extends CardImpl {
}
public Auramancer(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true);
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), true);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AureliasFury.java b/Mage.Sets/src/mage/cards/a/AureliasFury.java
index 5d5e32a7c5d..3ce2d3b5357 100644
--- a/Mage.Sets/src/mage/cards/a/AureliasFury.java
+++ b/Mage.Sets/src/mage/cards/a/AureliasFury.java
@@ -140,7 +140,7 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ')';
}
diff --git a/Mage.Sets/src/mage/cards/a/AuriokEdgewright.java b/Mage.Sets/src/mage/cards/a/AuriokEdgewright.java
index 87522791a94..55aa47616c4 100644
--- a/Mage.Sets/src/mage/cards/a/AuriokEdgewright.java
+++ b/Mage.Sets/src/mage/cards/a/AuriokEdgewright.java
@@ -19,7 +19,7 @@ import java.util.UUID;
*/
public final class AuriokEdgewright extends CardImpl {
- protected static String effectText = "Metalcraft — Auriok Edgewright has double strike as long as you control three or more artifacts.";
+ private static final String effectText = "{this} has double strike as long as you control three or more artifacts.";
public AuriokEdgewright(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}");
diff --git a/Mage.Sets/src/mage/cards/a/AuriokSiegeSled.java b/Mage.Sets/src/mage/cards/a/AuriokSiegeSled.java
index 4c859bc0dbd..bb360508011 100644
--- a/Mage.Sets/src/mage/cards/a/AuriokSiegeSled.java
+++ b/Mage.Sets/src/mage/cards/a/AuriokSiegeSled.java
@@ -1,11 +1,10 @@
-
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.combat.CantBeBlockedByTargetSourceEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByTargetSourceEffect;
import mage.cards.CardImpl;
@@ -13,8 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -23,12 +21,6 @@ import mage.target.common.TargetCreaturePermanent;
*/
public final class AuriokSiegeSled extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creature");
-
- static {
- filter.add(CardType.ARTIFACT.getPredicate());
- }
-
public AuriokSiegeSled(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}");
this.subtype.add(SubType.JUGGERNAUT);
@@ -37,15 +29,17 @@ public final class AuriokSiegeSled extends CardImpl {
// {1}: Target artifact creature blocks Auriok Siege Sled this turn if able.
MustBeBlockedByTargetSourceEffect effect = new MustBeBlockedByTargetSourceEffect(Duration.EndOfTurn);
- effect.setText("Target artifact creature blocks {this} this turn if able.");
- Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}"));
- ability1.addTarget(new TargetCreaturePermanent(filter));
+ effect.setText("target artifact creature blocks {this} this turn if able");
+ Ability ability1 = new SimpleActivatedAbility(effect, new GenericManaCost(1));
+ ability1.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_CREATURE));
this.addAbility(ability1);
// {1}: Target artifact creature can't block Auriok Siege Sled this turn.
- Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedByTargetSourceEffect(Duration.EndOfTurn),
- new ManaCostsImpl("{1}"));
- ability2.addTarget(new TargetCreaturePermanent(filter));
+ Ability ability2 = new SimpleActivatedAbility(
+ new CantBeBlockedByTargetSourceEffect(Duration.EndOfTurn),
+ new GenericManaCost(1)
+ );
+ ability2.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_CREATURE));
this.addAbility(ability2);
}
diff --git a/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java b/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java
index 0d33dabdcc4..3aeda316adf 100644
--- a/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java
+++ b/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java
@@ -2,7 +2,6 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageControllerEffect;
@@ -38,7 +37,7 @@ public final class AurraSingBaneOfJedi extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AURRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: You may have {this} deal 2 damage to target creature. If you don't, {this} deals 1 damage to you.
Ability ability = new LoyaltyAbility(new AurraSingBaneOfJediEffect(), +1);
@@ -112,7 +111,7 @@ class SacrificeAllEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- List permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getId(), game);
+ List permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source, game);
for (Permanent p : permanents) {
p.sacrifice(source, game);
}
diff --git a/Mage.Sets/src/mage/cards/a/AustereCommand.java b/Mage.Sets/src/mage/cards/a/AustereCommand.java
index 5f0a0950bf2..0890190d8a9 100644
--- a/Mage.Sets/src/mage/cards/a/AustereCommand.java
+++ b/Mage.Sets/src/mage/cards/a/AustereCommand.java
@@ -36,16 +36,13 @@ public final class AustereCommand extends CardImpl {
// Destroy all artifacts;
this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterArtifactPermanent("artifacts")));
// or destroy all enchantments;
- Mode mode = new Mode();
- mode.addEffect(new DestroyAllEffect(new FilterEnchantmentPermanent("enchantments")));
+ Mode mode = new Mode(new DestroyAllEffect(new FilterEnchantmentPermanent("enchantments")));
this.getSpellAbility().getModes().addMode(mode);
// or destroy all creatures with converted mana cost 3 or less;
- mode = new Mode();
- mode.addEffect(new DestroyAllEffect(filter3orLess));
+ mode = new Mode(new DestroyAllEffect(filter3orLess));
this.getSpellAbility().getModes().addMode(mode);
// or destroy all creatures with converted mana cost 4 or greater.
- mode = new Mode();
- mode.addEffect(new DestroyAllEffect(filter4orMore));
+ mode = new Mode(new DestroyAllEffect(filter4orMore));
this.getSpellAbility().getModes().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AuthorityOfTheConsuls.java b/Mage.Sets/src/mage/cards/a/AuthorityOfTheConsuls.java
index 5ad578250d3..505feb03a18 100644
--- a/Mage.Sets/src/mage/cards/a/AuthorityOfTheConsuls.java
+++ b/Mage.Sets/src/mage/cards/a/AuthorityOfTheConsuls.java
@@ -7,8 +7,7 @@ import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.FilterPermanent;
-import mage.filter.common.FilterOpponentsCreaturePermanent;
+import mage.filter.StaticFilters;
import java.util.UUID;
@@ -17,19 +16,16 @@ import java.util.UUID;
*/
public final class AuthorityOfTheConsuls extends CardImpl {
- private static final FilterPermanent filter
- = new FilterOpponentsCreaturePermanent("creatures your opponents control");
-
public AuthorityOfTheConsuls(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
// Creatures your opponents control enter the battlefield tapped.
- this.addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(filter)));
+ this.addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES)));
// Whenever a creature enters the battlefield under an opponent's control, you gain 1 life.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
- new GainLifeEffect(1), filter, "Whenever a creature enters " +
- "the battlefield under an opponent's control, you gain 1 life."
+ new GainLifeEffect(1), StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES,
+ "Whenever a creature enters the battlefield under an opponent's control, you gain 1 life."
));
}
diff --git a/Mage.Sets/src/mage/cards/a/AutomatedArtificer.java b/Mage.Sets/src/mage/cards/a/AutomatedArtificer.java
new file mode 100644
index 00000000000..e39f0d2b9c1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AutomatedArtificer.java
@@ -0,0 +1,101 @@
+package mage.cards.a;
+
+import mage.ConditionalMana;
+import mage.MageInt;
+import mage.MageObject;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.mana.ConditionalColorlessManaAbility;
+import mage.abilities.mana.builder.ConditionalManaBuilder;
+import mage.abilities.mana.conditional.ManaCondition;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.game.command.Commander;
+import mage.game.stack.StackObject;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AutomatedArtificer extends CardImpl {
+
+ public AutomatedArtificer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
+
+ this.subtype.add(SubType.ARTIFICER);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(3);
+
+ // {T}: Add {C}. Spend this mana only to activate an ability or cast an artifact spell.
+ this.addAbility(new ConditionalColorlessManaAbility(
+ new TapSourceCost(), 1, new AutomatedArtificerManaBuilder()
+ ));
+ }
+
+ private AutomatedArtificer(final AutomatedArtificer card) {
+ super(card);
+ }
+
+ @Override
+ public AutomatedArtificer copy() {
+ return new AutomatedArtificer(this);
+ }
+}
+
+class AutomatedArtificerManaBuilder extends ConditionalManaBuilder {
+
+ @Override
+ public ConditionalMana build(Object... options) {
+ return new AutomatedArtificerConditionalMana(this.mana);
+ }
+
+ @Override
+ public String getRule() {
+ return "Spend this mana only to activate an ability or cast an artifact spell";
+ }
+}
+
+class AutomatedArtificerConditionalMana extends ConditionalMana {
+
+ AutomatedArtificerConditionalMana(Mana mana) {
+ super(mana);
+ staticText = "Spend this mana only to activate an ability or cast an artifact spell";
+ addCondition(new AutomatedArtificerManaCondition());
+ }
+}
+
+class AutomatedArtificerManaCondition extends ManaCondition {
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (source == null) {
+ return false;
+ }
+ switch (source.getAbilityType()) {
+ case MANA:
+ case ACTIVATED:
+ return true;
+ case SPELL:
+ MageObject object = source.getSourceObject(game);
+ if (!(object instanceof StackObject) && !game.inCheckPlayableState()) {
+ return false;
+ }
+ if (object instanceof Commander) {
+ return ((Commander) object).getSourceObject().isArtifact(game);
+ }
+ return object.isArtifact(game);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, UUID originalId, Cost costsToPay) {
+ return apply(game, source);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AutumnWillow.java b/Mage.Sets/src/mage/cards/a/AutumnWillow.java
index 8ee5b02cfd5..e7bd1c7ba35 100644
--- a/Mage.Sets/src/mage/cards/a/AutumnWillow.java
+++ b/Mage.Sets/src/mage/cards/a/AutumnWillow.java
@@ -70,14 +70,9 @@ class AutumnWillowEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
- if (affectedControllerId.equals(source.getFirstTarget())) {
- Permanent creature = game.getPermanent(sourceId);
- if (creature != null) {
- if (sourceId.equals(source.getSourceId())) {
- return true;
- }
- }
- }
- return false;
+ if (!affectedControllerId.equals(source.getFirstTarget())) { return false; }
+ Permanent creature = game.getPermanent(sourceId);
+
+ return creature != null &&sourceId.equals(source.getSourceId());
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AvacynsJudgment.java b/Mage.Sets/src/mage/cards/a/AvacynsJudgment.java
index 3fe86e5fb30..c13154d5ae3 100644
--- a/Mage.Sets/src/mage/cards/a/AvacynsJudgment.java
+++ b/Mage.Sets/src/mage/cards/a/AvacynsJudgment.java
@@ -25,7 +25,7 @@ public final class AvacynsJudgment extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{R}");
// Madness {X}{R}
- Ability ability = new MadnessAbility(this, new ManaCostsImpl("{X}{R}"));
+ Ability ability = new MadnessAbility(new ManaCostsImpl("{X}{R}"));
ability.setRuleAtTheTop(true);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java b/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java
index 47e4137ed23..31a47150ab3 100644
--- a/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java
+++ b/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java
@@ -66,9 +66,6 @@ class AvatarOfWoeCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- if (AvatarOfWoe.graveyardCount.calculate(game, source, null) >= 10) {
- return true;
- }
- return false;
+ return AvatarOfWoe.graveyardCount.calculate(game, source, null) >= 10;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AvenCourier.java b/Mage.Sets/src/mage/cards/a/AvenCourier.java
new file mode 100644
index 00000000000..559b52d0fdb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AvenCourier.java
@@ -0,0 +1,119 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.choices.Choice;
+import mage.choices.ChoiceImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetControlledPermanent;
+import mage.util.CardUtil;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class AvenCourier extends CardImpl {
+
+ public AvenCourier(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
+
+ this.subtype.add(SubType.BIRD);
+ this.subtype.add(SubType.ADVISOR);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Aven Courier attacks, choose a counter on a permanent you control. Put a counter of that kind on target permanent you control if it doesn't have a counter of that kind on it.
+ Ability ability = new AttacksTriggeredAbility(new AvenCourierEffect());
+ ability.addTarget(new TargetControlledPermanent());
+ this.addAbility(ability);
+ }
+
+ private AvenCourier(final AvenCourier card) {
+ super(card);
+ }
+
+ @Override
+ public AvenCourier copy() {
+ return new AvenCourier(this);
+ }
+}
+
+class AvenCourierEffect extends OneShotEffect {
+
+ AvenCourierEffect() {
+ super(Outcome.Benefit);
+ staticText = "choose a counter on a permanent you control. Put a counter of that kind " +
+ "on target permanent you control if it doesn't have a counter of that kind on it";
+ }
+
+ private AvenCourierEffect(final AvenCourierEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AvenCourierEffect copy() {
+ return new AvenCourierEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (player == null || permanent == null) {
+ return false;
+ }
+ Set counterTypes = game
+ .getBattlefield()
+ .getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_PERMANENT,
+ source.getControllerId(), source, game
+ ).stream()
+ .map(p -> p.getCounters(game))
+ .map(HashMap::keySet)
+ .flatMap(Collection::stream)
+ .distinct()
+ .collect(Collectors.toSet());
+ String counterType;
+ switch (counterTypes.size()) {
+ case 0:
+ return false;
+ case 1:
+ counterType = counterTypes.iterator().next();
+ break;
+ case 2:
+ Iterator iterator = counterTypes.iterator();
+ String type1 = iterator.next();
+ String type2 = iterator.next();
+ counterType = player.chooseUse(
+ outcome, "Choose a counter to put on " + permanent.getName(), null,
+ CardUtil.getTextWithFirstCharUpperCase(type1),
+ CardUtil.getTextWithFirstCharUpperCase(type2), source, game
+ ) ? type1 : type2;
+ break;
+ default:
+ Choice choice = new ChoiceImpl(true);
+ choice.setChoices(counterTypes);
+ player.choose(outcome, choice, game);
+ counterType = choice.getChoice();
+ }
+ return permanent.getCounters(game).getCount(counterType) < 1
+ && permanent.addCounters(CounterType.findByName(counterType).createInstance(), source, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AvenHeartstabber.java b/Mage.Sets/src/mage/cards/a/AvenHeartstabber.java
new file mode 100644
index 00000000000..a276b93fce0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AvenHeartstabber.java
@@ -0,0 +1,66 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesSourceTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.common.DifferentManaValuesInGraveCondition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.MillCardsControllerEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.hint.common.DifferentManaValuesInGraveHint;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AvenHeartstabber extends CardImpl {
+
+ public AvenHeartstabber(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}");
+
+ this.subtype.add(SubType.BIRD);
+ this.subtype.add(SubType.ASSASSIN);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // As long as there are five or more mana values among cards in your graveyard, Aven Heartstabber gets +2/+2 and has deathtouch.
+ Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield),
+ DifferentManaValuesInGraveCondition.FIVE, "as long as there are five " +
+ "or more mana values among cards in your graveyard, {this} gets +2/+2"
+ ));
+ ability.addEffect(new ConditionalContinuousEffect(
+ new GainAbilitySourceEffect(DeathtouchAbility.getInstance()),
+ DifferentManaValuesInGraveCondition.FIVE, "and has deathtouch"
+ ));
+ this.addAbility(ability.addHint(DifferentManaValuesInGraveHint.instance));
+
+ // When Aven Heartstabber dies, mill two cards, then draw a card.
+ ability = new DiesSourceTriggeredAbility(new MillCardsControllerEffect(2));
+ ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy(", then"));
+ this.addAbility(ability);
+ }
+
+ private AvenHeartstabber(final AvenHeartstabber card) {
+ super(card);
+ }
+
+ @Override
+ public AvenHeartstabber copy() {
+ return new AvenHeartstabber(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AvenLiberator.java b/Mage.Sets/src/mage/cards/a/AvenLiberator.java
index ec0647ce4c0..18deae5c05a 100644
--- a/Mage.Sets/src/mage/cards/a/AvenLiberator.java
+++ b/Mage.Sets/src/mage/cards/a/AvenLiberator.java
@@ -32,7 +32,7 @@ public final class AvenLiberator extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Morph {3}{W}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{W}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{3}{W}")));
// When Aven Liberator is turned face up, target creature you control gains protection from the color of your choice until end of turn.
Ability ability = new TurnedFaceUpSourceTriggeredAbility(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn));
ability.addTarget(new TargetControlledCreaturePermanent());
diff --git a/Mage.Sets/src/mage/cards/a/AvenShrine.java b/Mage.Sets/src/mage/cards/a/AvenShrine.java
index 43bd4c8b79a..fa652eef316 100644
--- a/Mage.Sets/src/mage/cards/a/AvenShrine.java
+++ b/Mage.Sets/src/mage/cards/a/AvenShrine.java
@@ -90,7 +90,7 @@ class AvenShrineEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int count = 0;
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if(mageObject != null) {
Spell spell = (Spell) game.getState().getValue("avenShrine" + mageObject);
if (spell != null) {
diff --git a/Mage.Sets/src/mage/cards/a/AvenSoulgazer.java b/Mage.Sets/src/mage/cards/a/AvenSoulgazer.java
index 1fae3a76be9..647c2d9c61c 100644
--- a/Mage.Sets/src/mage/cards/a/AvenSoulgazer.java
+++ b/Mage.Sets/src/mage/cards/a/AvenSoulgazer.java
@@ -81,7 +81,7 @@ class AvenSoulgazerLookFaceDownEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (player == null || mageObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/a/AvenSunstriker.java b/Mage.Sets/src/mage/cards/a/AvenSunstriker.java
index c75cb4a63a9..aa2765914e0 100644
--- a/Mage.Sets/src/mage/cards/a/AvenSunstriker.java
+++ b/Mage.Sets/src/mage/cards/a/AvenSunstriker.java
@@ -30,7 +30,7 @@ public final class AvenSunstriker extends CardImpl {
// Double strike
this.addAbility(DoubleStrikeAbility.getInstance());
// Megamorph {4}{W}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{4}{W}"), true));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{4}{W}"), true));
}
private AvenSunstriker(final AvenSunstriker card) {
diff --git a/Mage.Sets/src/mage/cards/a/AvenSurveyor.java b/Mage.Sets/src/mage/cards/a/AvenSurveyor.java
index 986226eb057..a0799a1ab36 100644
--- a/Mage.Sets/src/mage/cards/a/AvenSurveyor.java
+++ b/Mage.Sets/src/mage/cards/a/AvenSurveyor.java
@@ -37,8 +37,7 @@ public final class AvenSurveyor extends CardImpl {
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
// * Return target creature to its owner's hand
- Mode mode = new Mode();
- mode.addEffect(new ReturnToHandTargetEffect());
+ Mode mode = new Mode(new ReturnToHandTargetEffect());
mode.addTarget(new TargetCreaturePermanent());
ability.addMode(mode);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AvenTrailblazer.java b/Mage.Sets/src/mage/cards/a/AvenTrailblazer.java
index dffb4444326..9954e2607bc 100644
--- a/Mage.Sets/src/mage/cards/a/AvenTrailblazer.java
+++ b/Mage.Sets/src/mage/cards/a/AvenTrailblazer.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DomainValue;
@@ -10,19 +8,17 @@ import mage.abilities.hint.common.DomainHint;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.SubType;
-import mage.constants.Zone;
+import mage.constants.*;
+
+import java.util.UUID;
/**
- *
* @author jeffwadsworth
*/
public final class AvenTrailblazer extends CardImpl {
public AvenTrailblazer(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.BIRD);
this.subtype.add(SubType.SOLDIER);
@@ -31,10 +27,12 @@ public final class AvenTrailblazer extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
-
+
// Domain - Aven Trailblazer's toughness is equal to the number of basic land types among lands you control.
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetToughnessSourceEffect(new DomainValue(), Duration.EndOfGame)).addHint(DomainHint.instance));
-
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new SetToughnessSourceEffect(DomainValue.REGULAR, Duration.EndOfGame)
+ .setText("{this}'s toughness is equal to the number of basic land types among lands you control")
+ ).addHint(DomainHint.instance).setAbilityWord(AbilityWord.DOMAIN));
}
private AvenTrailblazer(final AvenTrailblazer card) {
diff --git a/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java b/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java
index 4352f6c7813..fce92d1a56d 100644
--- a/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java
+++ b/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -6,14 +5,13 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@@ -23,7 +21,7 @@ import mage.filter.predicate.Predicates;
*/
public final class AzcantaTheSunkenRuin extends CardImpl {
- private static final FilterCard filter = new FilterCard("noncreature, nonland card");
+ private static final FilterCard filter = new FilterCard("a noncreature, nonland card");
static {
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
@@ -44,11 +42,8 @@ public final class AzcantaTheSunkenRuin extends CardImpl {
// {2}{U} , {T} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
Ability ability = new SimpleActivatedAbility(
- Zone.BATTLEFIELD,
- new LookLibraryAndPickControllerEffect(
- StaticValue.get(4), false, StaticValue.get(1),
- filter, Zone.LIBRARY, false, true, true
- ), new ManaCostsImpl<>("{2}{U}")
+ new LookLibraryAndPickControllerEffect(4, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY),
+ new ManaCostsImpl<>("{2}{U}")
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java b/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java
index 49c90ae4d72..4a1b428af29 100644
--- a/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java
+++ b/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java
@@ -113,7 +113,7 @@ class AzorTheLawbringerCantCastEffect extends ContinuousRuleModifyingEffectImpl
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't cast instant or sorcery spells this turn (" + mageObject.getIdName() + ").";
}
diff --git a/Mage.Sets/src/mage/cards/a/AzoriusAethermage.java b/Mage.Sets/src/mage/cards/a/AzoriusAethermage.java
index 333f7855d93..10a0b598ab1 100644
--- a/Mage.Sets/src/mage/cards/a/AzoriusAethermage.java
+++ b/Mage.Sets/src/mage/cards/a/AzoriusAethermage.java
@@ -11,7 +11,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
@@ -24,8 +24,6 @@ import java.util.UUID;
*/
public final class AzoriusAethermage extends CardImpl {
- private static final String rule = "Whenever a permanent is returned to your hand, ";
-
public AzoriusAethermage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
@@ -35,8 +33,8 @@ public final class AzoriusAethermage extends CardImpl {
this.toughness = new MageInt(1);
// Whenever a permanent is returned to your hand, you may pay {1}. If you do, draw a card.
- Effect effect = new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}"));
- this.addAbility(new AzoriusAEthermageAbility(Zone.BATTLEFIELD, Zone.BATTLEFIELD, Zone.HAND, effect, new FilterPermanent(), rule, false));
+ Effect effect = new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}"));
+ this.addAbility(new AzoriusAEthermageAbility(effect));
}
private AzoriusAethermage(final AzoriusAethermage card) {
@@ -51,25 +49,14 @@ public final class AzoriusAethermage extends CardImpl {
class AzoriusAEthermageAbility extends TriggeredAbilityImpl {
- protected FilterPermanent filter;
- protected Zone fromZone;
- protected Zone toZone;
- protected String rule;
+ private static final String rule = "Whenever a permanent is returned to your hand, ";
- public AzoriusAEthermageAbility(Zone zone, Zone fromZone, Zone toZone, Effect effect, FilterPermanent filter, String rule, boolean optional) {
- super(zone, effect, optional);
- this.fromZone = fromZone;
- this.toZone = toZone;
- this.rule = rule;
- this.filter = filter;
+ public AzoriusAEthermageAbility(Effect effect) {
+ super(Zone.BATTLEFIELD, effect, false);
}
- public AzoriusAEthermageAbility(final AzoriusAEthermageAbility ability) {
+ private AzoriusAEthermageAbility(final AzoriusAEthermageAbility ability) {
super(ability);
- this.fromZone = ability.fromZone;
- this.toZone = ability.toZone;
- this.rule = ability.rule;
- this.filter = ability.filter;
}
@Override
@@ -80,35 +67,29 @@ class AzoriusAEthermageAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- if ((fromZone == null || zEvent.getFromZone() == fromZone)
- && (toZone == null || zEvent.getToZone() == toZone)) {
- Permanent permanentThatMoved = null;
- if (zEvent.getTarget() != null) {
- permanentThatMoved = zEvent.getTarget();
- }
- //The controller's hand is where the permanent moved to.
- return permanentThatMoved != null
- && filter.match(permanentThatMoved, sourceId, controllerId, game)
- && zEvent.getPlayerId().equals(controllerId);
+ if (zEvent.getFromZone() != Zone.BATTLEFIELD || zEvent.getToZone() != Zone.HAND) {
+ return false;
}
- return false;
+
+ if (!zEvent.getPlayerId().equals(controllerId)) {
+ return false;
+ }
+
+ Permanent permanentThatMoved = zEvent.getTarget();
+ if (permanentThatMoved == null) {
+ return false;
+ }
+
+ return StaticFilters.FILTER_PERMANENT_CREATURE.match(permanentThatMoved, controllerId, this, game);
}
@Override
public String getTriggerPhrase() {
- return rule ;
+ return rule;
}
@Override
public AzoriusAEthermageAbility copy() {
return new AzoriusAEthermageAbility(this);
}
-
- public Zone getFromZone() {
- return fromZone;
- }
-
- public Zone getToZone() {
- return toZone;
- }
}
diff --git a/Mage.Sets/src/mage/cards/a/AzoriusCharm.java b/Mage.Sets/src/mage/cards/a/AzoriusCharm.java
index aa364fe42d3..1f44849bf43 100644
--- a/Mage.Sets/src/mage/cards/a/AzoriusCharm.java
+++ b/Mage.Sets/src/mage/cards/a/AzoriusCharm.java
@@ -28,14 +28,12 @@ public final class AzoriusCharm extends CardImpl {
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn, new FilterControlledCreaturePermanent("Creatures")));
// or draw a card;
- Mode mode = new Mode();
- mode.addEffect(new DrawCardSourceControllerEffect(1));
+ Mode mode = new Mode(new DrawCardSourceControllerEffect(1));
this.getSpellAbility().addMode(mode);
// or put target attacking or blocking creature on top of its owner's library.
- mode = new Mode();
+ mode = new Mode(new PutOnLibraryTargetEffect(true));
mode.addTarget(new TargetAttackingOrBlockingCreature());
- mode.addEffect(new PutOnLibraryTargetEffect(true));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/AzoriusJusticiar.java b/Mage.Sets/src/mage/cards/a/AzoriusJusticiar.java
index 97376007acf..fc23e4a143e 100644
--- a/Mage.Sets/src/mage/cards/a/AzoriusJusticiar.java
+++ b/Mage.Sets/src/mage/cards/a/AzoriusJusticiar.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -10,9 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.TargetController;
-import mage.filter.common.FilterCreaturePermanent;
-import mage.target.common.TargetCreaturePermanent;
+import mage.target.common.TargetOpponentsCreaturePermanent;
/**
*
@@ -20,12 +17,6 @@ import mage.target.common.TargetCreaturePermanent;
*/
public final class AzoriusJusticiar extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public AzoriusJusticiar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}");
this.subtype.add(SubType.HUMAN);
@@ -37,7 +28,7 @@ public final class AzoriusJusticiar extends CardImpl {
// When Azorius Justiciar enters the battlefield, detain up to two target creatures your opponents control.
// (Until your next turn, those creatures can't attack or block and their activated abilities can't be activated.)
Ability ability = new EntersBattlefieldTriggeredAbility(new DetainTargetEffect());
- ability.addTarget(new TargetCreaturePermanent(0,2,filter,false));
+ ability.addTarget(new TargetOpponentsCreaturePermanent(0, 2));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AzorsGateway.java b/Mage.Sets/src/mage/cards/a/AzorsGateway.java
index 9e97185af0c..18e42b3e952 100644
--- a/Mage.Sets/src/mage/cards/a/AzorsGateway.java
+++ b/Mage.Sets/src/mage/cards/a/AzorsGateway.java
@@ -38,7 +38,9 @@ public final class AzorsGateway extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.secondSideCardClazz = mage.cards.s.SanctumOfTheSun.class;
- // {1}, {T}: Draw a card, then exile a card from your hand. If cards with five or more different converted mana costs are exiled with Azor's Gateway, you gain 5 life, untap Azor's Gateway, and transform it.
+ // {1}, {T}: Draw a card, then exile a card from your hand.
+ // If cards with five or more different converted mana costs are exiled with Azor's Gateway,
+ // you gain 5 life, untap Azor's Gateway, and transform it.
this.addAbility(new TransformAbility());
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AzorsGatewayEffect(), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
@@ -59,7 +61,9 @@ class AzorsGatewayEffect extends OneShotEffect {
public AzorsGatewayEffect() {
super(Outcome.Benefit);
- this.staticText = "Draw a card, then exile a card from your hand. If cards with five or more different mana values are exiled with {this}, you gain 5 life, untap Azor's Gateway, and transform it";
+ this.staticText = "Draw a card, then exile a card from your hand. " +
+ "If cards with five or more different mana values are exiled with {this}, " +
+ "you gain 5 life, untap Azor's Gateway, and transform it";
}
public AzorsGatewayEffect(final AzorsGatewayEffect effect) {
@@ -74,30 +78,32 @@ class AzorsGatewayEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- UUID exileId = CardUtil.getCardExileZoneId(game, source);
+ if (controller == null) { return false; }
+
MageObject sourceObject = source.getSourceObject(game);
- if (controller != null && exileId != null && sourceObject != null) {
- controller.drawCards(1, source, game);
- TargetCardInHand target = new TargetCardInHand();
- controller.choose(outcome, target, source.getSourceId(), game);
- Card cardToExile = game.getCard(target.getFirstTarget());
- if (cardToExile != null) {
- controller.moveCardsToExile(cardToExile, source, game, true, exileId, sourceObject.getIdName());
- }
- Set usedCMC = new HashSet<>();
- ExileZone exileZone = game.getExile().getExileZone(exileId);
- if (exileZone != null) {
- for (Card card : exileZone.getCards(game)) {
- usedCMC.add(card.getManaValue());
- }
- if (usedCMC.size() > 4) {
- controller.gainLife(4, game, source);
- new UntapSourceEffect().apply(game, source);
- new TransformSourceEffect().apply(game, source);
- }
- }
- return true;
+ if (sourceObject == null) { return false; }
+
+ UUID exileId = CardUtil.getCardExileZoneId(game, source);
+
+ controller.drawCards(1, source, game);
+ TargetCardInHand target = new TargetCardInHand();
+ controller.choose(outcome, target, source, game);
+ Card cardToExile = game.getCard(target.getFirstTarget());
+ if (cardToExile != null) {
+ controller.moveCardsToExile(cardToExile, source, game, true, exileId, sourceObject.getIdName());
}
- return false;
+ Set usedCMC = new HashSet<>();
+ ExileZone exileZone = game.getExile().getExileZone(exileId);
+ if (exileZone != null) {
+ for (Card card : exileZone.getCards(game)) {
+ usedCMC.add(card.getManaValue());
+ }
+ if (usedCMC.size() > 4) {
+ controller.gainLife(4, game, source);
+ new UntapSourceEffect().apply(game, source);
+ new TransformSourceEffect().apply(game, source);
+ }
+ }
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java b/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java
index 4a73bdf6af4..46ec46c4431 100644
--- a/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java
+++ b/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java
@@ -75,7 +75,7 @@ class AzraBladeseekerEffect extends OneShotEffect {
continue;
}
Target target = new TargetDiscard(playerId);
- if (target.choose(Outcome.DrawCard, playerId, source.getSourceId(), game)) {
+ if (target.choose(Outcome.DrawCard, playerId, source.getSourceId(), source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
playerCardList.add(new PlayerCard(player, card));
diff --git a/Mage.Sets/src/mage/cards/a/AzraOddsmaker.java b/Mage.Sets/src/mage/cards/a/AzraOddsmaker.java
index c119b222b78..28f4dc7f6b7 100644
--- a/Mage.Sets/src/mage/cards/a/AzraOddsmaker.java
+++ b/Mage.Sets/src/mage/cards/a/AzraOddsmaker.java
@@ -82,7 +82,7 @@ class AzraOddsmakerEffect extends OneShotEffect {
Permanent permanent = null;
TargetCreaturePermanent target = new TargetCreaturePermanent();
target.setNotTarget(true);
- if (player.choose(Outcome.DrawCard, target, source.getSourceId(), game)) {
+ if (player.choose(Outcome.DrawCard, target, source, game)) {
permanent = game.getPermanent(target.getFirstTarget());
}
if (permanent == null) {
diff --git a/Mage.Sets/src/mage/cards/b/BINGO.java b/Mage.Sets/src/mage/cards/b/BINGO.java
index c02556c1903..979e459faa3 100644
--- a/Mage.Sets/src/mage/cards/b/BINGO.java
+++ b/Mage.Sets/src/mage/cards/b/BINGO.java
@@ -83,7 +83,7 @@ class BingoEffect extends OneShotEffect {
if (spell.getManaValue() > 9) {
return true;
}
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
Map chipCounters = new HashMap<>(); // Map
if (game.getState().getValue(mageObject.getId() + "_chip") != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java b/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java
index 54c0b94a254..7f326f2d9b3 100644
--- a/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java
+++ b/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java
@@ -67,12 +67,12 @@ class BackFromTheBrinkCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return targets.canChoose(source.getSourceId(), controllerId, game);
+ return targets.canChoose(controllerId, source, game);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
- if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), game)) {
+ if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), source, game)) {
Player controller = game.getPlayer(controllerId);
if (controller != null) {
Card card = controller.getGraveyard().get(targets.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/cards/b/Backfire.java b/Mage.Sets/src/mage/cards/b/Backfire.java
index e9948284cbc..57e3fdf6cf7 100644
--- a/Mage.Sets/src/mage/cards/b/Backfire.java
+++ b/Mage.Sets/src/mage/cards/b/Backfire.java
@@ -1,10 +1,8 @@
-
package mage.cards.b;
import java.util.UUID;
-import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility;
-import mage.abilities.dynamicvalue.common.NumericSetToEffectValues;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DamageAttachedControllerEffect;
import mage.abilities.keyword.EnchantAbility;
@@ -32,11 +30,10 @@ public final class Backfire extends CardImpl {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// Whenever enchanted creature deals damage to you, Backfire deals that much damage to that creature's controller.
- this.addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new DamageAttachedControllerEffect(new NumericSetToEffectValues("that much", "damage")), "enchanted creature", false, true, false, TargetController.YOU));
+ this.addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new DamageAttachedControllerEffect(SavedDamageValue.MUCH), "enchanted creature", false, true, false, TargetController.YOU));
}
private Backfire(final Backfire card) {
diff --git a/Mage.Sets/src/mage/cards/b/BackstreetBruiser.java b/Mage.Sets/src/mage/cards/b/BackstreetBruiser.java
new file mode 100644
index 00000000000..80419d64518
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BackstreetBruiser.java
@@ -0,0 +1,71 @@
+package mage.cards.b;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalAsThoughEffect;
+import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderSourceEffect;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.abilities.keyword.DefenderAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.counters.Counter;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class BackstreetBruiser extends CardImpl {
+
+ public BackstreetBruiser(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
+
+ this.subtype.add(SubType.CEPHALID);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Defender
+ this.addAbility(DefenderAbility.getInstance());
+
+ // As long as there are two or more counters among creatures you control, Backstreet Bruiser can attack as though it didn't have defender.
+ this.addAbility(new SimpleStaticAbility(new ConditionalAsThoughEffect(
+ new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield),
+ BackstreetBruiserCondition.instance
+ ).setText("As long as there are two or more counters among creatures you control, {this} can attack as though it didn't have defender")));
+ }
+
+ private BackstreetBruiser(final BackstreetBruiser card) {
+ super(card);
+ }
+
+ @Override
+ public BackstreetBruiser copy() {
+ return new BackstreetBruiser(this);
+ }
+}
+
+enum BackstreetBruiserCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ int totalCounters = 0;
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source, game)) {
+ for (Counter counter : permanent.getCounters(game).values()) {
+ totalCounters += counter.getCount();
+ if (totalCounters >= 2) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BackupAgent.java b/Mage.Sets/src/mage/cards/b/BackupAgent.java
new file mode 100644
index 00000000000..3eaa6a21e4b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BackupAgent.java
@@ -0,0 +1,43 @@
+package mage.cards.b;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.counters.CounterType;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class BackupAgent extends CardImpl {
+
+ public BackupAgent(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.CITIZEN);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // When Backup Agent enters the battlefield, put a +1/+1 counter on target creature.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private BackupAgent(final BackupAgent card) {
+ super(card);
+ }
+
+ @Override
+ public BackupAgent copy() {
+ return new BackupAgent(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BagOfDevouring.java b/Mage.Sets/src/mage/cards/b/BagOfDevouring.java
index b223aa83345..c0a57fc5eb0 100644
--- a/Mage.Sets/src/mage/cards/b/BagOfDevouring.java
+++ b/Mage.Sets/src/mage/cards/b/BagOfDevouring.java
@@ -113,7 +113,7 @@ class BagOfDevouringEffect extends OneShotEffect {
CardUtil.getExileZoneId(game, source)
);
target.setNotTarget(true);
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/b/BakisCurse.java b/Mage.Sets/src/mage/cards/b/BakisCurse.java
index 0afce6934a4..78b4627151d 100644
--- a/Mage.Sets/src/mage/cards/b/BakisCurse.java
+++ b/Mage.Sets/src/mage/cards/b/BakisCurse.java
@@ -55,7 +55,7 @@ class BakisCurseEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source, game)) {
int count = 0;
List attachments = creature.getAttachments();
for (UUID attachmentId : attachments) {
diff --git a/Mage.Sets/src/mage/cards/b/BalaGedThief.java b/Mage.Sets/src/mage/cards/b/BalaGedThief.java
index f27ca9a8548..574025d2f60 100644
--- a/Mage.Sets/src/mage/cards/b/BalaGedThief.java
+++ b/Mage.Sets/src/mage/cards/b/BalaGedThief.java
@@ -36,7 +36,7 @@ public final class BalaGedThief extends CardImpl {
// You choose one of them. That player discards that card.
Ability ability = new AllyEntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect(TargetController.ANY, xValue), false);
ability.addTarget(new TargetPlayer());
- this.addAbility(ability);
+ this.addAbility(ability.setAbilityWord(null));
}
private BalaGedThief(final BalaGedThief card) {
diff --git a/Mage.Sets/src/mage/cards/b/BalancingAct.java b/Mage.Sets/src/mage/cards/b/BalancingAct.java
index 45403e59038..d0c157143b9 100644
--- a/Mage.Sets/src/mage/cards/b/BalancingAct.java
+++ b/Mage.Sets/src/mage/cards/b/BalancingAct.java
@@ -64,7 +64,7 @@ class BalancingActEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- int count = game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source.getSourceId(), game).size();
+ int count = game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source, game).size();
if (count < minPermanent) {
minPermanent = count;
}
@@ -75,8 +75,8 @@ class BalancingActEffect extends OneShotEffect {
Player player = game.getPlayer(playerId);
if (player != null) {
TargetControlledPermanent target = new TargetControlledPermanent(minPermanent, minPermanent, new FilterControlledPermanent(), true);
- if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source.getSourceId(), game)) {
+ if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), source, game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source, game)) {
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
permanent.sacrifice(source, game);
}
@@ -101,7 +101,7 @@ class BalancingActEffect extends OneShotEffect {
Player player = game.getPlayer(playerId);
if (player != null) {
TargetCardInHand target = new TargetCardInHand(minCard, new FilterCard());
- if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)) {
+ if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), source, game)) {
Cards cards = player.getHand().copy();
cards.removeIf(target.getTargets()::contains);
player.discard(cards, false, source, game);
diff --git a/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java b/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java
index 6bb41553fa1..51276efd26e 100644
--- a/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java
+++ b/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java
@@ -115,8 +115,8 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName());
filter.add(new PermanentInListPredicate(list));
TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true);
- if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
- while (!target.isChosen() && target.canChoose(source.getSourceId(), controller.getId(), game) && controller.canRespond()) {
+ if (target.canChoose(controller.getId(), source, game)) {
+ while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
controller.chooseTarget(outcome, target, source, game);
}
} else {
diff --git a/Mage.Sets/src/mage/cards/b/BalefireDragon.java b/Mage.Sets/src/mage/cards/b/BalefireDragon.java
index 827778e328a..61468c3d7dd 100644
--- a/Mage.Sets/src/mage/cards/b/BalefireDragon.java
+++ b/Mage.Sets/src/mage/cards/b/BalefireDragon.java
@@ -1,21 +1,15 @@
-
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
+import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.filter.StaticFilters;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
/**
*
@@ -31,9 +25,12 @@ public final class BalefireDragon extends CardImpl {
this.toughness = new MageInt(6);
this.addAbility(FlyingAbility.getInstance());
- // Whenever Balefire Dragon deals combat damage to a player, it deals that much damage to each creature that player controls.
- this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new BalefireDragonEffect(), false, true));
+ // Whenever Balefire Dragon deals combat damage to a player,
+ // it deals that much damage to each creature that player controls.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
+ new DamageAllControlledTargetEffect(SavedDamageValue.MUCH, "it"),
+ false, true));
}
private BalefireDragon(final BalefireDragon card) {
@@ -45,36 +42,3 @@ public final class BalefireDragon extends CardImpl {
return new BalefireDragon(this);
}
}
-
-class BalefireDragonEffect extends OneShotEffect {
-
- public BalefireDragonEffect() {
- super(Outcome.Damage);
- staticText = "it deals that much damage to each creature that player controls";
- }
-
- public BalefireDragonEffect(final BalefireDragonEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(targetPointer.getFirst(game, source));
- if (player != null) {
- int amount = (Integer) getValue("damage");
- if (amount > 0) {
- for (Permanent creature : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, player.getId(), game)) {
- creature.damage(amount, source.getSourceId(), source, game, false, true);
- }
- }
- return true;
- }
- return false;
- }
-
- @Override
- public BalefireDragonEffect copy() {
- return new BalefireDragonEffect(this);
- }
-
-}
diff --git a/Mage.Sets/src/mage/cards/b/BallroomBrawlers.java b/Mage.Sets/src/mage/cards/b/BallroomBrawlers.java
new file mode 100644
index 00000000000..5dbe42a864e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BallroomBrawlers.java
@@ -0,0 +1,95 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.targetpointer.FixedTargets;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BallroomBrawlers extends CardImpl {
+
+ public BallroomBrawlers(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(5);
+
+ // Whenever Ballroom Brawlers attacks, Ballroom Brawlers and up to one other target creature you control each gain your choice of first strike or lifelink until end of turn.
+ Ability ability = new AttacksTriggeredAbility(new BallroomBrawlersEffect());
+ ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE));
+ this.addAbility(ability);
+ }
+
+ private BallroomBrawlers(final BallroomBrawlers card) {
+ super(card);
+ }
+
+ @Override
+ public BallroomBrawlers copy() {
+ return new BallroomBrawlers(this);
+ }
+}
+
+class BallroomBrawlersEffect extends OneShotEffect {
+
+ BallroomBrawlersEffect() {
+ super(Outcome.Benefit);
+ staticText = "{this} and up to one other target creature you control " +
+ "both gain your choice of first strike or lifelink until end of turn";
+ }
+
+ private BallroomBrawlersEffect(final BallroomBrawlersEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BallroomBrawlersEffect copy() {
+ return new BallroomBrawlersEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ List permanents = new ArrayList<>();
+ permanents.add(source.getSourcePermanentIfItStillExists(game));
+ permanents.add(game.getPermanent(getTargetPointer().getFirst(game, source)));
+ permanents.removeIf(Objects::isNull);
+ if (permanents.isEmpty()) {
+ return false;
+ }
+ Ability ability = player.chooseUse(
+ outcome, "Choose first strike or lifelink", null,
+ "First Strike", "Lifelink", source, game
+ ) ? FirstStrikeAbility.getInstance() : LifelinkAbility.getInstance();
+ game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn)
+ .setTargetPointer(new FixedTargets(permanents, game)), source);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BallynockCohort.java b/Mage.Sets/src/mage/cards/b/BallynockCohort.java
index a7afdb28be3..539e3f0a082 100644
--- a/Mage.Sets/src/mage/cards/b/BallynockCohort.java
+++ b/Mage.Sets/src/mage/cards/b/BallynockCohort.java
@@ -35,7 +35,7 @@ public final class BallynockCohort extends CardImpl {
filter.add(AnotherPredicate.instance);
}
- private String rule = "{this} gets +1/+1 as long as you control another white creature";
+ private static final String rule = "{this} gets +1/+1 as long as you control another white creature";
public BallynockCohort(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
diff --git a/Mage.Sets/src/mage/cards/b/BalmOfRestoration.java b/Mage.Sets/src/mage/cards/b/BalmOfRestoration.java
index f7af97f9800..12e9d88efad 100644
--- a/Mage.Sets/src/mage/cards/b/BalmOfRestoration.java
+++ b/Mage.Sets/src/mage/cards/b/BalmOfRestoration.java
@@ -32,8 +32,7 @@ public final class BalmOfRestoration extends CardImpl {
ability.addCost(new SacrificeSourceCost());
// or prevent the next 2 damage that would be dealt to any target this turn.
- Mode mode = new Mode();
- mode.addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, 2));
+ Mode mode = new Mode(new PreventDamageToTargetEffect(Duration.EndOfTurn, 2));
mode.addTarget(new TargetAnyTarget());
ability.addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/b/BalthorTheDefiled.java b/Mage.Sets/src/mage/cards/b/BalthorTheDefiled.java
index 2328627e1b5..46bb525f73f 100644
--- a/Mage.Sets/src/mage/cards/b/BalthorTheDefiled.java
+++ b/Mage.Sets/src/mage/cards/b/BalthorTheDefiled.java
@@ -89,7 +89,7 @@ class BalthorTheDefiledEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- cardsToReturn.addAll(player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game));
+ cardsToReturn.addAll(player.getGraveyard().getCards(filter, source.getControllerId(), source, game));
}
}
controller.moveCards(cardsToReturn.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null);
diff --git a/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java b/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java
index 26b383bded4..f90e667e36e 100644
--- a/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java
+++ b/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java
@@ -162,7 +162,7 @@ class BaneAlleyBrokerReturnToHandEffect extends OneShotEffect {
if (card == null) {
return false;
}
- return card != null && player.moveCards(card, Zone.HAND, source, game);
+ return player.moveCards(card, Zone.HAND, source, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BaneOfProgress.java b/Mage.Sets/src/mage/cards/b/BaneOfProgress.java
index 609daa3db66..b452f1339f6 100644
--- a/Mage.Sets/src/mage/cards/b/BaneOfProgress.java
+++ b/Mage.Sets/src/mage/cards/b/BaneOfProgress.java
@@ -70,7 +70,7 @@ class BaneOfProgressEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int destroyedPermanents = 0;
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
if (permanent.destroy(source, game, false)) {
destroyedPermanents++;
}
diff --git a/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java b/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java
index e0765a87d3b..7d951ad6fc4 100644
--- a/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java
+++ b/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java
@@ -31,7 +31,7 @@ public final class BaneOfTheLiving extends CardImpl {
this.toughness = new MageInt(3);
// Morph {X}{B}{B}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{X}{B}{B}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{X}{B}{B}")));
// When Bane of the Living is turned face up, all creatures get -X/-X until end of turn.
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new BoostAllEffect(morphX, morphX, Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_ALL_CREATURES, false, null, true)));
diff --git a/Mage.Sets/src/mage/cards/b/BaneclawMarauder.java b/Mage.Sets/src/mage/cards/b/BaneclawMarauder.java
index 2a2394c962e..e158a3c738f 100644
--- a/Mage.Sets/src/mage/cards/b/BaneclawMarauder.java
+++ b/Mage.Sets/src/mage/cards/b/BaneclawMarauder.java
@@ -1,7 +1,6 @@
package mage.cards.b;
import mage.MageInt;
-import mage.MageObjectReference;
import mage.abilities.common.BecomesBlockedSourceTriggeredAbility;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.effects.common.LoseLifeTargetControllerEffect;
@@ -12,18 +11,10 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.WatcherScope;
-import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.predicate.ObjectSourcePlayer;
-import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.permanent.Permanent;
-import mage.watchers.Watcher;
-import java.util.*;
+import java.util.UUID;
/**
* @author TheElk801
@@ -31,11 +22,9 @@ import java.util.*;
public final class BaneclawMarauder extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
- private static final FilterPermanent filter2 = new FilterCreaturePermanent("a creature blocking {this}");
static {
filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
- filter2.add(BaneclawMarauderPredicate.instance);
}
public BaneclawMarauder(UUID ownerId, CardSetInfo setInfo) {
@@ -56,8 +45,8 @@ public final class BaneclawMarauder extends CardImpl {
this.addAbility(new DiesCreatureTriggeredAbility(
new LoseLifeTargetControllerEffect(1)
.setText("that creature's controller loses 1 life"),
- false, filter2, true
- ), new BaneclawMarauderWatcher());
+ false, filter, true
+ ));
// Nightbound
this.addAbility(new NightboundAbility());
@@ -72,55 +61,3 @@ public final class BaneclawMarauder extends CardImpl {
return new BaneclawMarauder(this);
}
}
-
-enum BaneclawMarauderPredicate implements ObjectSourcePlayerPredicate {
- instance;
-
- @Override
- public boolean apply(ObjectSourcePlayer input, Game game) {
- return BaneclawMarauderWatcher.check(input.getSourceId(), input.getObject(), game);
- }
-}
-
-class BaneclawMarauderWatcher extends Watcher {
-
- private final Map> blockerMap = new HashMap<>();
-
- BaneclawMarauderWatcher() {
- super(WatcherScope.GAME);
- }
-
- @Override
- public void watch(GameEvent event, Game game) {
- switch (event.getType()) {
- case BLOCKER_DECLARED:
- blockerMap
- .computeIfAbsent(new MageObjectReference(event.getTargetId(), game), x -> new HashSet<>())
- .add(new MageObjectReference(event.getSourceId(), game));
- return;
- case END_COMBAT_STEP_POST:
- blockerMap.clear();
- return;
- case REMOVED_FROM_COMBAT:
- blockerMap
- .values()
- .stream()
- .forEach(set -> set.removeIf(mor -> mor.refersTo(event.getTargetId(), game)));
- }
- }
-
- @Override
- public void reset() {
- super.reset();
- blockerMap.clear();
- }
-
- static boolean check(UUID sourceId, Permanent blocker, Game game) {
- return game.getState()
- .getWatcher(BaneclawMarauderWatcher.class)
- .blockerMap
- .getOrDefault(new MageObjectReference(sourceId, game), Collections.emptySet())
- .stream()
- .anyMatch(mor -> mor.refersTo(blocker, game));
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/Banefire.java b/Mage.Sets/src/mage/cards/b/Banefire.java
index ccf67d35f2a..8c3657e3606 100644
--- a/Mage.Sets/src/mage/cards/b/Banefire.java
+++ b/Mage.Sets/src/mage/cards/b/Banefire.java
@@ -34,6 +34,7 @@ public final class Banefire extends CardImpl {
// Banefire deals X damage to any target.
this.getSpellAbility().addEffect(new BaneFireEffect());
this.getSpellAbility().addTarget(new TargetAnyTarget());
+
// If X is 5 or more, Banefire can't be countered and the damage can't be prevented.
this.addAbility(new SimpleStaticAbility(Zone.STACK, new BanefireCantCounterEffect()));
}
@@ -50,8 +51,8 @@ public final class Banefire extends CardImpl {
class testCondition implements Condition {
- private DynamicValue xValue;
- private int limit;
+ private final DynamicValue xValue;
+ private final int limit;
public testCondition(DynamicValue xValue, int limit) {
this.xValue = xValue;
@@ -105,7 +106,7 @@ class BaneFireEffect extends OneShotEffect {
class BanefireCantCounterEffect extends ContinuousRuleModifyingEffectImpl {
- Condition condition = new testCondition(ManacostVariableValue.REGULAR, 5);
+ private Condition condition = new testCondition(ManacostVariableValue.REGULAR, 5);
public BanefireCantCounterEffect() {
super(Duration.WhileOnStack, Outcome.Benefit);
@@ -129,18 +130,14 @@ class BanefireCantCounterEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (event.getType() == GameEvent.EventType.COUNTER) {
- Card card = game.getCard(source.getSourceId());
- if (card != null) {
- UUID spellId = card.getSpellAbility().getId();
- if (event.getTargetId().equals(spellId)) {
- if (condition.apply(game, source)) {
- return true;
- }
- }
- }
- }
- return false;
- }
+ if (event.getType() != GameEvent.EventType.COUNTER) { return false; }
+ Card card = game.getCard(source.getSourceId());
+ if (card == null) { return false; }
+
+ UUID spellId = card.getSpellAbility().getId();
+ if (!event.getTargetId().equals(spellId)) { return false; }
+
+ return condition.apply(game, source);
+ }
}
diff --git a/Mage.Sets/src/mage/cards/b/BantCharm.java b/Mage.Sets/src/mage/cards/b/BantCharm.java
index 98ba3c09e82..bce7fcac5e0 100644
--- a/Mage.Sets/src/mage/cards/b/BantCharm.java
+++ b/Mage.Sets/src/mage/cards/b/BantCharm.java
@@ -34,13 +34,11 @@ public final class BantCharm extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetArtifactPermanent());
// or put target creature on the bottom of its owner's library;
- Mode mode = new Mode();
- mode.addEffect(new PutOnLibraryTargetEffect(false));
+ Mode mode = new Mode(new PutOnLibraryTargetEffect(false));
mode.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addMode(mode);
// or counter target instant spell.
- mode = new Mode();
- mode.addEffect(new CounterTargetEffect());
+ mode = new Mode(new CounterTargetEffect());
mode.addTarget(new TargetSpell(filter));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/b/BantSojourners.java b/Mage.Sets/src/mage/cards/b/BantSojourners.java
index c96ea3fe610..f2d7d76d62b 100644
--- a/Mage.Sets/src/mage/cards/b/BantSojourners.java
+++ b/Mage.Sets/src/mage/cards/b/BantSojourners.java
@@ -1,41 +1,44 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.CycleTriggeredAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.CyclingAbility;
+import mage.abilities.meta.OrTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
+import mage.constants.Zone;
import mage.game.permanent.token.SoldierToken;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class BantSojourners extends CardImpl {
public BantSojourners(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{W}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}{U}");
this.subtype.add(SubType.HUMAN, SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// When you cycle Bant Sojourners or it dies, you may create a 1/1 white Soldier creature token.
- Ability ability1 = new CycleTriggeredAbility(new CreateTokenEffect(new SoldierToken()), true);
- Ability ability2 = new DiesSourceTriggeredAbility(new CreateTokenEffect(new SoldierToken()), true);
- this.addAbility(ability1);
- this.addAbility(ability2);
-
+ this.addAbility(new OrTriggeredAbility(Zone.ALL,
+ new CreateTokenEffect(new SoldierToken()),
+ true,
+ "When you cycle {this} or it dies, ",
+ new CycleTriggeredAbility(null, true),
+ new DiesSourceTriggeredAbility(null, true)
+ ));
+
// Cycling {2}{W}
- this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}{W}")));
+ this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}{W}")));
}
private BantSojourners(final BantSojourners card) {
diff --git a/Mage.Sets/src/mage/cards/b/BanthaHerd.java b/Mage.Sets/src/mage/cards/b/BanthaHerd.java
index a20e4be969a..0e06b46df17 100644
--- a/Mage.Sets/src/mage/cards/b/BanthaHerd.java
+++ b/Mage.Sets/src/mage/cards/b/BanthaHerd.java
@@ -65,10 +65,10 @@ class BathaHerdEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- int xValue = ((BecomesMonstrousSourceTriggeredAbility) source).getMonstrosityValue();
- return new CreateTokenEffect(new TuskenRaiderToken(), xValue).apply(game, source);
- }
- return false;
+ if (controller == null) { return false; }
+
+ int xValue = ((BecomesMonstrousSourceTriggeredAbility) source).getMonstrosityValue();
+
+ return new CreateTokenEffect(new TuskenRaiderToken(), xValue).apply(game, source);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BaralChiefOfCompliance.java b/Mage.Sets/src/mage/cards/b/BaralChiefOfCompliance.java
index f22bd18f2fc..6a6bc26cd0f 100644
--- a/Mage.Sets/src/mage/cards/b/BaralChiefOfCompliance.java
+++ b/Mage.Sets/src/mage/cards/b/BaralChiefOfCompliance.java
@@ -18,7 +18,6 @@ import mage.filter.predicate.Predicates;
import java.util.UUID;
/**
- *
* @author fireshoes
*/
public final class BaralChiefOfCompliance extends CardImpl {
@@ -35,7 +34,7 @@ public final class BaralChiefOfCompliance extends CardImpl {
public BaralChiefOfCompliance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
- addSuperType(SuperType.LEGENDARY);
+ addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN, SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
@@ -44,7 +43,7 @@ public final class BaralChiefOfCompliance extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1)));
// Whenever a spell or ability you control counters a spell, you may draw a card. If you do, discard a card.
- this.addAbility(new SpellCounteredControllerTriggeredAbility(new DrawDiscardControllerEffect(), true));
+ this.addAbility(new SpellCounteredControllerTriggeredAbility(new DrawDiscardControllerEffect(true)));
}
private BaralChiefOfCompliance(final BaralChiefOfCompliance card) {
diff --git a/Mage.Sets/src/mage/cards/b/BaralsExpertise.java b/Mage.Sets/src/mage/cards/b/BaralsExpertise.java
index 634b7ee170f..483f3a0a59a 100644
--- a/Mage.Sets/src/mage/cards/b/BaralsExpertise.java
+++ b/Mage.Sets/src/mage/cards/b/BaralsExpertise.java
@@ -1,27 +1,34 @@
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
-import mage.abilities.effects.common.cost.CastWithoutPayingManaCostEffect;
+import mage.abilities.effects.common.cost.CastFromHandForFreeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.target.TargetPermanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class BaralsExpertise extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifacts and/or creatures");
+ private static final FilterCard filter2 = new FilterCard("a spell with mana value 4 or less");
static {
- filter.add(Predicates.or(CardType.ARTIFACT.getPredicate(),
- CardType.CREATURE.getPredicate()));
+ filter.add(Predicates.or(
+ CardType.ARTIFACT.getPredicate(),
+ CardType.CREATURE.getPredicate()
+ ));
+ filter2.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 5));
}
public BaralsExpertise(UUID ownerId, CardSetInfo setInfo) {
@@ -32,7 +39,7 @@ public final class BaralsExpertise extends CardImpl {
getSpellAbility().addTarget(new TargetPermanent(0, 3, filter, false));
// You may cast a card with converted mana cost 4 or less from your hand without paying its mana cost.
- getSpellAbility().addEffect(new CastWithoutPayingManaCostEffect(4).concatBy("
"));
+ getSpellAbility().addEffect(new CastFromHandForFreeEffect(filter2).concatBy("
"));
}
private BaralsExpertise(final BaralsExpertise card) {
diff --git a/Mage.Sets/src/mage/cards/b/BarbedBackWurm.java b/Mage.Sets/src/mage/cards/b/BarbedBackWurm.java
index a3d937a91d5..5941c3d1831 100644
--- a/Mage.Sets/src/mage/cards/b/BarbedBackWurm.java
+++ b/Mage.Sets/src/mage/cards/b/BarbedBackWurm.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
@@ -13,30 +11,37 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
+import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
-import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
-import mage.target.common.TargetCreaturePermanent;
+import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
/**
- *
* @author LoneFox
*/
public final class BarbedBackWurm extends CardImpl {
+ private static final FilterPermanent filter = new FilterCreaturePermanent("green creature blocking {this}");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.GREEN));
+ filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
+ }
+
public BarbedBackWurm(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.WURM);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// {B}: Target green creature blocking Barbed-Back Wurm gets -1/-1 until end of turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-1, -1, Duration.EndOfTurn), new ManaCostsImpl("{B}"));
- FilterCreaturePermanent filter = new FilterCreaturePermanent("green creature blocking {this}");
- filter.add(new ColorPredicate(ObjectColor.GREEN));
- filter.add(new BlockingAttackerIdPredicate(this.getId()));
- ability.addTarget(new TargetCreaturePermanent(filter));
+ Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(
+ -1, -1, Duration.EndOfTurn
+ ), new ManaCostsImpl<>("{B}"));
+ ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BarbedLightning.java b/Mage.Sets/src/mage/cards/b/BarbedLightning.java
index 5f774da7f45..d8252a6fcff 100644
--- a/Mage.Sets/src/mage/cards/b/BarbedLightning.java
+++ b/Mage.Sets/src/mage/cards/b/BarbedLightning.java
@@ -25,8 +25,7 @@ public final class BarbedLightning extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// or Barbed Lightning deals 3 damage to target player.
- Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(3));
+ Mode mode = new Mode(new DamageTargetEffect(3));
mode.addTarget(new TargetPlayerOrPlaneswalker());
this.getSpellAbility().getModes().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/b/BarbedShocker.java b/Mage.Sets/src/mage/cards/b/BarbedShocker.java
index 97406cf6662..c921f095ef5 100644
--- a/Mage.Sets/src/mage/cards/b/BarbedShocker.java
+++ b/Mage.Sets/src/mage/cards/b/BarbedShocker.java
@@ -31,8 +31,11 @@ public final class BarbedShocker extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// Haste
this.addAbility(HasteAbility.getInstance());
+
// Whenever Barbed Shocker deals damage to a player, that player discards all the cards in their hand, then draws that many cards.
- this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new BarbedShockerEffect(), false, true));
+ this.addAbility(new DealsDamageToAPlayerTriggeredAbility(
+ new BarbedShockerEffect(), false, true
+ ));
}
private BarbedShocker(final BarbedShocker card) {
@@ -49,7 +52,7 @@ class BarbedShockerEffect extends OneShotEffect {
BarbedShockerEffect() {
super(Outcome.Discard);
- this.staticText = " that player discards all the cards in their hand, then draws that many cards";
+ this.staticText = "that player discards all the cards in their hand, then draws that many cards";
}
private BarbedShockerEffect(final BarbedShockerEffect effect) {
@@ -64,11 +67,12 @@ class BarbedShockerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
- if (targetPlayer == null) {
+ if (targetPlayer == null || targetPlayer.getHand().isEmpty()) {
return false;
}
- int count = targetPlayer.discard(targetPlayer.getHand(), false, source, game).size();
- targetPlayer.drawCards(count, source, game);
+ targetPlayer.drawCards(targetPlayer.discard(
+ targetPlayer.getHand(), false, source, game
+ ).size(), source, game);
return true;
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/b/BarbedSliver.java b/Mage.Sets/src/mage/cards/b/BarbedSliver.java
index 6eb399d6442..0b8a258bb3e 100644
--- a/Mage.Sets/src/mage/cards/b/BarbedSliver.java
+++ b/Mage.Sets/src/mage/cards/b/BarbedSliver.java
@@ -29,7 +29,7 @@ public final class BarbedSliver extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn).setText("this creature gets +1/+0 until end of turn"),
- new GenericManaCost(2)), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, false)));
+ new GenericManaCost(2)), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS, false)));
}
private BarbedSliver(final BarbedSliver card) {
diff --git a/Mage.Sets/src/mage/cards/b/BarbedWire.java b/Mage.Sets/src/mage/cards/b/BarbedWire.java
index e8f42a84fe0..6fcc49d55f3 100644
--- a/Mage.Sets/src/mage/cards/b/BarbedWire.java
+++ b/Mage.Sets/src/mage/cards/b/BarbedWire.java
@@ -24,7 +24,7 @@ import mage.players.Player;
*/
public final class BarbedWire extends CardImpl {
- private final String rule = "At the beginning of each player's upkeep, "
+ private static final String rule = "At the beginning of each player's upkeep, "
+ "Barbed Wire deals 1 damage to that player.";
public BarbedWire(UUID ownerId, CardSetInfo setInfo) {
diff --git a/Mage.Sets/src/mage/cards/b/BarkshellBlessing.java b/Mage.Sets/src/mage/cards/b/BarkshellBlessing.java
index 15a587256d3..86c46bfb2bd 100644
--- a/Mage.Sets/src/mage/cards/b/BarkshellBlessing.java
+++ b/Mage.Sets/src/mage/cards/b/BarkshellBlessing.java
@@ -24,7 +24,7 @@ public final class BarkshellBlessing extends CardImpl {
this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn));
// Conspire
- this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
+ this.addAbility(new ConspireAbility(ConspireAbility.ConspireTargets.ONE));
}
private BarkshellBlessing(final BarkshellBlessing card) {
diff --git a/Mage.Sets/src/mage/cards/b/BaronVonCount.java b/Mage.Sets/src/mage/cards/b/BaronVonCount.java
index cd15e61d273..063be647844 100644
--- a/Mage.Sets/src/mage/cards/b/BaronVonCount.java
+++ b/Mage.Sets/src/mage/cards/b/BaronVonCount.java
@@ -76,7 +76,7 @@ class BaronVonCountPutCounterEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
if (mageObject == null) {
- mageObject = game.getObject(source.getSourceId());
+ mageObject = game.getObject(source);
}
if (controller != null && mageObject != null) {
Integer doomNumber = 5;
@@ -172,7 +172,7 @@ class BaronVonCountMoveDoomCounterEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (controller != null && sourcePermanent != null && mageObject != null) {
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
return false;
@@ -249,7 +249,7 @@ class BaronVonCountDestroyPlayerEffect extends OneShotEffect {
targetPlayer.lost(game); // double checks canLose, but seems more future-proof than lostForced
}
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (sourcePermanent != null && mageObject != null) {
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/b/BarrinsSpite.java b/Mage.Sets/src/mage/cards/b/BarrinsSpite.java
index a9be4bde62e..f90e68333c5 100644
--- a/Mage.Sets/src/mage/cards/b/BarrinsSpite.java
+++ b/Mage.Sets/src/mage/cards/b/BarrinsSpite.java
@@ -7,7 +7,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -30,9 +29,7 @@ public final class BarrinsSpite extends CardImpl {
// Choose two target creatures controlled by the same player. Their controller chooses and sacrifices one of them. Return the other to its owner's hand.
this.getSpellAbility().addEffect(new BarrinsSpiteEffect());
- this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(
- 2, 2, StaticFilters.FILTER_PERMANENT_CREATURE, false
- ));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(2));
}
private BarrinsSpite(final BarrinsSpite card) {
diff --git a/Mage.Sets/src/mage/cards/b/BaseCamp.java b/Mage.Sets/src/mage/cards/b/BaseCamp.java
index d5c97d41156..79de773fff5 100644
--- a/Mage.Sets/src/mage/cards/b/BaseCamp.java
+++ b/Mage.Sets/src/mage/cards/b/BaseCamp.java
@@ -75,7 +75,7 @@ enum BaseCampCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
return object != null && (
object.hasSubtype(SubType.CLERIC, game)
|| object.hasSubtype(SubType.ROGUE, game)
diff --git a/Mage.Sets/src/mage/cards/b/BasicConjuration.java b/Mage.Sets/src/mage/cards/b/BasicConjuration.java
index b4ad758ab45..4c8e38d7fa1 100644
--- a/Mage.Sets/src/mage/cards/b/BasicConjuration.java
+++ b/Mage.Sets/src/mage/cards/b/BasicConjuration.java
@@ -2,11 +2,11 @@ package mage.cards.b;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
import java.util.UUID;
@@ -24,9 +24,7 @@ public final class BasicConjuration extends CardImpl {
// Look at the top six cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. You gain 3 life.
this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- 6, 1, StaticFilters.FILTER_CARD_CREATURE_A,
- true, false, Zone.HAND, true
- ).setBackInRandomOrder(true));
+ 6, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM));
this.getSpellAbility().addEffect(new GainLifeEffect(3));
}
diff --git a/Mage.Sets/src/mage/cards/b/BaskingRootwalla.java b/Mage.Sets/src/mage/cards/b/BaskingRootwalla.java
index f0573659bee..b8c4bdbbe93 100644
--- a/Mage.Sets/src/mage/cards/b/BaskingRootwalla.java
+++ b/Mage.Sets/src/mage/cards/b/BaskingRootwalla.java
@@ -32,7 +32,7 @@ public final class BaskingRootwalla extends CardImpl {
new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{1}{G}")));
// Madness {0}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{0}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{0}")));
}
private BaskingRootwalla(final BaskingRootwalla card) {
diff --git a/Mage.Sets/src/mage/cards/b/BasriDevotedPaladin.java b/Mage.Sets/src/mage/cards/b/BasriDevotedPaladin.java
index c484ec5995a..310a1694c41 100644
--- a/Mage.Sets/src/mage/cards/b/BasriDevotedPaladin.java
+++ b/Mage.Sets/src/mage/cards/b/BasriDevotedPaladin.java
@@ -3,7 +3,6 @@ package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
@@ -39,7 +38,7 @@ public final class BasriDevotedPaladin extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.BASRI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Put a +1/+1 counter on up to one target creature. It gains vigilance until end of turn.
Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(
diff --git a/Mage.Sets/src/mage/cards/b/BasriKet.java b/Mage.Sets/src/mage/cards/b/BasriKet.java
index 2c4bd29ff94..d1fbff60631 100644
--- a/Mage.Sets/src/mage/cards/b/BasriKet.java
+++ b/Mage.Sets/src/mage/cards/b/BasriKet.java
@@ -3,7 +3,6 @@ package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.GetEmblemEffect;
@@ -39,7 +38,7 @@ public final class BasriKet extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.BASRI);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: Put a +1/+1 counter on up to one target creature. It gains indestructible until end of turn.
Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(
diff --git a/Mage.Sets/src/mage/cards/b/BatheInLight.java b/Mage.Sets/src/mage/cards/b/BatheInLight.java
index 1c5ea0c9a7e..932559944e3 100644
--- a/Mage.Sets/src/mage/cards/b/BatheInLight.java
+++ b/Mage.Sets/src/mage/cards/b/BatheInLight.java
@@ -70,34 +70,32 @@ class BatheInLightEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
- if (target != null) {
- ChoiceColor colorChoice = new ChoiceColor();
- if (!controller.choose(Outcome.Benefit, colorChoice, game)) {
- return false;
- }
- game.informPlayers(target.getName() + ": " + controller.getLogName() + " has chosen " + colorChoice.getChoice());
- game.getState().setValue(target.getId() + "_color", colorChoice.getColor());
+ if (controller == null) { return false; }
- ObjectColor protectColor = (ObjectColor) game.getState().getValue(target.getId() + "_color");
- if (protectColor != null) {
- ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
- game.addEffect(effect, source);
- ObjectColor color = target.getColor(game);
- for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
- if (!permanent.getId().equals(target.getId()) && permanent.getColor(game).shares(color)) {
- game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
- effect.setTargetPointer(new FixedTarget(permanent, game));
- game.addEffect(effect, source);
- }
- }
+ Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (target == null) { return false; }
- }
- return true;
+ ChoiceColor colorChoice = new ChoiceColor();
+ if (!controller.choose(Outcome.Benefit, colorChoice, game)) { return false; }
+
+ game.informPlayers(target.getName() + ": " + controller.getLogName() + " has chosen " + colorChoice.getChoice());
+ game.getState().setValue(target.getId() + "_color", colorChoice.getColor());
+
+ ObjectColor protectColor = (ObjectColor) game.getState().getValue(target.getId() + "_color");
+ if (protectColor == null) { return true; }
+
+ ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
+ game.addEffect(effect, source);
+ ObjectColor color = target.getColor(game);
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source, game)) {
+ if (!permanent.getId().equals(target.getId()) && permanent.getColor(game).shares(color)) {
+ game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
}
}
- return false;
+
+ return true;
}
}
@@ -128,19 +126,20 @@ class ProtectionChosenColorTargetEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
- if (permanent != null) {
- ObjectColor color = (ObjectColor) game.getState().getValue(permanent.getId() + "_color");
- if (color != null && (protectionAbility == null || !color.equals(chosenColor))) {
- chosenColor = color;
- FilterObject protectionFilter = new FilterObject(chosenColor.getDescription());
- protectionFilter.add(new ColorPredicate(chosenColor));
- protectionAbility = new ProtectionAbility(protectionFilter);
- }
- if (protectionAbility != null) {
- permanent.addAbility(protectionAbility, source.getSourceId(), game);
- return true;
- }
+ if (permanent == null) { return false; }
+
+ ObjectColor color = (ObjectColor) game.getState().getValue(permanent.getId() + "_color");
+ if (color != null && (protectionAbility == null || !color.equals(chosenColor))) {
+ chosenColor = color;
+ FilterObject protectionFilter = new FilterObject<>(chosenColor.getDescription());
+ protectionFilter.add(new ColorPredicate(chosenColor));
+ protectionAbility = new ProtectionAbility(protectionFilter);
}
+ if (protectionAbility != null) {
+ permanent.addAbility(protectionAbility, source.getSourceId(), game);
+ return true;
+ }
+
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BatteringCraghorn.java b/Mage.Sets/src/mage/cards/b/BatteringCraghorn.java
index b28e0a4712d..ea4ccd5fd6c 100644
--- a/Mage.Sets/src/mage/cards/b/BatteringCraghorn.java
+++ b/Mage.Sets/src/mage/cards/b/BatteringCraghorn.java
@@ -27,7 +27,7 @@ public final class BatteringCraghorn extends CardImpl {
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Morph {1}{R}{R}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{R}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{1}{R}{R}")));
}
private BatteringCraghorn(final BatteringCraghorn card) {
diff --git a/Mage.Sets/src/mage/cards/b/BattleForBretagard.java b/Mage.Sets/src/mage/cards/b/BattleForBretagard.java
index ed2e3c190a5..ac11200470e 100644
--- a/Mage.Sets/src/mage/cards/b/BattleForBretagard.java
+++ b/Mage.Sets/src/mage/cards/b/BattleForBretagard.java
@@ -89,7 +89,7 @@ class BattleForBretagardEffect extends OneShotEffect {
return false;
}
TargetPermanent target = new BattleForBretagardTarget();
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
for (UUID targetId : target.getTargets()) {
new CreateTokenCopyTargetEffect()
.setTargetPointer(new FixedTarget(targetId, game))
@@ -145,8 +145,8 @@ class BattleForBretagardTarget extends TargetPermanent {
@Override
- public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
- Set possibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
+ public Set possibleTargets(UUID sourceControllerId, Ability source, Game game) {
+ Set possibleTargets = super.possibleTargets(sourceControllerId, source, game);
Set names = this.getTargets()
.stream()
.map(game::getPermanent)
diff --git a/Mage.Sets/src/mage/cards/b/BattleSliver.java b/Mage.Sets/src/mage/cards/b/BattleSliver.java
index 7bf8276baa1..29cde1e0dc7 100644
--- a/Mage.Sets/src/mage/cards/b/BattleSliver.java
+++ b/Mage.Sets/src/mage/cards/b/BattleSliver.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
@@ -10,11 +8,11 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class BattleSliver extends CardImpl {
@@ -27,9 +25,10 @@ public final class BattleSliver extends CardImpl {
this.toughness = new MageInt(3);
// Sliver creatures you control get +2/+0.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
- new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS)));
-
+ this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
+ 2, 0, Duration.WhileOnBattlefield,
+ StaticFilters.FILTER_PERMANENT_SLIVERS
+ )));
}
private BattleSliver(final BattleSliver card) {
diff --git a/Mage.Sets/src/mage/cards/b/BattlefieldScrounger.java b/Mage.Sets/src/mage/cards/b/BattlefieldScrounger.java
index 04ad2419f8e..ceb6de8a6b7 100644
--- a/Mage.Sets/src/mage/cards/b/BattlefieldScrounger.java
+++ b/Mage.Sets/src/mage/cards/b/BattlefieldScrounger.java
@@ -68,7 +68,7 @@ class BattlefieldScroungerCost extends CostImpl {
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
if (controller != null) {
- if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), game)) {
+ if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), source, game)) {
for (UUID targetId: targets.get(0).getTargets()) {
Card card = game.getCard(targetId);
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
@@ -84,7 +84,7 @@ class BattlefieldScroungerCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return targets.canChoose(source.getSourceId(), controllerId, game);
+ return targets.canChoose(controllerId, source, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java
index c911bd92af5..20694150ff0 100644
--- a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java
+++ b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java
@@ -66,7 +66,7 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
- int reduceAmount = 0;
+ int reduceAmount;
if (game.inCheckPlayableState()) {
// checking state (search max possible targets)
reduceAmount = getMaxPossibleTargetCreatures(abilityToModify, game);
@@ -99,7 +99,7 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf
if (target.isNotTarget()) {
continue;
}
- Set possibleList = target.possibleTargets(ability.getSourceId(), ability.getControllerId(), game);
+ Set possibleList = target.possibleTargets(ability.getControllerId(), ability, game);
possibleList.removeIf(id -> {
Permanent permanent = game.getPermanent(id);
return permanent == null || !permanent.isCreature(game);
@@ -117,7 +117,7 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf
&& abilityToModify.isControlledBy(source.getControllerId())) {
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
if (spell != null) {
- return spell != null && StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(spell, game);
+ return StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(spell, game);
} else {
Card sourceCard = game.getCard(abilityToModify.getSourceId());
return sourceCard != null && StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(sourceCard, game);
diff --git a/Mage.Sets/src/mage/cards/b/BattlegateMimic.java b/Mage.Sets/src/mage/cards/b/BattlegateMimic.java
index 7466db08d17..86ae874ccea 100644
--- a/Mage.Sets/src/mage/cards/b/BattlegateMimic.java
+++ b/Mage.Sets/src/mage/cards/b/BattlegateMimic.java
@@ -31,7 +31,7 @@ public final class BattlegateMimic extends CardImpl {
filter.add(new ColorPredicate(ObjectColor.WHITE));
}
- private String rule = "Whenever you cast a spell that's both red and white, {this} has base power and toughness 4/2 and gains first strike until end of turn.";
+ private static final String rule = "Whenever you cast a spell that's both red and white, {this} has base power and toughness 4/2 until end of turn and gains first strike until end of turn.";
public BattlegateMimic(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R/W}");
diff --git a/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java b/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java
index 7d7c48646ee..716eb9d1a32 100644
--- a/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java
+++ b/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java
@@ -35,7 +35,7 @@ public final class BattlegraceAngel extends CardImpl {
// Whenever a creature you control attacks alone, it gains lifelink until end of turn.
this.addAbility(new AttacksAloneControlledTriggeredAbility(new GainAbilityTargetEffect(
LifelinkAbility.getInstance(), Duration.EndOfTurn
- ).setText("it gains lifelink until end of turn")));
+ ).setText("it gains lifelink until end of turn"), true, false));
}
public BattlegraceAngel(final BattlegraceAngel card) {
diff --git a/Mage.Sets/src/mage/cards/b/BayouGroff.java b/Mage.Sets/src/mage/cards/b/BayouGroff.java
index b45b35fe2bd..52f441c2c2a 100644
--- a/Mage.Sets/src/mage/cards/b/BayouGroff.java
+++ b/Mage.Sets/src/mage/cards/b/BayouGroff.java
@@ -28,9 +28,9 @@ public final class BayouGroff extends CardImpl {
// As an additional cost to cast this spell, sacrifice a creature or pay {3}.
this.getSpellAbility().addCost(new OrCost(
- new SacrificeTargetCost(new TargetControlledPermanent(
+ "sacrifice a creature or pay {3}", new SacrificeTargetCost(new TargetControlledPermanent(
StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT
- )), new GenericManaCost(3), "sacrifice a creature or pay {3}"
+ )), new GenericManaCost(3)
));
}
diff --git a/Mage.Sets/src/mage/cards/b/BeaconOfDestiny.java b/Mage.Sets/src/mage/cards/b/BeaconOfDestiny.java
index 80b6b4c4aff..f390f76d8bb 100644
--- a/Mage.Sets/src/mage/cards/b/BeaconOfDestiny.java
+++ b/Mage.Sets/src/mage/cards/b/BeaconOfDestiny.java
@@ -71,7 +71,7 @@ class BeaconOfDestinyEffect extends RedirectionEffect {
@Override
public void init(Ability source, Game game) {
- this.damageSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game);
+ this.damageSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game);
super.init(source, game);
}
diff --git a/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java b/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java
index 1163654b047..04b192dc2c6 100644
--- a/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java
+++ b/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java
@@ -112,7 +112,7 @@ class BeamsplitterMageTriggeredAbility extends TriggeredAbilityImpl {
}
return game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
- getControllerId(), getSourceId(), game
+ getControllerId(), this, game
).stream()
.filter(Objects::nonNull)
.filter(permanent -> permanent.isCreature(game))
@@ -165,7 +165,7 @@ class BeamsplitterMageEffect extends OneShotEffect {
filter.add(new BeamsplitterMagePredicate(spell));
TargetPermanent target = new TargetPermanent(filter);
target.setNotTarget(true);
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/b/BearUmbra.java b/Mage.Sets/src/mage/cards/b/BearUmbra.java
index 66a746ee6f2..9041e77289a 100644
--- a/Mage.Sets/src/mage/cards/b/BearUmbra.java
+++ b/Mage.Sets/src/mage/cards/b/BearUmbra.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -13,33 +11,37 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.TotemArmorAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class BearUmbra extends CardImpl {
public BearUmbra(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");
this.subtype.add(SubType.AURA);
-
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
-
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
+
// Enchanted creature gets +2/+2 and has "Whenever this creature attacks, untap all lands you control."
- Ability attachedAbility = new AttacksTriggeredAbility(new UntapAllLandsControllerEffect(), false);
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(attachedAbility, AttachmentType.AURA)));
-
+ Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(2, 2));
+ ability.addEffect(new GainAbilityAttachedEffect(new AttacksTriggeredAbility(
+ new UntapAllLandsControllerEffect(), false
+ ), AttachmentType.AURA).setText("and has \"Whenever this creature attacks, untap all lands you control.\""));
+ this.addAbility(ability);
+
// Totem armor
this.addAbility(new TotemArmorAbility());
}
diff --git a/Mage.Sets/src/mage/cards/b/BeckCall.java b/Mage.Sets/src/mage/cards/b/BeckCall.java
index 5a5932f6956..0a63bff7c77 100644
--- a/Mage.Sets/src/mage/cards/b/BeckCall.java
+++ b/Mage.Sets/src/mage/cards/b/BeckCall.java
@@ -14,7 +14,6 @@ import mage.constants.SpellAbilityType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.BirdToken;
@@ -65,7 +64,7 @@ class BeckTriggeredAbility extends DelayedTriggeredAbility {
public boolean checkTrigger(GameEvent event, Game game) {
UUID targetId = event.getTargetId();
Permanent permanent = game.getPermanent(targetId);
- return filter.match(permanent, getSourceId(), getControllerId(), game);
+ return filter.match(permanent, getControllerId(), this, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BellowingSaddlebrute.java b/Mage.Sets/src/mage/cards/b/BellowingSaddlebrute.java
index 83c8dfd3755..08b697864de 100644
--- a/Mage.Sets/src/mage/cards/b/BellowingSaddlebrute.java
+++ b/Mage.Sets/src/mage/cards/b/BellowingSaddlebrute.java
@@ -32,7 +32,7 @@ public final class BellowingSaddlebrute extends CardImpl {
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new LoseLifeSourceControllerEffect(4)),
new InvertCondition(RaidCondition.instance),
- "Raid — When {this} enters the battlefield, you lose 4 life unless you attacked this turn.")
+ "When {this} enters the battlefield, you lose 4 life unless you attacked this turn.")
.setAbilityWord(AbilityWord.RAID)
.addHint(RaidHint.instance),
new PlayerAttackedWatcher());
diff --git a/Mage.Sets/src/mage/cards/b/BelltollDragon.java b/Mage.Sets/src/mage/cards/b/BelltollDragon.java
index d8385290b1c..bb6ed0e1bc3 100644
--- a/Mage.Sets/src/mage/cards/b/BelltollDragon.java
+++ b/Mage.Sets/src/mage/cards/b/BelltollDragon.java
@@ -41,7 +41,7 @@ public final class BelltollDragon extends CardImpl {
// Hexproof
this.addAbility(HexproofAbility.getInstance());
// Megamorph {5}{U}{U}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{U}{U}"), true));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{5}{U}{U}"), true));
// When Belltoll Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false));
diff --git a/Mage.Sets/src/mage/cards/b/BendOrBreak.java b/Mage.Sets/src/mage/cards/b/BendOrBreak.java
index 18018f38b28..fc347eb89d2 100644
--- a/Mage.Sets/src/mage/cards/b/BendOrBreak.java
+++ b/Mage.Sets/src/mage/cards/b/BendOrBreak.java
@@ -64,122 +64,123 @@ class BendOrBreakEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
+ if (controller == null) { return false; }
- // Map of players and their piles
- Map>> playerPermanents = new LinkedHashMap<>();
+ // Map of players and their piles
+ Map>> playerPermanents = new LinkedHashMap<>();
- PlayerList playerList = game.getState().getPlayerList().copy();
- while (!playerList.get().equals(source.getControllerId()) && controller.canRespond()) {
- playerList.getNext();
- }
- Player currentPlayer = game.getPlayer(playerList.get());
- Player nextPlayer;
- UUID firstNextPlayer = null;
-
- while (!getNextPlayerInDirection(true, playerList).equals(firstNextPlayer) && controller.canRespond()) {
- nextPlayer = game.getPlayer(playerList.get());
- if (nextPlayer == null) {
- return false;
- }
- if (firstNextPlayer == null) {
- firstNextPlayer = nextPlayer.getId();
- }
- if (!nextPlayer.canRespond()) {
- continue;
- }
- // Each player separates all nontoken lands they control into two piles
- if (currentPlayer != null && game.getState().getPlayersInRange(controller.getId(), game).contains(currentPlayer.getId())) {
- List firstPile = new ArrayList<>();
- List secondPile = new ArrayList<>();
- FilterControlledLandPermanent filter = new FilterControlledLandPermanent("lands you control to assign to the first pile (lands not chosen will be assigned to the second pile)");
- TargetPermanent target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true);
- if (target.canChoose(source.getSourceId(), currentPlayer.getId(), game)) {
- // TODO: add support for AI (50/50), need AI hints mechanic here
- currentPlayer.chooseTarget(Outcome.Neutral, target, source, game);
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, currentPlayer.getId(), game)) {
- if (target.getTargets().contains(permanent.getId())) {
- firstPile.add(permanent);
- } else {
- secondPile.add(permanent);
- }
- }
-
- StringBuilder sb = new StringBuilder("First pile of ").append(currentPlayer.getLogName()).append(": ");
- sb.append(firstPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
-
- game.informPlayers(sb.toString());
-
- sb = new StringBuilder("Second pile of ").append(currentPlayer.getLogName()).append(": ");
- sb.append(secondPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
-
- game.informPlayers(sb.toString());
- }
- List> playerPiles = new ArrayList<>();
- playerPiles.add(firstPile);
- playerPiles.add(secondPile);
- playerPermanents.put(currentPlayer.getId(), playerPiles);
- }
- currentPlayer = nextPlayer;
- }
-
- // For each player, one of their piles is chosen by one of their opponents of their choice
- for (Map.Entry>> playerPiles : playerPermanents.entrySet()) {
- Player player = game.getPlayer(playerPiles.getKey());
- if (player != null) {
- FilterPlayer filter = new FilterPlayer("opponent");
- List opponentPredicates = new ArrayList<>();
- for (UUID opponentId : game.getOpponents(player.getId())) {
- opponentPredicates.add(new PlayerIdPredicate(opponentId));
- }
- filter.add(Predicates.or(opponentPredicates));
- Target target = new TargetPlayer(1, 1, true, filter);
- target.setTargetController(player.getId());
- target.setAbilityController(source.getControllerId());
- if (player.chooseTarget(outcome, target, source, game)) {
- Player chosenOpponent = game.getPlayer(target.getFirstTarget());
- if (chosenOpponent != null) {
- List firstPile = playerPiles.getValue().get(0);
- List secondPile = playerPiles.getValue().get(1);
- game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to choose their pile");
- if (chosenOpponent.choosePile(outcome, "Piles of " + player.getName(), firstPile, secondPile, game)) {
- List> lists = playerPiles.getValue();
- lists.clear();
- lists.add(firstPile);
- lists.add(secondPile);
- game.informPlayers(player.getLogName() + " will have their first pile destroyed");
- } else {
- List> lists = playerPiles.getValue();
- lists.clear();
- lists.add(secondPile);
- lists.add(firstPile);
- game.informPlayers(player.getLogName() + " will have their second pile destroyed");
- }
- }
- }
- }
- }
- // Destroy all lands in the chosen piles. Tap all lands in the other piles
- for (Map.Entry>> playerPiles : playerPermanents.entrySet()) {
- Player player = game.getPlayer(playerPiles.getKey());
- if (player != null) {
- List pileToSac = playerPiles.getValue().get(0);
- List pileToTap = playerPiles.getValue().get(1);
- for (Permanent permanent : pileToSac) {
- if (permanent != null) {
- permanent.destroy(source, game, false);
- }
- }
- for (Permanent permanent : pileToTap) {
- if (permanent != null) {
- permanent.tap(source, game);
- }
- }
- }
- }
- return true;
+ PlayerList playerList = game.getState().getPlayerList().copy();
+ while (!playerList.get().equals(source.getControllerId()) && controller.canRespond()) {
+ playerList.getNext();
}
- return false;
+ Player currentPlayer = game.getPlayer(playerList.get());
+ Player nextPlayer;
+ UUID firstNextPlayer = null;
+
+ while (!getNextPlayerInDirection(true, playerList).equals(firstNextPlayer) && controller.canRespond()) {
+ nextPlayer = game.getPlayer(playerList.get());
+ if (nextPlayer == null) {
+ return false;
+ }
+ if (firstNextPlayer == null) {
+ firstNextPlayer = nextPlayer.getId();
+ }
+ if (!nextPlayer.canRespond()) {
+ continue;
+ }
+ // Each player separates all nontoken lands they control into two piles
+ if (currentPlayer == null || !game.getState().getPlayersInRange(controller.getId(), game).contains(currentPlayer.getId())) {
+ continue;
+ }
+ List firstPile = new ArrayList<>();
+ List secondPile = new ArrayList<>();
+ FilterControlledLandPermanent filter = new FilterControlledLandPermanent("lands you control to assign to the first pile (lands not chosen will be assigned to the second pile)");
+ TargetPermanent target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true);
+ if (!target.canChoose(currentPlayer.getId(), source, game)) { continue; }
+
+ // TODO: add support for AI (50/50), need AI hints mechanic here
+ currentPlayer.chooseTarget(Outcome.Neutral, target, source, game);
+ for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, currentPlayer.getId(), game)) {
+ if (target.getTargets().contains(permanent.getId())) {
+ firstPile.add(permanent);
+ } else {
+ secondPile.add(permanent);
+ }
+ }
+
+ StringBuilder sb = new StringBuilder("First pile of ").append(currentPlayer.getLogName()).append(": ");
+ sb.append(firstPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
+
+ game.informPlayers(sb.toString());
+
+ sb = new StringBuilder("Second pile of ").append(currentPlayer.getLogName()).append(": ");
+ sb.append(secondPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
+
+ game.informPlayers(sb.toString());
+
+ List> playerPiles = new ArrayList<>();
+ playerPiles.add(firstPile);
+ playerPiles.add(secondPile);
+ playerPermanents.put(currentPlayer.getId(), playerPiles);
+
+ currentPlayer = nextPlayer;
+ }
+
+ // For each player, one of their piles is chosen by one of their opponents of their choice
+ for (Map.Entry>> playerPiles : playerPermanents.entrySet()) {
+ Player player = game.getPlayer(playerPiles.getKey());
+ if (player == null) { continue; }
+
+ FilterPlayer filter = new FilterPlayer("opponent");
+ List opponentPredicates = new ArrayList<>();
+ for (UUID opponentId : game.getOpponents(player.getId())) {
+ opponentPredicates.add(new PlayerIdPredicate(opponentId));
+ }
+ filter.add(Predicates.or(opponentPredicates));
+ Target target = new TargetPlayer(1, 1, true, filter);
+ target.setTargetController(player.getId());
+ target.setAbilityController(source.getControllerId());
+ if (!player.chooseTarget(outcome, target, source, game)) { continue; }
+
+ Player chosenOpponent = game.getPlayer(target.getFirstTarget());
+ if (chosenOpponent == null) { continue; }
+
+ List firstPile = playerPiles.getValue().get(0);
+ List secondPile = playerPiles.getValue().get(1);
+ game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to choose their pile");
+ if (chosenOpponent.choosePile(outcome, "Piles of " + player.getName(), firstPile, secondPile, game)) {
+ List> lists = playerPiles.getValue();
+ lists.clear();
+ lists.add(firstPile);
+ lists.add(secondPile);
+ game.informPlayers(player.getLogName() + " will have their first pile destroyed");
+ } else {
+ List> lists = playerPiles.getValue();
+ lists.clear();
+ lists.add(secondPile);
+ lists.add(firstPile);
+ game.informPlayers(player.getLogName() + " will have their second pile destroyed");
+ }
+ }
+ // Destroy all lands in the chosen piles. Tap all lands in the other piles
+ for (Map.Entry>> playerPiles : playerPermanents.entrySet()) {
+ Player player = game.getPlayer(playerPiles.getKey());
+ if (player == null) { continue; }
+
+ List pileToSac = playerPiles.getValue().get(0);
+ List pileToTap = playerPiles.getValue().get(1);
+ for (Permanent permanent : pileToSac) {
+ if (permanent != null) {
+ permanent.destroy(source, game, false);
+ }
+ }
+ for (Permanent permanent : pileToTap) {
+ if (permanent != null) {
+ permanent.tap(source, game);
+ }
+ }
+ }
+ return true;
}
private UUID getNextPlayerInDirection(boolean left, PlayerList playerList) {
diff --git a/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java b/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java
index cccf8353357..b391ad05407 100644
--- a/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java
+++ b/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java
@@ -61,7 +61,7 @@ class BenefactionOfRhonasEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject != null && controller != null) {
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
boolean creatureCardFound = false;
diff --git a/Mage.Sets/src/mage/cards/b/BenevolentOffering.java b/Mage.Sets/src/mage/cards/b/BenevolentOffering.java
index c6bd066c468..f3365b3f2be 100644
--- a/Mage.Sets/src/mage/cards/b/BenevolentOffering.java
+++ b/Mage.Sets/src/mage/cards/b/BenevolentOffering.java
@@ -63,19 +63,18 @@ class BenevolentOfferingEffect1 extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Target target = new TargetOpponent(true);
- target.choose(Outcome.Sacrifice, source.getControllerId(), source.getSourceId(), game);
- Player opponent = game.getPlayer(target.getFirstTarget());
- if (opponent != null) {
- Effect effect = new CreateTokenTargetEffect(new SpiritWhiteToken(), 3);
- effect.setTargetPointer(new FixedTarget(opponent.getId()));
- effect.apply(game, source);
- new CreateTokenEffect(new SpiritWhiteToken(), 3).apply(game, source);
- return true;
- }
- }
- return false;
+ if (controller == null) { return false; }
+
+ Target target = new TargetOpponent(true);
+ target.choose(Outcome.Sacrifice, source.getControllerId(), source.getSourceId(), source, game);
+ Player opponent = game.getPlayer(target.getFirstTarget());
+ if (opponent == null) { return false; }
+
+ Effect effect = new CreateTokenTargetEffect(new SpiritWhiteToken(), 3);
+ effect.setTargetPointer(new FixedTarget(opponent.getId()));
+ effect.apply(game, source);
+ new CreateTokenEffect(new SpiritWhiteToken(), 3).apply(game, source);
+ return true;
}
}
@@ -98,18 +97,18 @@ class BenevolentOfferingEffect2 extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Target target = new TargetOpponent(true);
- target.choose(Outcome.Sacrifice, source.getControllerId(), source.getSourceId(), game);
- Player opponent = game.getPlayer(target.getFirstTarget());
- if (opponent != null) {
- int count = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, controller.getId(), game) * 2;
- controller.gainLife(count, game, source);
- count = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, opponent.getId(), game) * 2;
- opponent.gainLife(count, game, source);
- return true;
- }
- }
- return false;
+ if (controller == null) { return false; }
+
+ Target target = new TargetOpponent(true);
+ target.choose(Outcome.Sacrifice, source.getControllerId(), source.getSourceId(), source, game);
+ Player opponent = game.getPlayer(target.getFirstTarget());
+ if (opponent == null) { return false; }
+
+ int count = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, controller.getId(), game) * 2;
+ controller.gainLife(count, game, source);
+ count = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, opponent.getId(), game) * 2;
+ opponent.gainLife(count, game, source);
+
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BennieBracksZoologist.java b/Mage.Sets/src/mage/cards/b/BennieBracksZoologist.java
new file mode 100644
index 00000000000..26729bc7206
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BennieBracksZoologist.java
@@ -0,0 +1,47 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.condition.common.CreatedTokenThisTurnCondition;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.keyword.ConvokeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.watchers.common.CreatedTokenWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BennieBracksZoologist extends CardImpl {
+
+ public BennieBracksZoologist(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.DRUID);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Convoke
+ this.addAbility(new ConvokeAbility());
+
+ // At the beginning of each end step, if you created a token this turn, draw a card.
+ this.addAbility(new BeginningOfEndStepTriggeredAbility(
+ Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1),
+ TargetController.ANY, CreatedTokenThisTurnCondition.instance, false
+ ).addHint(CreatedTokenThisTurnCondition.getHint()), new CreatedTokenWatcher());
+ }
+
+ private BennieBracksZoologist(final BennieBracksZoologist card) {
+ super(card);
+ }
+
+ @Override
+ public BennieBracksZoologist copy() {
+ return new BennieBracksZoologist(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BenthicExplorers.java b/Mage.Sets/src/mage/cards/b/BenthicExplorers.java
index 1b91349da20..661e60a3040 100644
--- a/Mage.Sets/src/mage/cards/b/BenthicExplorers.java
+++ b/Mage.Sets/src/mage/cards/b/BenthicExplorers.java
@@ -67,7 +67,7 @@ public final class BenthicExplorers extends CardImpl {
class BenthicExplorersCost extends CostImpl {
- TargetLandPermanent target;
+ private final TargetLandPermanent target;
public BenthicExplorersCost(TargetLandPermanent target) {
this.target = target;
@@ -81,7 +81,7 @@ class BenthicExplorersCost extends CostImpl {
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
- if (target.choose(Outcome.Untap, controllerId, source.getSourceId(), game)) {
+ if (target.choose(Outcome.Untap, controllerId, source.getSourceId(), source, game)) {
for (UUID targetId : target.getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent == null) {
@@ -98,7 +98,7 @@ class BenthicExplorersCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return target.canChoose(source.getSourceId(), controllerId, game);
+ return target.canChoose(controllerId, source, game);
}
@Override
@@ -155,59 +155,60 @@ class BenthicExplorersManaEffect extends ManaEffect {
@Override
public Mana produceMana(Game game, Ability source) {
Mana mana = new Mana();
- if (game == null) {
- return mana;
- }
+ if (game == null) { return mana; }
+
Choice choice = ManaType.getChoiceOfManaTypes(getManaTypes(game, source), false);
- if (!choice.getChoices().isEmpty()) {
- Player player = game.getPlayer(source.getControllerId());
- if (choice.getChoices().size() == 1) {
- choice.setChoice(choice.getChoices().iterator().next());
- } else {
- if (player == null
- || !player.choose(Outcome.Neutral, choice, game)) {
- return mana;
- }
- }
- if (choice.getChoice() != null) {
- switch (choice.getChoice()) {
- case "Black":
- mana.setBlack(1);
- break;
- case "Blue":
- mana.setBlue(1);
- break;
- case "Red":
- mana.setRed(1);
- break;
- case "Green":
- mana.setGreen(1);
- break;
- case "White":
- mana.setWhite(1);
- break;
- case "Colorless":
- mana.setColorless(1);
- break;
- }
+ if (choice.getChoices().isEmpty()) { return mana; }
+
+ Player player = game.getPlayer(source.getControllerId());
+ if (choice.getChoices().size() == 1) {
+ choice.setChoice(choice.getChoices().iterator().next());
+ } else {
+ if (player == null
+ || !player.choose(Outcome.Neutral, choice, game)) {
+ return mana;
}
}
+
+ if (choice.getChoice() == null) { return mana; }
+
+ switch (choice.getChoice()) {
+ case "Black":
+ mana.setBlack(1);
+ break;
+ case "Blue":
+ mana.setBlue(1);
+ break;
+ case "Red":
+ mana.setRed(1);
+ break;
+ case "Green":
+ mana.setGreen(1);
+ break;
+ case "White":
+ mana.setWhite(1);
+ break;
+ case "Colorless":
+ mana.setColorless(1);
+ break;
+ }
+
return mana;
}
private Set getManaTypes(Game game, Ability source) {
Set types = EnumSet.noneOf(ManaType.class);
- if (game == null
- || game.getPhase() == null) {
+ if (game == null || game.getPhase() == null) {
return types;
}
+
Permanent land = (Permanent) game.getState().getValue("UntapTargetCost" + source.getSourceId().toString());
- if (land != null) {
- Abilities mana = land.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD);
- for (ActivatedManaAbilityImpl ability : mana) {
- if (ability.definesMana(game)) {
- types.addAll(ability.getProducableManaTypes(game));
- }
+ if (land == null) { return types; }
+
+ Abilities mana = land.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD);
+ for (ActivatedManaAbilityImpl ability : mana) {
+ if (ability.definesMana(game)) {
+ types.addAll(ability.getProducableManaTypes(game));
}
}
return types;
diff --git a/Mage.Sets/src/mage/cards/b/Benthicore.java b/Mage.Sets/src/mage/cards/b/Benthicore.java
index 7f9763a7040..f4151c1554f 100644
--- a/Mage.Sets/src/mage/cards/b/Benthicore.java
+++ b/Mage.Sets/src/mage/cards/b/Benthicore.java
@@ -45,8 +45,8 @@ public final class Benthicore extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MerfolkWizardToken(), 2), false));
// Tap two untapped Merfolk you control: Untap Benthicore. It gains shroud until end of turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new TapTargetCost(new TargetControlledPermanent(2, 2, filter, false)));
- ability.addEffect(new GainAbilitySourceEffect(ShroudAbility.getInstance(), Duration.EndOfTurn));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new TapTargetCost(new TargetControlledPermanent(2, filter)));
+ ability.addEffect(new GainAbilitySourceEffect(ShroudAbility.getInstance(), Duration.EndOfTurn).setText("it gains shroud until end of turn"));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/Berserk.java b/Mage.Sets/src/mage/cards/b/Berserk.java
index ab4ac242365..da69f465d89 100644
--- a/Mage.Sets/src/mage/cards/b/Berserk.java
+++ b/Mage.Sets/src/mage/cards/b/Berserk.java
@@ -127,15 +127,15 @@ class BerserkDestroyEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- //create delayed triggered ability
- Effect effect = new BerserkDelayedDestroyEffect();
- effect.setTargetPointer(new FixedTarget(this.getTargetPointer().getFirst(game, source), game));
- AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
- game.addDelayedTriggeredAbility(delayedAbility, source);
- return true;
- }
- return false;
+ if (controller == null) { return false; }
+
+ //create delayed triggered ability
+ Effect effect = new BerserkDelayedDestroyEffect();
+ effect.setTargetPointer(new FixedTarget(this.getTargetPointer().getFirst(game, source), game));
+ AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
+ game.addDelayedTriggeredAbility(delayedAbility, source);
+
+ return true;
}
}
@@ -158,15 +158,15 @@ class BerserkDelayedDestroyEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
- if (permanent != null) {
- AttackedThisTurnWatcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
- if (watcher.getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))) {
- return permanent.destroy(source, game, false);
- }
- }
- }
- return false;
+ if (controller == null) { return false; }
+
+ Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
+ if (permanent == null) { return false; }
+
+ AttackedThisTurnWatcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
+ if (watcher == null) { return false; }
+
+ return watcher.getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))
+ && permanent.destroy(source, game, false);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BerserkersFrenzy.java b/Mage.Sets/src/mage/cards/b/BerserkersFrenzy.java
index 2dc7617417e..744b5503e4e 100644
--- a/Mage.Sets/src/mage/cards/b/BerserkersFrenzy.java
+++ b/Mage.Sets/src/mage/cards/b/BerserkersFrenzy.java
@@ -99,7 +99,7 @@ class BerserkersFrenzyEffect extends OneShotEffect {
}
TargetPermanent target = new TargetCreaturePermanent(0, Integer.MAX_VALUE);
target.setNotTarget(true);
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
game.addEffect(new BlocksIfAbleTargetEffect(Duration.EndOfTurn)
.setTargetPointer(new FixedTargets(new CardsImpl(target.getTargets()), game)), source);
return true;
diff --git a/Mage.Sets/src/mage/cards/b/Besmirch.java b/Mage.Sets/src/mage/cards/b/Besmirch.java
index ff160ad483e..f510600418d 100644
--- a/Mage.Sets/src/mage/cards/b/Besmirch.java
+++ b/Mage.Sets/src/mage/cards/b/Besmirch.java
@@ -1,9 +1,6 @@
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.Ability;
-import mage.abilities.effects.ContinuousEffect;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.effects.common.combat.GoadTargetEffect;
@@ -20,8 +17,9 @@ import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import mage.target.targetpointer.TargetPointer;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class Besmirch extends CardImpl {
@@ -66,24 +64,19 @@ class BesmirchEffect extends OneShotEffect {
TargetPointer target = new FixedTarget(source.getFirstTarget(), game);
// gain control
- ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn);
- effect.setTargetPointer(target);
- game.addEffect(effect, source);
+ game.addEffect(new GainControlTargetEffect(Duration.EndOfTurn)
+ .setTargetPointer(target), source);
// haste
- effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn);
- effect.setTargetPointer(target);
- game.addEffect(effect, source);
+ game.addEffect(new GainAbilityTargetEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn
+ ).setTargetPointer(target), source);
// goad
- Effect effect2 = new GoadTargetEffect();
- effect2.setTargetPointer(target);
- effect2.apply(game, source);
+ game.addEffect(new GoadTargetEffect().setTargetPointer(target), source);
// untap
- effect2 = new UntapTargetEffect();
- effect2.setTargetPointer(target);
- effect2.apply(game, source);
+ new UntapTargetEffect().setTargetPointer(target).apply(game, source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java b/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java
index f5a8328bbda..08741a0f536 100644
--- a/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java
+++ b/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java
@@ -33,8 +33,7 @@ public final class BetrayalOfFlesh extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// or return target creature card from your graveyard to the battlefield.
- Mode mode = new Mode();
- mode.addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect());
+ Mode mode = new Mode(new ReturnFromGraveyardToBattlefieldTargetEffect());
mode.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
this.getSpellAbility().getModes().addMode(mode);
// Entwine-Sacrifice three lands.
diff --git a/Mage.Sets/src/mage/cards/b/Bewilder.java b/Mage.Sets/src/mage/cards/b/Bewilder.java
index 10ddaddde57..4d13dcb3072 100644
--- a/Mage.Sets/src/mage/cards/b/Bewilder.java
+++ b/Mage.Sets/src/mage/cards/b/Bewilder.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
@@ -10,21 +8,22 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class Bewilder extends CardImpl {
public Bewilder(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");
// Target creature gets -3/-0 until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(-3, 0, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+
// Draw a card.
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
"));
}
private Bewilder(final Bewilder card) {
diff --git a/Mage.Sets/src/mage/cards/b/BigGameHunter.java b/Mage.Sets/src/mage/cards/b/BigGameHunter.java
index cefa0d6c158..ca3cd824caf 100644
--- a/Mage.Sets/src/mage/cards/b/BigGameHunter.java
+++ b/Mage.Sets/src/mage/cards/b/BigGameHunter.java
@@ -41,7 +41,7 @@ public final class BigGameHunter extends CardImpl {
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
// Madness {B}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{B}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{B}")));
}
private BigGameHunter(final BigGameHunter card) {
diff --git a/Mage.Sets/src/mage/cards/b/BigScore.java b/Mage.Sets/src/mage/cards/b/BigScore.java
new file mode 100644
index 00000000000..83f24b0b3ae
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BigScore.java
@@ -0,0 +1,37 @@
+package mage.cards.b;
+
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.permanent.token.TreasureToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BigScore extends CardImpl {
+
+ public BigScore(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}");
+
+ // As an additional cost to cast this spell, draw a card.
+ this.getSpellAbility().addCost(new DiscardCardCost(false));
+
+ // Draw two cards and create two Treasure tokens.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken(), 2).concatBy("and"));
+ }
+
+ private BigScore(final BigScore card) {
+ super(card);
+ }
+
+ @Override
+ public BigScore copy() {
+ return new BigScore(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BindingAgony.java b/Mage.Sets/src/mage/cards/b/BindingAgony.java
index 8f73dfd4190..f3332c069d1 100644
--- a/Mage.Sets/src/mage/cards/b/BindingAgony.java
+++ b/Mage.Sets/src/mage/cards/b/BindingAgony.java
@@ -1,13 +1,10 @@
-
package mage.cards.b;
import java.util.UUID;
-import mage.abilities.Ability;
import mage.abilities.common.DealtDamageAttachedTriggeredAbility;
-import mage.abilities.dynamicvalue.common.NumericSetToEffectValues;
-import mage.abilities.effects.Effect;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.common.AttachEffect;
-import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.DamageAttachedControllerEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -29,12 +26,10 @@ public final class BindingAgony extends CardImpl {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
+
// Whenever enchanted creature is dealt damage, Binding Agony deals that much damage to that creature's controller.
- Effect effect = new DamageTargetEffect(new NumericSetToEffectValues("that much", "damage"));
- effect.setText("{this} deals that much damage to that creature's controller");
- this.addAbility(new DealtDamageAttachedTriggeredAbility(Zone.BATTLEFIELD, effect, false, SetTargetPointer.PLAYER));
+ this.addAbility(new DealtDamageAttachedTriggeredAbility(new DamageAttachedControllerEffect(SavedDamageValue.MUCH), false));
}
private BindingAgony(final BindingAgony card) {
diff --git a/Mage.Sets/src/mage/cards/b/BiomanticMastery.java b/Mage.Sets/src/mage/cards/b/BiomanticMastery.java
index 19742a056f7..73de4b5d5d7 100644
--- a/Mage.Sets/src/mage/cards/b/BiomanticMastery.java
+++ b/Mage.Sets/src/mage/cards/b/BiomanticMastery.java
@@ -26,7 +26,6 @@ public final class BiomanticMastery extends CardImpl {
// Draw a card for each creature target player controls, then draw a card for each creature another target player controls.
this.getSpellAbility().addEffect(new BiomanticMasteryEffect());
this.getSpellAbility().addTarget(new TargetPlayer(2));
-
}
private BiomanticMastery(final BiomanticMastery card) {
@@ -58,16 +57,15 @@ class BiomanticMasteryEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- for (UUID playerId : getTargetPointer().getTargets(game, source)) {
- Player player = game.getPlayer(playerId);
- if (player != null) {
- int creatures = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game);
- controller.drawCards(creatures, source, game);
- }
- }
- return true;
+ if (controller == null) { return false; }
+
+ for (UUID playerId : getTargetPointer().getTargets(game, source)) {
+ Player player = game.getPlayer(playerId);
+ if (player == null) { continue; }
+
+ int creatures = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game);
+ controller.drawCards(creatures, source, game);
}
- return false;
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BirchloreRangers.java b/Mage.Sets/src/mage/cards/b/BirchloreRangers.java
index 29f0351e04e..ebcbbf2eef7 100644
--- a/Mage.Sets/src/mage/cards/b/BirchloreRangers.java
+++ b/Mage.Sets/src/mage/cards/b/BirchloreRangers.java
@@ -45,7 +45,7 @@ public final class BirchloreRangers extends CardImpl {
new TapTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, false))));
// Morph {G}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{G}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{G}")));
}
private BirchloreRangers(final BirchloreRangers card) {
@@ -80,7 +80,7 @@ class BirchloreRangersManaEffect extends AddManaOfAnyColorEffect {
@Override
public List getNetMana(Game game, Ability source) {
if (game != null && game.inCheckPlayableState()) {
- int count = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) / 2;
+ int count = game.getBattlefield().count(filter, source.getControllerId(), source, game) / 2;
List netMana = new ArrayList<>();
if (count > 0) {
netMana.add(Mana.AnyMana(count * 2));
diff --git a/Mage.Sets/src/mage/cards/b/BitingPalmNinja.java b/Mage.Sets/src/mage/cards/b/BitingPalmNinja.java
index 54545f492f1..8197edfd741 100644
--- a/Mage.Sets/src/mage/cards/b/BitingPalmNinja.java
+++ b/Mage.Sets/src/mage/cards/b/BitingPalmNinja.java
@@ -44,7 +44,7 @@ public final class BitingPalmNinja extends CardImpl {
new DoWhenCostPaid(new ReflexiveTriggeredAbility(
new ExileCardYouChooseTargetOpponentEffect(StaticFilters.FILTER_CARD_A_NON_LAND), false,
"that player reveals their hand and you choose a nonland card from it. Exile that card"
- ), new RemoveCountersSourceCost(CounterType.MENACE.createInstance()), "Remove a menace counter?"), false, true
+ ), new RemoveCountersSourceCost(CounterType.MENACE.createInstance()).setText("remove a menace counter from it"), "Remove a menace counter?"), false, true
));
}
diff --git a/Mage.Sets/src/mage/cards/b/BitingRain.java b/Mage.Sets/src/mage/cards/b/BitingRain.java
index 005b8b1aab0..c9b8312f934 100644
--- a/Mage.Sets/src/mage/cards/b/BitingRain.java
+++ b/Mage.Sets/src/mage/cards/b/BitingRain.java
@@ -23,7 +23,7 @@ public final class BitingRain extends CardImpl {
this.getSpellAbility().addEffect(new BoostAllEffect(-2, -2, Duration.EndOfTurn));
// Madness {2}{B}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{2}{B}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{2}{B}")));
}
private BitingRain(final BitingRain card) {
diff --git a/Mage.Sets/src/mage/cards/b/BitterFeud.java b/Mage.Sets/src/mage/cards/b/BitterFeud.java
index 8ad9ab2694b..8ced30b6ded 100644
--- a/Mage.Sets/src/mage/cards/b/BitterFeud.java
+++ b/Mage.Sets/src/mage/cards/b/BitterFeud.java
@@ -63,23 +63,27 @@ class BitterFeudEntersBattlefieldEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false; }
+
Permanent permanent = game.getPermanentEntering(source.getSourceId());
- if (controller != null && permanent != null) {
- TargetPlayer target = new TargetPlayer(2, 2, true);
- controller.chooseTarget(outcome, target, source, game);
- Player player1 = game.getPlayer(target.getFirstTarget());
- if (target.getTargets().size() > 1) {
- Player player2 = game.getPlayer(target.getTargets().get(1));
- if (player1 != null && player2 != null) {
- game.getState().setValue(source.getSourceId() + "_player1", player1);
- game.getState().setValue(source.getSourceId() + "_player2", player2);
- game.informPlayers(permanent.getLogName() + ": " + controller.getLogName() + " has chosen " + player1.getLogName() + " and " + player2.getLogName());
- permanent.addInfo("chosen players", "Chosen players: " + player1.getName() + ", " + player2.getName() + "", game);
- return true;
- }
- }
- }
- return false;
+ if (permanent == null) { return false; }
+
+ TargetPlayer target = new TargetPlayer(2, 2, true);
+ controller.chooseTarget(outcome, target, source, game);
+ Player player1 = game.getPlayer(target.getFirstTarget());
+ if (player1 == null) { return false; }
+
+ if (target.getTargets().size() <= 1) { return false; }
+
+ Player player2 = game.getPlayer(target.getTargets().get(1));
+ if (player2 == null) { return false; }
+
+ game.getState().setValue(source.getSourceId() + "_player1", player1);
+ game.getState().setValue(source.getSourceId() + "_player2", player2);
+ game.informPlayers(permanent.getLogName() + ": " + controller.getLogName() + " has chosen " + player1.getLogName() + " and " + player2.getLogName());
+ permanent.addInfo("chosen players", "Chosen players: " + player1.getName() + ", " + player2.getName() + "", game);
+
+ return true;
}
@Override
@@ -91,8 +95,8 @@ class BitterFeudEntersBattlefieldEffect extends OneShotEffect {
class BitterFeudEffect extends ReplacementEffectImpl {
- Player player1;
- Player player2;
+ private Player player1;
+ private Player player2;
public BitterFeudEffect() {
super(Duration.WhileOnBattlefield, Outcome.Damage);
@@ -101,6 +105,8 @@ class BitterFeudEffect extends ReplacementEffectImpl {
public BitterFeudEffect(final BitterFeudEffect effect) {
super(effect);
+ this.player1 = effect.player1;
+ this.player2 = effect.player2;
}
@Override
@@ -110,54 +116,50 @@ class BitterFeudEffect extends ReplacementEffectImpl {
@Override
public boolean checksEventType(GameEvent event, Game game) {
- switch (event.getType()) {
- case DAMAGE_PERMANENT:
- case DAMAGE_PLAYER:
- return true;
- default:
- return false;
- }
+ return event.getType() == GameEvent.EventType.DAMAGE_PERMANENT && event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
player1 = (Player) game.getState().getValue(source.getSourceId() + "_player1");
- player2 = (Player) game.getState().getValue(source.getSourceId() + "_player2");
- if (player1 != null && player2 != null) {
- UUID targetPlayerId = null;
- switch (event.getType()) {
- case DAMAGE_PLAYER:
- targetPlayerId = event.getTargetId();
- break;
- case DAMAGE_PERMANENT:
- Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent != null) {
- targetPlayerId = permanent.getControllerId();
- }
- break;
- default:
- return false;
- }
+ if (player1 == null) { return false; }
- if (player1.getId().equals(targetPlayerId) || player2.getId().equals(targetPlayerId)) {
- UUID sourcePlayerId = null;
- MageObject damageSource = game.getObject(event.getSourceId());
- if (damageSource instanceof StackObject) {
- sourcePlayerId = ((StackObject) damageSource).getControllerId();
- } else if (damageSource instanceof Permanent) {
- sourcePlayerId = ((Permanent) damageSource).getControllerId();
- } else if (damageSource instanceof Card) {
- sourcePlayerId = ((Card) damageSource).getOwnerId();
- }
- if (sourcePlayerId != null
- && (player1.getId().equals(sourcePlayerId) || player2.getId().equals(sourcePlayerId))
- && !sourcePlayerId.equals(targetPlayerId)) {
- return true;
- }
- }
+ player2 = (Player) game.getState().getValue(source.getSourceId() + "_player2");
+ if (player2 == null) { return false; }
+
+ UUID targetPlayerId;
+ switch (event.getType()) {
+ case DAMAGE_PLAYER:
+ targetPlayerId = event.getTargetId();
+ break;
+ case DAMAGE_PERMANENT:
+ Permanent permanent = game.getPermanent(event.getTargetId());
+ if (permanent == null) { return false; }
+
+ targetPlayerId = permanent.getControllerId();
+ break;
+ default:
+ return false;
}
- return false;
+ if (!player1.getId().equals(targetPlayerId) && !player2.getId().equals(targetPlayerId)) { return false; }
+
+ UUID sourcePlayerId;
+ MageObject damageSource = game.getObject(event.getSourceId());
+
+ if (damageSource instanceof StackObject) {
+ sourcePlayerId = ((StackObject) damageSource).getControllerId();
+ } else if (damageSource instanceof Permanent) {
+ sourcePlayerId = ((Permanent) damageSource).getControllerId();
+ } else if (damageSource instanceof Card) {
+ sourcePlayerId = ((Card) damageSource).getOwnerId();
+ } else {
+ return false;
+ }
+
+ return sourcePlayerId != null
+ && (player1.getId().equals(sourcePlayerId) || player2.getId().equals(sourcePlayerId))
+ && !sourcePlayerId.equals(targetPlayerId);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BitterOrdeal.java b/Mage.Sets/src/mage/cards/b/BitterOrdeal.java
index 2e445d8d26d..22dd7745b16 100644
--- a/Mage.Sets/src/mage/cards/b/BitterOrdeal.java
+++ b/Mage.Sets/src/mage/cards/b/BitterOrdeal.java
@@ -1,37 +1,28 @@
-
package mage.cards.b;
-import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.search.SearchLibraryAndExileTargetEffect;
import mage.abilities.keyword.GravestormAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
-import mage.game.Game;
-import mage.players.Player;
import mage.target.TargetPlayer;
-import mage.target.common.TargetCardInLibrary;
-import mage.watchers.common.GravestormWatcher;
+
+import java.util.UUID;
/**
- *
* @author emerald000
*/
public final class BitterOrdeal extends CardImpl {
public BitterOrdeal(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
// Search target player's library for a card and exile it. Then that player shuffles their library.
- this.getSpellAbility().addEffect(new BitterOrdealEffect());
+ this.getSpellAbility().addEffect(new SearchLibraryAndExileTargetEffect(1, false));
this.getSpellAbility().addTarget(new TargetPlayer());
-
+
// Gravestorm
- this.addAbility(new GravestormAbility(), new GravestormWatcher());
+ this.addAbility(new GravestormAbility());
}
private BitterOrdeal(final BitterOrdeal card) {
@@ -43,38 +34,3 @@ public final class BitterOrdeal extends CardImpl {
return new BitterOrdeal(this);
}
}
-
-class BitterOrdealEffect extends OneShotEffect {
-
- BitterOrdealEffect() {
- super(Outcome.Exile);
- staticText = "Search target player's library for a card and exile it. Then that player shuffles.";
- }
-
- BitterOrdealEffect(final BitterOrdealEffect effect) {
- super(effect);
- }
-
- @Override
- public BitterOrdealEffect copy() {
- return new BitterOrdealEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null && targetPlayer != null) {
- TargetCardInLibrary target = new TargetCardInLibrary();
- if (controller.searchLibrary(target, source, game, targetPlayer.getId())) {
- Card card = targetPlayer.getLibrary().getCard(target.getFirstTarget(), game);
- if (card != null) {
- controller.moveCardToExileWithInfo(card, null, null, source, game, Zone.LIBRARY, true);
- }
- }
- targetPlayer.shuffleLibrary(source, game);
- return true;
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BitterRevelation.java b/Mage.Sets/src/mage/cards/b/BitterRevelation.java
index 531e91595f6..0e37f7fbaa2 100644
--- a/Mage.Sets/src/mage/cards/b/BitterRevelation.java
+++ b/Mage.Sets/src/mage/cards/b/BitterRevelation.java
@@ -1,14 +1,12 @@
-
package mage.cards.b;
import java.util.UUID;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
-import mage.cards.*;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.filter.StaticFilters;
/**
*
@@ -20,8 +18,7 @@ public final class BitterRevelation extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Look at the top four cards of your library. Put two of them into your hand and the rest into your graveyard. You lose 2 life.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(StaticValue.get(4), false, StaticValue.get(2),
- StaticFilters.FILTER_CARD, Zone.GRAVEYARD, false, false, false, Zone.HAND, false));
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(4, 2, PutCards.HAND, PutCards.GRAVEYARD));
this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(2));
}
diff --git a/Mage.Sets/src/mage/cards/l/LucasTheSharpshooter.java b/Mage.Sets/src/mage/cards/b/BjornaNightfallAlchemist.java
similarity index 83%
rename from Mage.Sets/src/mage/cards/l/LucasTheSharpshooter.java
rename to Mage.Sets/src/mage/cards/b/BjornaNightfallAlchemist.java
index 1f6fce94307..99b286dd644 100644
--- a/Mage.Sets/src/mage/cards/l/LucasTheSharpshooter.java
+++ b/Mage.Sets/src/mage/cards/b/BjornaNightfallAlchemist.java
@@ -1,4 +1,4 @@
-package mage.cards.l;
+package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
@@ -22,9 +22,9 @@ import java.util.UUID;
/**
* @author TheElk801
*/
-public final class LucasTheSharpshooter extends CardImpl {
+public final class BjornaNightfallAlchemist extends CardImpl {
- public LucasTheSharpshooter(UUID ownerId, CardSetInfo setInfo) {
+ public BjornaNightfallAlchemist(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{R}");
this.addSuperType(SuperType.LEGENDARY);
@@ -43,12 +43,12 @@ public final class LucasTheSharpshooter extends CardImpl {
this.addAbility(FriendsForeverAbility.getInstance());
}
- private LucasTheSharpshooter(final LucasTheSharpshooter card) {
+ private BjornaNightfallAlchemist(final BjornaNightfallAlchemist card) {
super(card);
}
@Override
- public LucasTheSharpshooter copy() {
- return new LucasTheSharpshooter(this);
+ public BjornaNightfallAlchemist copy() {
+ return new BjornaNightfallAlchemist(this);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BlackMarketTycoon.java b/Mage.Sets/src/mage/cards/b/BlackMarketTycoon.java
new file mode 100644
index 00000000000..a73c6a835dc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BlackMarketTycoon.java
@@ -0,0 +1,60 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DamageControllerEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.permanent.token.TreasureToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BlackMarketTycoon extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.TREASURE);
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter, 2);
+ private static final Hint hint = new ValueHint(
+ "Treasures you control", new PermanentsOnBattlefieldCount(filter)
+ );
+
+ public BlackMarketTycoon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}");
+
+ this.subtype.add(SubType.CAT);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // At the beginning of your upkeep, Black Market Tycoon deals 2 damage to you for each Treasure you control.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new DamageControllerEffect(xValue), TargetController.YOU, false
+ ).addHint(hint));
+
+ // {T}: Create a Treasure token.
+ this.addAbility(new SimpleActivatedAbility(new CreateTokenEffect(new TreasureToken()), new TapSourceCost()));
+ }
+
+ private BlackMarketTycoon(final BlackMarketTycoon card) {
+ super(card);
+ }
+
+ @Override
+ public BlackMarketTycoon copy() {
+ return new BlackMarketTycoon(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BlackWard.java b/Mage.Sets/src/mage/cards/b/BlackWard.java
index 1b124f23192..73bd956aa21 100644
--- a/Mage.Sets/src/mage/cards/b/BlackWard.java
+++ b/Mage.Sets/src/mage/cards/b/BlackWard.java
@@ -1,36 +1,29 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.FilterCard;
-import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LoneFox
*/
public final class BlackWard extends CardImpl {
- private static final FilterCard filter = new FilterCard("black");
-
- static {
- filter.add(new ColorPredicate(ObjectColor.BLACK));
- }
-
public BlackWard(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
this.subtype.add(SubType.AURA);
// Enchant creature
@@ -38,12 +31,11 @@ public final class BlackWard extends CardImpl {
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Protect));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
+
// Enchanted creature has protection from black. This effect doesn't remove Black Ward.
- ProtectionAbility gainedAbility = new ProtectionAbility(filter);
- gainedAbility.setAuraIdNotToBeRemoved(this.getId());
- Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA);
- effect.setText("Enchanted creature has protection from black. This effect doesn't remove {this}.");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect(
+ ProtectionAbility.from(ObjectColor.BLACK), AttachmentType.AURA
+ ).setDoesntRemoveItself(true)));
}
private BlackWard(final BlackWard card) {
diff --git a/Mage.Sets/src/mage/cards/b/BladeOfTheOni.java b/Mage.Sets/src/mage/cards/b/BladeOfTheOni.java
new file mode 100644
index 00000000000..ed6a5b035e9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BladeOfTheOni.java
@@ -0,0 +1,114 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.keyword.MenaceAbility;
+import mage.abilities.keyword.ReconfigureAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BladeOfTheOni extends CardImpl {
+
+ public BladeOfTheOni(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{B}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+ this.subtype.add(SubType.DEMON);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Menace
+ this.addAbility(new MenaceAbility(false));
+
+ // Equipped creature has base power and toughness 5/5, has menace, and is a black Demon in addition to its other colors and types.
+ this.addAbility(new SimpleStaticAbility(new BladeOfTheOniEffect()));
+
+ // Reconfigure {2}{B}{B}
+ this.addAbility(new ReconfigureAbility("{2}{B}{B}"));
+ }
+
+ private BladeOfTheOni(final BladeOfTheOni card) {
+ super(card);
+ }
+
+ @Override
+ public BladeOfTheOni copy() {
+ return new BladeOfTheOni(this);
+ }
+}
+
+class BladeOfTheOniEffect extends ContinuousEffectImpl {
+
+ BladeOfTheOniEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Benefit);
+ staticText = "equipped creature has base power and toughness 5/5, " +
+ "has menace, and is a black Demon in addition to its other colors and types";
+ }
+
+ private BladeOfTheOniEffect(final BladeOfTheOniEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BladeOfTheOniEffect copy() {
+ return new BladeOfTheOniEffect(this);
+ }
+
+ @Override
+ public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
+ Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
+ if (sourcePermanent == null) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(sourcePermanent.getAttachedTo());
+ if (permanent == null) {
+ return false;
+ }
+ switch (layer) {
+ case AbilityAddingRemovingEffects_6:
+ permanent.addAbility(new MenaceAbility(false), source.getSourceId(), game);
+ return true;
+ case ColorChangingEffects_5:
+ permanent.getColor(game).setBlack(true);
+ return true;
+ case TypeChangingEffects_4:
+ permanent.addSubType(game, SubType.DEMON);
+ return true;
+ case PTChangingEffects_7:
+ if (sublayer != SubLayer.SetPT_7b) {
+ return false;
+ }
+ permanent.getPower().setValue(5);
+ permanent.getToughness().setValue(5);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return false;
+ }
+
+ @Override
+ public boolean hasLayer(Layer layer) {
+ switch (layer) {
+ case TypeChangingEffects_4:
+ case ColorChangingEffects_5:
+ case AbilityAddingRemovingEffects_6:
+ case PTChangingEffects_7:
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BladeSliver.java b/Mage.Sets/src/mage/cards/b/BladeSliver.java
index 7fc07a17b9b..644d8fe77e9 100644
--- a/Mage.Sets/src/mage/cards/b/BladeSliver.java
+++ b/Mage.Sets/src/mage/cards/b/BladeSliver.java
@@ -28,7 +28,7 @@ public final class BladeSliver extends CardImpl {
// All Sliver creatures get +1/+0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
- new BoostAllEffect(1, 0, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, false)));
+ new BoostAllEffect(1, 0, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS, false)));
}
private BladeSliver(final BladeSliver card) {
diff --git a/Mage.Sets/src/mage/cards/b/BladeSplicer.java b/Mage.Sets/src/mage/cards/b/BladeSplicer.java
index 3fd48e080cf..a6290b2378e 100644
--- a/Mage.Sets/src/mage/cards/b/BladeSplicer.java
+++ b/Mage.Sets/src/mage/cards/b/BladeSplicer.java
@@ -21,10 +21,9 @@ import java.util.UUID;
* @author Loki
*/
public final class BladeSplicer extends CardImpl {
- private static final FilterPermanent filter = new FilterPermanent("Golem creatures");
+ private static final FilterPermanent filter = new FilterPermanent("Golems");
static {
- filter.add(CardType.CREATURE.getPredicate());
filter.add(SubType.GOLEM.getPredicate());
}
diff --git a/Mage.Sets/src/mage/cards/b/BladeTribeBerserkers.java b/Mage.Sets/src/mage/cards/b/BladeTribeBerserkers.java
index d1b971152b3..2c9f4e5ad4c 100644
--- a/Mage.Sets/src/mage/cards/b/BladeTribeBerserkers.java
+++ b/Mage.Sets/src/mage/cards/b/BladeTribeBerserkers.java
@@ -23,7 +23,7 @@ import java.util.UUID;
*/
public final class BladeTribeBerserkers extends CardImpl {
- private static final String effectText = "Metalcraft — When Blade-Tribe Berserkers enters the battlefield, if you control three or more artifacts, Blade-Tribe Berserkers gets +3/+3 and gains haste until end of turn.";
+ private static final String effectText = "When {this} enters the battlefield, if you control three or more artifacts, {this} gets +3/+3 and gains haste until end of turn.";
public BladeTribeBerserkers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
diff --git a/Mage.Sets/src/mage/cards/b/BladebackSliver.java b/Mage.Sets/src/mage/cards/b/BladebackSliver.java
index de3440775f2..109101d3c45 100644
--- a/Mage.Sets/src/mage/cards/b/BladebackSliver.java
+++ b/Mage.Sets/src/mage/cards/b/BladebackSliver.java
@@ -39,7 +39,7 @@ public final class BladebackSliver extends CardImpl {
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new GainAbilityControlledEffect(
ability, Duration.WhileOnBattlefield,
- StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS
+ StaticFilters.FILTER_PERMANENT_ALL_SLIVERS
), HellbentCondition.instance, "Hellbent — " +
"As long as you have no cards in hand, Sliver creatures you control have " +
"\"{T}: This creature deals 1 damage to target player or planeswalker.\""
diff --git a/Mage.Sets/src/mage/cards/b/BlademaneBaku.java b/Mage.Sets/src/mage/cards/b/BlademaneBaku.java
index 144a4440645..fd9b07f0a49 100644
--- a/Mage.Sets/src/mage/cards/b/BlademaneBaku.java
+++ b/Mage.Sets/src/mage/cards/b/BlademaneBaku.java
@@ -1,30 +1,34 @@
-
-
package mage.cards.b;
- import java.util.UUID;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
-import mage.abilities.costs.Cost;
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.MultipliedValue;
+import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
- import mage.cards.CardSetInfo;
- import mage.constants.*;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
-import mage.game.Game;
/**
* @author LevelX2
*/
public final class BlademaneBaku extends CardImpl {
+ private static final DynamicValue xValue = new MultipliedValue(RemovedCountersForCostValue.instance, 2);
+
public BlademaneBaku(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}");
this.subtype.add(SubType.SPIRIT);
@@ -32,12 +36,14 @@ public final class BlademaneBaku extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
- // Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Skullmane Baku.
+ // Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Blademane Baku.
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.FILTER_SPIRIT_OR_ARCANE_CARD, true));
// {1}, Remove X ki counters from Blademane Baku: For each counter removed, Blademane Baku gets +2/+0 until end of turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BlademaneBakuBoostEffect(), new GenericManaCost(1));
- ability.addCost(new RemoveVariableCountersSourceCost(CounterType.KI.createInstance(1)));
+ Effect effect = new BoostSourceEffect(xValue, StaticValue.get(0), Duration.EndOfTurn);
+ effect.setText("for each counter removed, {this} gets +2/+0 until end of turn");
+ Ability ability = new SimpleActivatedAbility(effect, new GenericManaCost(1));
+ ability.addCost(new RemoveVariableCountersSourceCost(CounterType.KI.createInstance()));
this.addAbility(ability);
}
@@ -49,37 +55,4 @@ public final class BlademaneBaku extends CardImpl {
public BlademaneBaku copy() {
return new BlademaneBaku(this);
}
-
- static class BlademaneBakuBoostEffect extends OneShotEffect {
-
- public BlademaneBakuBoostEffect() {
- super(Outcome.UnboostCreature);
- staticText = "For each counter removed, {this} gets +2/+0 until end of turn";
- }
-
- public BlademaneBakuBoostEffect(BlademaneBakuBoostEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- int numberToBoost = 0;
- for (Cost cost : source.getCosts()) {
- if (cost instanceof RemoveVariableCountersSourceCost) {
- numberToBoost = ((RemoveVariableCountersSourceCost)cost).getAmount() * 2;
- }
- }
- if (numberToBoost >= 0) {
- game.addEffect(new BoostSourceEffect(numberToBoost, 0, Duration.EndOfTurn), source);
- return true;
- }
- return false;
- }
-
- @Override
- public BlademaneBakuBoostEffect copy() {
- return new BlademaneBakuBoostEffect(this);
- }
-
- }
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/b/BlankaFerociousFriend.java b/Mage.Sets/src/mage/cards/b/BlankaFerociousFriend.java
new file mode 100644
index 00000000000..090f31fe734
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BlankaFerociousFriend.java
@@ -0,0 +1,76 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BecomesTargetTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.DamagePlayersEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.watchers.common.CastSpellLastTurnWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BlankaFerociousFriend extends CardImpl {
+
+ public BlankaFerociousFriend(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.BEAST);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Rolling Attack—Blanka, Ferocious Friend has trample as long as you've cast three or more spells this turn.
+ this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new GainAbilitySourceEffect(TrampleAbility.getInstance()), BlankaFerociousFriendCondition.instance,
+ "{this} has trample as long as you've cast three or more spells this turn"
+ )).withFlavorWord("Rolling Attack"));
+
+ // Electric Thunder—Whenever Blanka becomes the target of a spell, he gets +2/+2 until end of turn and deals 2 damage to each opponent.
+ Ability ability = new BecomesTargetTriggeredAbility(new BoostSourceEffect(
+ 2, 2, Duration.EndOfTurn
+ ).setText("he gets +2/+2 until end of turn"), StaticFilters.FILTER_SPELL_A).setTriggerPhrase("Whenever {this} becomes the target of a spell, ");
+ ability.addEffect(new DamagePlayersEffect(2, TargetController.OPPONENT)
+ .setText("and deals 2 damage to each opponent"));
+ this.addAbility(ability.withFlavorWord("Electric Thunder"));
+ }
+
+ private BlankaFerociousFriend(final BlankaFerociousFriend card) {
+ super(card);
+ }
+
+ @Override
+ public BlankaFerociousFriend copy() {
+ return new BlankaFerociousFriend(this);
+ }
+}
+
+enum BlankaFerociousFriendCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return game
+ .getState()
+ .getWatcher(CastSpellLastTurnWatcher.class)
+ .getAmountOfSpellsPlayerCastOnCurrentTurn(source.getControllerId()) >= 3;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BlasphemousAct.java b/Mage.Sets/src/mage/cards/b/BlasphemousAct.java
index c67a14b6763..f17a9d0f425 100644
--- a/Mage.Sets/src/mage/cards/b/BlasphemousAct.java
+++ b/Mage.Sets/src/mage/cards/b/BlasphemousAct.java
@@ -57,12 +57,12 @@ class BlasphemousCostReductionEffect extends CostModificationEffectImpl {
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player player = game.getPlayer(source.getControllerId());
- if (player != null) {
- int reductionAmount = game.getBattlefield().count(StaticFilters.FILTER_PERMANENT_CREATURE, source.getSourceId(), source.getControllerId(), game);
- CardUtil.reduceCost(abilityToModify, reductionAmount);
- return true;
- }
- return false;
+ if (player == null) { return false; }
+
+ int reductionAmount = game.getBattlefield().count(StaticFilters.FILTER_PERMANENT_CREATURE, source.getSourceId(), source, game);
+ CardUtil.reduceCost(abilityToModify, reductionAmount);
+
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BlastFromThePast.java b/Mage.Sets/src/mage/cards/b/BlastFromThePast.java
index 97bdd6bc46a..9b993cc074f 100644
--- a/Mage.Sets/src/mage/cards/b/BlastFromThePast.java
+++ b/Mage.Sets/src/mage/cards/b/BlastFromThePast.java
@@ -15,7 +15,6 @@ import mage.abilities.keyword.MadnessAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.TimingRule;
import mage.game.permanent.token.GoblinToken;
import mage.target.common.TargetAnyTarget;
@@ -29,7 +28,7 @@ public final class BlastFromThePast extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}");
// Madness {R}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{R}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{R}")));
// Cycling {1}{R}
this.addAbility(new CyclingAbility(new ManaCostsImpl("{1}{R}")));
// Kicker {2}{R}
diff --git a/Mage.Sets/src/mage/cards/b/BlastOfGenius.java b/Mage.Sets/src/mage/cards/b/BlastOfGenius.java
index 3bdc32a0641..4aea551192e 100644
--- a/Mage.Sets/src/mage/cards/b/BlastOfGenius.java
+++ b/Mage.Sets/src/mage/cards/b/BlastOfGenius.java
@@ -60,8 +60,8 @@ class BlastOfGeniusEffect extends OneShotEffect {
if (player != null) {
player.drawCards(3, source, game);
TargetDiscard target = new TargetDiscard(player.getId());
- if (target.canChoose(source.getSourceId(), player.getId(), game)) {
- player.choose(Outcome.Discard, target, source.getSourceId(), game);
+ if (target.canChoose(player.getId(), source, game)) {
+ player.choose(Outcome.Discard, target, source, game);
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
player.discard(card, false, source, game);
diff --git a/Mage.Sets/src/mage/cards/b/BlatantThievery.java b/Mage.Sets/src/mage/cards/b/BlatantThievery.java
index 9a754b68068..c619988e8f5 100644
--- a/Mage.Sets/src/mage/cards/b/BlatantThievery.java
+++ b/Mage.Sets/src/mage/cards/b/BlatantThievery.java
@@ -52,7 +52,7 @@ enum BlatantThieveryAdjuster implements TargetAdjuster {
Player opponent = game.getPlayer(opponentId);
if (opponent == null || game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_PERMANENT,
- ability.getSourceId(), opponentId, game
+ opponentId, ability, game
) < 1) {
continue;
}
diff --git a/Mage.Sets/src/mage/cards/b/BlazingEffigy.java b/Mage.Sets/src/mage/cards/b/BlazingEffigy.java
index 68c7af94966..c64d4e9826f 100644
--- a/Mage.Sets/src/mage/cards/b/BlazingEffigy.java
+++ b/Mage.Sets/src/mage/cards/b/BlazingEffigy.java
@@ -89,15 +89,16 @@ class BlazingEffigyWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.DAMAGED_PERMANENT) {
- if (!event.getSourceId().equals(event.getTargetId())) {
- MageObjectReference damageSourceRef = new MageObjectReference(event.getSourceId(), game);
- MageObjectReference damageTargetRef = new MageObjectReference(event.getTargetId(), game);
- if (game.getPermanentOrLKIBattlefield(event.getSourceId()) != null && game.getPermanentOrLKIBattlefield(event.getSourceId()).getName().equals("Blazing Effigy")) {
- damagedObjects.putIfAbsent(damageTargetRef, 0);
- damagedObjects.compute(damageTargetRef, (k, damage) -> damage + event.getAmount());
- }
- }
+ if (event.getType() != GameEvent.EventType.DAMAGED_PERMANENT) { return; }
+
+ if (event.getSourceId().equals(event.getTargetId())) { return; }
+
+ // TODO: Should damageSourceRef be used for anything?
+ MageObjectReference damageSourceRef = new MageObjectReference(event.getSourceId(), game);
+ MageObjectReference damageTargetRef = new MageObjectReference(event.getTargetId(), game);
+ if (game.getPermanentOrLKIBattlefield(event.getSourceId()) != null && game.getPermanentOrLKIBattlefield(event.getSourceId()).getName().equals("Blazing Effigy")) {
+ damagedObjects.putIfAbsent(damageTargetRef, 0);
+ damagedObjects.compute(damageTargetRef, (k, damage) -> damage + event.getAmount());
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BlazingHope.java b/Mage.Sets/src/mage/cards/b/BlazingHope.java
index 319e1ed3437..f85d5a86ef6 100644
--- a/Mage.Sets/src/mage/cards/b/BlazingHope.java
+++ b/Mage.Sets/src/mage/cards/b/BlazingHope.java
@@ -54,29 +54,29 @@ class BlazingHopeTarget extends TargetCreaturePermanent {
if (permanent != null) {
if (!isNotTarget()) {
if (!permanent.canBeTargetedBy(game.getObject(source.getId()), controllerId, game)
- || !permanent.canBeTargetedBy(game.getObject(source.getSourceId()), controllerId, game)) {
+ || !permanent.canBeTargetedBy(game.getObject(source), controllerId, game)) {
return false;
}
}
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && permanent.getPower().getValue() >= controller.getLife()) {
- return filter.match(permanent, source.getSourceId(), controllerId, game);
+ return filter.match(permanent, controllerId, source, game);
}
}
return false;
}
@Override
- public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
+ public boolean canChoose(UUID sourceControllerId, Ability source, Game game) {
int remainingTargets = this.minNumberOfTargets - targets.size();
if (remainingTargets <= 0) {
return true;
}
int count = 0;
Player controller = game.getPlayer(sourceControllerId);
- MageObject targetSource = game.getObject(sourceId);
+ MageObject targetSource = game.getObject(source);
if(targetSource != null) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, source, game)) {
if (!targets.containsKey(permanent.getId())) {
if (notTarget || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
if (controller != null && permanent.getPower().getValue() >= controller.getLife()) {
diff --git a/Mage.Sets/src/mage/cards/b/BlazingRootwalla.java b/Mage.Sets/src/mage/cards/b/BlazingRootwalla.java
index f3e450b8d7a..a8b711d1449 100644
--- a/Mage.Sets/src/mage/cards/b/BlazingRootwalla.java
+++ b/Mage.Sets/src/mage/cards/b/BlazingRootwalla.java
@@ -32,7 +32,7 @@ public final class BlazingRootwalla extends CardImpl {
new BoostSourceEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}")));
// Madness{0}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{0}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{0}")));
}
private BlazingRootwalla(final BlazingRootwalla card) {
diff --git a/Mage.Sets/src/mage/cards/b/BlazingShoal.java b/Mage.Sets/src/mage/cards/b/BlazingShoal.java
index c460a3d7228..ad753cc0da2 100644
--- a/Mage.Sets/src/mage/cards/b/BlazingShoal.java
+++ b/Mage.Sets/src/mage/cards/b/BlazingShoal.java
@@ -12,8 +12,6 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.common.FilterOwnedCard;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreaturePermanent;
@@ -25,19 +23,27 @@ import java.util.UUID;
*/
public final class BlazingShoal extends CardImpl {
+ private static final FilterOwnedCard filter
+ = new FilterOwnedCard("a red card with mana value X from your hand");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.RED));
+ }
+
public BlazingShoal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}");
this.subtype.add(SubType.ARCANE);
-
// You may exile a red card with converted mana cost X from your hand rather than pay Blazing Shoal's mana cost.
- FilterOwnedCard filter = new FilterOwnedCard("a red card with mana value X from your hand");
- filter.add(new ColorPredicate(ObjectColor.RED));
- filter.add(Predicates.not(new CardIdPredicate(this.getId()))); // the exile cost can never be paid with the card itself
- this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter), true)));
+ this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(
+ new TargetCardInHand(filter), true
+ )));
// Target creature gets +X/+0 until end of turn.
- this.getSpellAbility().addEffect(new BoostTargetEffect(ExileFromHandCostCardConvertedMana.instance, StaticValue.get(0), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(
+ ExileFromHandCostCardConvertedMana.instance,
+ StaticValue.get(0), Duration.EndOfTurn
+ ));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/b/BleakCovenVampires.java b/Mage.Sets/src/mage/cards/b/BleakCovenVampires.java
index 87ccf22aff4..54b1e7a1ab9 100644
--- a/Mage.Sets/src/mage/cards/b/BleakCovenVampires.java
+++ b/Mage.Sets/src/mage/cards/b/BleakCovenVampires.java
@@ -23,7 +23,7 @@ import java.util.UUID;
*/
public final class BleakCovenVampires extends CardImpl {
- private static final String effectText = "Metalcraft — When Bleak Coven Vampires enters the battlefield, if you control three or more artifacts, target player loses 4 life and you gain 4 life.";
+ private static final String effectText = "When {this} enters the battlefield, if you control three or more artifacts, target player loses 4 life and you gain 4 life.";
public BleakCovenVampires(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
diff --git a/Mage.Sets/src/mage/cards/b/BlessedAlliance.java b/Mage.Sets/src/mage/cards/b/BlessedAlliance.java
index 23af303722e..1edb08eed24 100644
--- a/Mage.Sets/src/mage/cards/b/BlessedAlliance.java
+++ b/Mage.Sets/src/mage/cards/b/BlessedAlliance.java
@@ -49,16 +49,14 @@ public final class BlessedAlliance extends CardImpl {
this.getSpellAbility().addTarget(new TargetPlayer(1, 1, false, filterGainLife).withChooseHint("player gains 4 life"));
// Untap up to two target creatures.
- Mode mode = new Mode();
effect = new UntapTargetEffect();
effect.setText("Untap up to two target creatures");
- mode.addEffect(effect);
+ Mode mode = new Mode(effect);
mode.addTarget(new TargetCreaturePermanent(0, 2, filterCreature, false).withChooseHint("untap"));
this.getSpellAbility().addMode(mode);
// Target opponent sacrifices an attacking creature.
- mode = new Mode();
- mode.addEffect(new SacrificeEffect(new FilterAttackingCreature(), 1, "Target opponent"));
+ mode = new Mode(new SacrificeEffect(new FilterAttackingCreature(), 1, "Target opponent"));
mode.addTarget(new TargetPlayer(1, 1, false, filterSacrifice).withChooseHint("sacrifices an attacking creature"));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/b/BlessedDefiance.java b/Mage.Sets/src/mage/cards/b/BlessedDefiance.java
index 1c234914355..f151510822b 100644
--- a/Mage.Sets/src/mage/cards/b/BlessedDefiance.java
+++ b/Mage.Sets/src/mage/cards/b/BlessedDefiance.java
@@ -28,7 +28,7 @@ import java.util.UUID;
public class BlessedDefiance extends CardImpl {
public BlessedDefiance(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "W");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
// Target creature you control gets +2/+0 and gains lifelink until end of turn. When that creature dies this turn, create a 1/1 white Spirit creature token with flying.
this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0)
diff --git a/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java b/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java
index 1deee6907f5..a90524a964c 100644
--- a/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java
+++ b/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java
@@ -91,7 +91,7 @@ class BlessingOfFrostEffect extends OneShotEffect {
}
game.getState().processAction(game);
player.drawCards(game.getBattlefield().count(
- filter, source.getSourceId(), source.getControllerId(), game
+ filter, source.getControllerId(), source, game
), source, game);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/b/BlexVexingPest.java b/Mage.Sets/src/mage/cards/b/BlexVexingPest.java
index 0c0a87da95c..c67811db949 100644
--- a/Mage.Sets/src/mage/cards/b/BlexVexingPest.java
+++ b/Mage.Sets/src/mage/cards/b/BlexVexingPest.java
@@ -6,21 +6,18 @@ import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.GainLifeEffect;
-import mage.abilities.effects.common.LookLibraryControllerEffect;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.Cards;
-import mage.cards.CardsImpl;
import mage.cards.ModalDoubleFacesCard;
import mage.constants.*;
import mage.cards.CardSetInfo;
-import mage.filter.FilterCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
/**
*
@@ -81,15 +78,11 @@ public final class BlexVexingPest extends ModalDoubleFacesCard {
}
}
-class SearchForBlexEffect extends LookLibraryControllerEffect {
+class SearchForBlexEffect extends LookLibraryAndPickControllerEffect {
- private static final FilterCard filter = new FilterCard("cards to put into your hand");
-
- public SearchForBlexEffect() {
- super(Outcome.DrawCard, StaticValue.get(5), false, Zone.GRAVEYARD, true);
- this.staticText = "Look at the top five cards of your library. "
- + "You may put any number of them into your hand and the rest into your graveyard. "
- + "You lose 3 life for each card you put into your hand this way";
+ SearchForBlexEffect() {
+ super(5, Integer.MAX_VALUE, PutCards.HAND, PutCards.GRAVEYARD);
+ this.optional = true;
}
private SearchForBlexEffect(final SearchForBlexEffect effect) {
@@ -102,21 +95,14 @@ class SearchForBlexEffect extends LookLibraryControllerEffect {
}
@Override
- protected void actionWithSelectedCards(Cards cards, Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
- if (player != null) {
- TargetCard target = new TargetCard(0, 5, Zone.LIBRARY, filter);
- if (player.choose(outcome, cards, target, game)) {
- Cards pickedCards = new CardsImpl(target.getTargets());
- cards.removeAll(pickedCards);
- player.moveCards(pickedCards, Zone.HAND, source, game);
- player.loseLife(pickedCards.size() * 3, game, source, false);
- }
- }
+ protected boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) {
+ super.actionWithPickedCards(game, source, player, pickedCards, otherCards);
+ player.loseLife(pickedCards.size() * 3, game, source, false);
+ return true;
}
@Override
public String getText(Mode mode) {
- return staticText;
+ return super.getText(mode).concat(". You lose 3 life for each card you put into your hand this way");
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BlightHerder.java b/Mage.Sets/src/mage/cards/b/BlightHerder.java
index 82c0a5afaac..a33c25b6563 100644
--- a/Mage.Sets/src/mage/cards/b/BlightHerder.java
+++ b/Mage.Sets/src/mage/cards/b/BlightHerder.java
@@ -72,7 +72,7 @@ class BlightHerderEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Target target = new TargetCardInExile(2, 2, filter, null);
- if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
+ if (target.canChoose(source.getControllerId(), source, game)) {
if (controller.chooseTarget(outcome, target, source, game)) {
Cards cardsToGraveyard = new CardsImpl(target.getTargets());
controller.moveCards(cardsToGraveyard, Zone.GRAVEYARD, source, game);
diff --git a/Mage.Sets/src/mage/cards/b/BlimComedicGenius.java b/Mage.Sets/src/mage/cards/b/BlimComedicGenius.java
index 5b1782303c2..0664c90748c 100644
--- a/Mage.Sets/src/mage/cards/b/BlimComedicGenius.java
+++ b/Mage.Sets/src/mage/cards/b/BlimComedicGenius.java
@@ -93,13 +93,13 @@ class BlimComedicGeniusEffect extends OneShotEffect {
if (player == null) {
continue;
}
- int count = game.getBattlefield().count(filter, source.getSourceId(), playerId, game);
+ int count = game.getBattlefield().count(filter, playerId, source, game);
if (count < 1) {
continue;
}
player.loseLife(count, game, source, true);
TargetDiscard target = new TargetDiscard(StaticFilters.FILTER_CARD, playerId);
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
cardsMap.put(playerId, new CardsImpl(target.getTargets()));
}
for (Map.Entry entry : cardsMap.entrySet()) {
diff --git a/Mage.Sets/src/mage/cards/b/BlindingBeam.java b/Mage.Sets/src/mage/cards/b/BlindingBeam.java
index d358aa68c2f..e208efa112e 100644
--- a/Mage.Sets/src/mage/cards/b/BlindingBeam.java
+++ b/Mage.Sets/src/mage/cards/b/BlindingBeam.java
@@ -41,8 +41,7 @@ public final class BlindingBeam extends CardImpl {
this.getSpellAbility().addEffect(new TapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(2,2));
// or creatures don't untap during target player's next untap step.
- Mode mode = new Mode();
- mode.addEffect(new BlindingBeamEffect());
+ Mode mode = new Mode(new BlindingBeamEffect());
mode.addTarget(new TargetPlayer());
this.getSpellAbility().getModes().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/b/BlindingSouleater.java b/Mage.Sets/src/mage/cards/b/BlindingSouleater.java
index b2e51005868..e9fd4a7a2e1 100644
--- a/Mage.Sets/src/mage/cards/b/BlindingSouleater.java
+++ b/Mage.Sets/src/mage/cards/b/BlindingSouleater.java
@@ -1,28 +1,25 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.costs.mana.PhyrexianManaCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.TapTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class BlindingSouleater extends CardImpl {
public BlindingSouleater(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.CLERIC);
@@ -30,9 +27,7 @@ public final class BlindingSouleater extends CardImpl {
this.toughness = new MageInt(3);
// {W/P},{T}: Tap target creature. ( can be paid with either or 2 life.)
- SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new TapTargetEffect(),
- new PhyrexianManaCost(ColoredManaSymbol.W));
+ SimpleActivatedAbility ability = new SimpleActivatedAbility(new TapTargetEffect(), new ManaCostsImpl<>("{W/P}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BlindingSpray.java b/Mage.Sets/src/mage/cards/b/BlindingSpray.java
index 0a51960e0de..29001f55cde 100644
--- a/Mage.Sets/src/mage/cards/b/BlindingSpray.java
+++ b/Mage.Sets/src/mage/cards/b/BlindingSpray.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -8,8 +7,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.TargetController;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.StaticFilters;
/**
*
@@ -17,18 +15,11 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class BlindingSpray extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public BlindingSpray(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{U}");
-
// Creatures your opponents control get -4/-0 until end of turn.
- this.getSpellAbility().addEffect(new BoostAllEffect(-4, 0, Duration.EndOfTurn, filter, false));
+ this.getSpellAbility().addEffect(new BoostAllEffect(-4, 0, Duration.EndOfTurn, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES, false));
// Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
diff --git a/Mage.Sets/src/mage/cards/b/BlinkmothInfusion.java b/Mage.Sets/src/mage/cards/b/BlinkmothInfusion.java
index a02615bfd77..9bc1c7020ee 100644
--- a/Mage.Sets/src/mage/cards/b/BlinkmothInfusion.java
+++ b/Mage.Sets/src/mage/cards/b/BlinkmothInfusion.java
@@ -23,9 +23,9 @@ public final class BlinkmothInfusion extends CardImpl {
public BlinkmothInfusion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{12}{U}{U}");
-
// Affinity for artifacts
this.addAbility(new AffinityForArtifactsAbility());
+
// Untap all artifacts.
this.getSpellAbility().addEffect(new UntapAllArtifactsEffect());
}
@@ -54,13 +54,12 @@ class UntapAllArtifactsEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
- if (player != null) {
- for (Permanent artifact: game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), game)) {
- artifact.untap(game);
- }
- return true;
+ if (player == null) { return false; }
+
+ for (Permanent artifact: game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), game)) {
+ artifact.untap(game);
}
- return false;
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java b/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java
index 23a6f1b7157..cf3cf34b851 100644
--- a/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java
+++ b/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java
@@ -66,7 +66,7 @@ class BlinkmothUrnEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (player != null && sourcePermanent != null && !sourcePermanent.isTapped()) {
player.getManaPool().addMana(Mana.ColorlessMana(
- game.getState().getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game).
+ game.getState().getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game).
size()), game, source, false);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/b/BlisteringFirecat.java b/Mage.Sets/src/mage/cards/b/BlisteringFirecat.java
index ec1c357a85b..a13d2111184 100644
--- a/Mage.Sets/src/mage/cards/b/BlisteringFirecat.java
+++ b/Mage.Sets/src/mage/cards/b/BlisteringFirecat.java
@@ -35,7 +35,7 @@ public final class BlisteringFirecat extends CardImpl {
// At the beginning of the end step, sacrifice Blistering Firecat.
this.addAbility(new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()));
// Morph {R}{R}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{R}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{R}{R}")));
}
private BlisteringFirecat(final BlisteringFirecat card) {
diff --git a/Mage.Sets/src/mage/cards/b/BlisterstickShaman.java b/Mage.Sets/src/mage/cards/b/BlisterstickShaman.java
index c21730c32ca..0f03c5173b0 100644
--- a/Mage.Sets/src/mage/cards/b/BlisterstickShaman.java
+++ b/Mage.Sets/src/mage/cards/b/BlisterstickShaman.java
@@ -25,7 +25,7 @@ public final class BlisterstickShaman extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(1);
- Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1));
+ Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1, "it"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BlitzHellion.java b/Mage.Sets/src/mage/cards/b/BlitzHellion.java
index d1b0ded175b..89d548493d1 100644
--- a/Mage.Sets/src/mage/cards/b/BlitzHellion.java
+++ b/Mage.Sets/src/mage/cards/b/BlitzHellion.java
@@ -1,10 +1,7 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ShuffleIntoLibrarySourceEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.TrampleAbility;
@@ -13,16 +10,16 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
-import mage.constants.Zone;
+
+import java.util.UUID;
/**
- *
* @author jeffwadsworth
*/
public final class BlitzHellion extends CardImpl {
public BlitzHellion(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}");
this.subtype.add(SubType.HELLION);
this.power = new MageInt(7);
this.toughness = new MageInt(7);
@@ -34,9 +31,11 @@ public final class BlitzHellion extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// At the beginning of the end step, Blitz Hellion's owner shuffles it into their library.
- Effect effect = new ShuffleIntoLibrarySourceEffect();
- effect.setText("{this}'s owner shuffles it into their library.");
- this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.ANY, null, false));
+ this.addAbility(new BeginningOfEndStepTriggeredAbility(
+ new ShuffleIntoLibrarySourceEffect()
+ .setText("{this}'s owner shuffles it into their library."),
+ TargetController.NEXT, false
+ ));
}
private BlitzHellion(final BlitzHellion card) {
diff --git a/Mage.Sets/src/mage/cards/b/BlizzardBrawl.java b/Mage.Sets/src/mage/cards/b/BlizzardBrawl.java
index 4d82979e5e6..44e37d37f76 100644
--- a/Mage.Sets/src/mage/cards/b/BlizzardBrawl.java
+++ b/Mage.Sets/src/mage/cards/b/BlizzardBrawl.java
@@ -61,7 +61,7 @@ class BlizzardBrawlEffect extends OneShotEffect {
staticText = "Choose target creature you control and target creature you don't control. " +
"If you control three or more snow permanents, the creature you control gets +1/+0 " +
"and gains indestructible until end of turn. " +
- "Then those creatures fight each other." +
+ "Then those creatures fight each other. " +
"(Each deals damage equal to its power to the other.)";
}
@@ -81,7 +81,7 @@ class BlizzardBrawlEffect extends OneShotEffect {
if (creature1 == null) {
return false;
}
- if (game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) >= 3) {
+ if (game.getBattlefield().count(filter, source.getControllerId(), source, game) >= 3) {
game.addEffect(new BoostTargetEffect(
1, 0, Duration.EndOfTurn
).setTargetPointer(new FixedTarget(creature1.getId(), game)), source);
diff --git a/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java b/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java
index 71f9d0dc46d..6067663d03b 100644
--- a/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java
+++ b/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java
@@ -40,8 +40,7 @@ public final class BlizzardSpecter extends CardImpl {
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandEffect(), false, true);
// or that player discards a card.
- Mode mode = new Mode();
- mode.addEffect(new DiscardTargetEffect(1, false));
+ Mode mode = new Mode(new DiscardTargetEffect(1, false));
ability.addMode(mode);
this.addAbility(ability);
@@ -80,7 +79,7 @@ class ReturnToHandEffect extends OneShotEffect {
return false;
}
Target target = new TargetControlledPermanent(1, 1, new FilterControlledPermanent(), true);
- if (target.canChoose(source.getSourceId(), targetPlayer.getId(), game)) {
+ if (target.canChoose(targetPlayer.getId(), source, game)) {
targetPlayer.chooseTarget(Outcome.ReturnToHand, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BlizzardStrix.java b/Mage.Sets/src/mage/cards/b/BlizzardStrix.java
index b45eaca2a0c..01a422fdf79 100644
--- a/Mage.Sets/src/mage/cards/b/BlizzardStrix.java
+++ b/Mage.Sets/src/mage/cards/b/BlizzardStrix.java
@@ -7,7 +7,6 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.keyword.FlashAbility;
@@ -90,18 +89,17 @@ class BlizzardStrixEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
- Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (controller != null && permanent != null && sourcePermanent != null) {
- if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source, game, Zone.BATTLEFIELD, true)) {
- //create delayed triggered ability
- Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
- effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
- effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
- game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
- return true;
- }
+ if (controller == null || permanent == null) {
+ return false;
}
- return false;
+ controller.moveCards(permanent, Zone.EXILED, source, game);
+ //create delayed triggered ability
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false)
+ .setText("Return that card to the battlefield under its owner's control at the beginning of the next end step")
+ .setTargetPointer(new FixedTarget(source.getFirstTarget(), game))
+ ), source);
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BloodBaronOfVizkopa.java b/Mage.Sets/src/mage/cards/b/BloodBaronOfVizkopa.java
index 68b1873d0e2..0137ca84c6b 100644
--- a/Mage.Sets/src/mage/cards/b/BloodBaronOfVizkopa.java
+++ b/Mage.Sets/src/mage/cards/b/BloodBaronOfVizkopa.java
@@ -32,7 +32,6 @@ public final class BloodBaronOfVizkopa extends CardImpl {
// As long as you have 30 or more life and an opponent has 10 or less life, Blood Baron of Vizkopa gets +6/+6 and has flying.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BloodBaronOfVizkopaEffect()));
-
}
private BloodBaronOfVizkopa(final BloodBaronOfVizkopa card) {
@@ -53,7 +52,7 @@ class BloodBaronOfVizkopaEffect extends ContinuousEffectImpl {
staticText = "As long as you have 30 or more life and an opponent has 10 or less life, {this} gets +6/+6 and has flying";
}
- public BloodBaronOfVizkopaEffect(final BloodBaronOfVizkopaEffect effect) {
+ private BloodBaronOfVizkopaEffect(final BloodBaronOfVizkopaEffect effect) {
super(effect);
}
@@ -64,41 +63,45 @@ class BloodBaronOfVizkopaEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
- if (conditionState(source, game)) {
- Permanent creature = game.getPermanent(source.getSourceId());
- if (creature != null) {
- switch (layer) {
- case PTChangingEffects_7:
- if (sublayer == SubLayer.ModifyPT_7c) {
- creature.addPower(6);
- creature.addToughness(6);
- }
- break;
- case AbilityAddingRemovingEffects_6:
- if (sublayer == SubLayer.NA) {
- creature.addAbility(FlyingAbility.getInstance(), source.getSourceId(), game);
- }
- break;
- default:
+ if (!conditionState(source, game)) { return false; }
+
+ Permanent creature = game.getPermanent(source.getSourceId());
+ if (creature == null) { return false; }
+
+ switch (layer) {
+ case PTChangingEffects_7:
+ if (sublayer == SubLayer.ModifyPT_7c) {
+ creature.addPower(6);
+ creature.addToughness(6);
}
- return true;
- }
+ break;
+ case AbilityAddingRemovingEffects_6:
+ if (sublayer == SubLayer.NA) {
+ creature.addAbility(FlyingAbility.getInstance(), source.getSourceId(), game);
+ }
+ break;
+ default:
+ return false;
}
- return false;
+
+ return true;
}
- protected boolean conditionState(Ability source, Game game) {
+ private boolean conditionState(Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null && controller.getLife() >= 30) {
- for (UUID opponentId : game.getState().getPlayersInRange(controller.getId(), game)) {
- if (controller.hasOpponent(opponentId, game)) {
- Player opponent = game.getPlayer(opponentId);
- if (opponent != null && opponent.getLife() < 11) {
- return true;
- }
- }
- }
+ if (controller == null) { return false; }
+
+ if (controller.getLife() < 30) { return false; }
+
+ for (UUID opponentId : game.getState().getPlayersInRange(controller.getId(), game)) {
+ if (!controller.hasOpponent(opponentId, game)) { return false; }
+
+ Player opponent = game.getPlayer(opponentId);
+ if (opponent == null) { return false; }
+
+ return opponent.getLife() < 11;
}
+
return false;
}
@@ -109,8 +112,6 @@ class BloodBaronOfVizkopaEffect extends ContinuousEffectImpl {
@Override
public boolean hasLayer(Layer layer) {
- return (layer == Layer.AbilityAddingRemovingEffects_6 || layer == layer.PTChangingEffects_7);
-
+ return (layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.PTChangingEffects_7);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodClock.java b/Mage.Sets/src/mage/cards/b/BloodClock.java
index 90739872eff..f17f9752d49 100644
--- a/Mage.Sets/src/mage/cards/b/BloodClock.java
+++ b/Mage.Sets/src/mage/cards/b/BloodClock.java
@@ -73,7 +73,7 @@ class BloodClockEffect extends OneShotEffect {
}
Target target = new TargetControlledPermanent();
target.setNotTarget(true);
- if (!target.canChoose(source.getSourceId(), player.getId(), game)
+ if (!target.canChoose(player.getId(), source, game)
|| !player.chooseTarget(outcome, target, source, game)) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodCurdle.java b/Mage.Sets/src/mage/cards/b/BloodCurdle.java
index 9a75ba77a1e..df33509b6b5 100644
--- a/Mage.Sets/src/mage/cards/b/BloodCurdle.java
+++ b/Mage.Sets/src/mage/cards/b/BloodCurdle.java
@@ -66,7 +66,7 @@ class BloodCurdleEffect extends OneShotEffect {
}
Target target = new TargetControlledCreaturePermanent();
target.setNotTarget(true);
- if (!player.choose(outcome, target, source.getSourceId(), game)) {
+ if (!player.choose(outcome, target, source, game)) {
return false;
}
Permanent permanent = game.getPermanent(target.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/b/BloodLust.java b/Mage.Sets/src/mage/cards/b/BloodLust.java
index e0ae6a2e613..941c4dc4f72 100644
--- a/Mage.Sets/src/mage/cards/b/BloodLust.java
+++ b/Mage.Sets/src/mage/cards/b/BloodLust.java
@@ -68,7 +68,7 @@ class TargetMatchesFilterCondition implements Condition {
public boolean apply(Game game, Ability source) {
Permanent target = game.getBattlefield().getPermanent(source.getFirstTarget());
if (target != null) {
- if (filter.match(target, source.getSourceId(), source.getControllerId(), game)) {
+ if (filter.match(target, source.getControllerId(), source, game)) {
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodOath.java b/Mage.Sets/src/mage/cards/b/BloodOath.java
index 0893ebbd5dd..1a4756c3cf7 100644
--- a/Mage.Sets/src/mage/cards/b/BloodOath.java
+++ b/Mage.Sets/src/mage/cards/b/BloodOath.java
@@ -73,7 +73,7 @@ class BloodOathEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
Player player = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget());
if (player != null && opponent != null && sourceObject != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BloodPrice.java b/Mage.Sets/src/mage/cards/b/BloodPrice.java
index 68dde6c913b..93305849f4c 100644
--- a/Mage.Sets/src/mage/cards/b/BloodPrice.java
+++ b/Mage.Sets/src/mage/cards/b/BloodPrice.java
@@ -1,13 +1,11 @@
package mage.cards.b;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.filter.StaticFilters;
import java.util.UUID;
@@ -20,13 +18,7 @@ public final class BloodPrice extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Look at the top four cards of your library. Put two of them into your hand and the rest on the bottom of your library in any order. You lose 2 life.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(4), false, StaticValue.get(2),
- StaticFilters.FILTER_CARD, Zone.LIBRARY, false,
- false, false, Zone.HAND, false,
- false, true
- ).setText("Look at at the top four cards of your library." +
- "Put two of them into your hand and the rest on the bottom of your library in any order "));
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(4, 2, PutCards.HAND, PutCards.BOTTOM_ANY));
this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(2));
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodSun.java b/Mage.Sets/src/mage/cards/b/BloodSun.java
index 0a9e2dd853a..55bfd19f9da 100644
--- a/Mage.Sets/src/mage/cards/b/BloodSun.java
+++ b/Mage.Sets/src/mage/cards/b/BloodSun.java
@@ -69,7 +69,7 @@ class BloodSunEffect extends ContinuousEffectImpl {
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(StaticFilters.FILTER_LANDS, player.getId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(StaticFilters.FILTER_LANDS, player.getId(), source, game)) {
switch (layer) {
case AbilityAddingRemovingEffects_6:
List toRemove = new ArrayList<>();
diff --git a/Mage.Sets/src/mage/cards/b/BloodTribute.java b/Mage.Sets/src/mage/cards/b/BloodTribute.java
index d0dee861e18..2559e50297a 100644
--- a/Mage.Sets/src/mage/cards/b/BloodTribute.java
+++ b/Mage.Sets/src/mage/cards/b/BloodTribute.java
@@ -7,18 +7,16 @@ import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.KickerAbility;
-import mage.abilities.text.TextPartSubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.predicate.mageobject.TextPartSubtypePredicate;
+import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.players.Player;
-import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetOpponent;
import java.util.UUID;
@@ -28,15 +26,18 @@ import java.util.UUID;
*/
public final class BloodTribute extends CardImpl {
+ private static final FilterControlledPermanent filter
+ = new FilterControlledPermanent(SubType.VAMPIRE, "an untapped Vampire you control");
+
+ static {
+ filter.add(TappedPredicate.UNTAPPED);
+ }
+
public BloodTribute(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{B}");
// Kicker - Tap an untapped Vampire you control.
- TextPartSubType textPartVampire = (TextPartSubType) addTextPart(new TextPartSubType(SubType.VAMPIRE));
- FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("an untapped Vampire you control");
- filter.add(new TextPartSubtypePredicate(textPartVampire));
- filter.add(TappedPredicate.UNTAPPED);
- this.addAbility(new KickerAbility(new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))));
+ this.addAbility(new KickerAbility(new TapTargetCost(new TargetControlledPermanent(filter))));
// Target opponent loses half their life, rounded up.
this.getSpellAbility().addEffect(new BloodTributeLoseLifeEffect());
diff --git a/Mage.Sets/src/mage/cards/b/BloodhallPriest.java b/Mage.Sets/src/mage/cards/b/BloodhallPriest.java
index b25f7385704..2bd018e71a7 100644
--- a/Mage.Sets/src/mage/cards/b/BloodhallPriest.java
+++ b/Mage.Sets/src/mage/cards/b/BloodhallPriest.java
@@ -38,7 +38,7 @@ public final class BloodhallPriest extends CardImpl {
));
// Madness {1}{B}{R}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{B}{R}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{1}{B}{R}")));
}
private BloodhallPriest(final BloodhallPriest card) {
diff --git a/Mage.Sets/src/mage/cards/b/Bloodletter.java b/Mage.Sets/src/mage/cards/b/Bloodletter.java
index 39e5867931d..ace3e39ce06 100644
--- a/Mage.Sets/src/mage/cards/b/Bloodletter.java
+++ b/Mage.Sets/src/mage/cards/b/Bloodletter.java
@@ -64,7 +64,7 @@ class BloodletterStateTriggeredAbility extends StateTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Map initialCount = new HashMap<>();
- for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterNonlandPermanent(), getControllerId(), getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterNonlandPermanent(), getControllerId(), this, game)) {
Character initial = permanent.getName().charAt(0);
initialCount.putIfAbsent(initial, 0);
initialCount.put(initial, initialCount.get(initial) + 1);
diff --git a/Mage.Sets/src/mage/cards/b/BloodlineShaman.java b/Mage.Sets/src/mage/cards/b/BloodlineShaman.java
index 08eb1ff2a06..b561b9795a6 100644
--- a/Mage.Sets/src/mage/cards/b/BloodlineShaman.java
+++ b/Mage.Sets/src/mage/cards/b/BloodlineShaman.java
@@ -67,31 +67,34 @@ class BloodlineShamanEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false; }
+
MageObject sourceObject = game.getObject(source.getSourceId());
+ if (sourceObject == null) { return false; }
+
Choice typeChoice = new ChoiceCreatureType(sourceObject);
- if (controller != null && sourceObject != null && controller.choose(outcome, typeChoice, game)) {
- game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice());
- FilterCard filterSubtype = new FilterCard();
- filterSubtype.add(SubType.byDescription(typeChoice.getChoice()).getPredicate());
+ if (!controller.choose(outcome, typeChoice, game)) { return false; }
- // Reveal the top card of your library.
- if (controller.getLibrary().hasCards()) {
- Card card = controller.getLibrary().getFromTop(game);
- Cards cards = new CardsImpl(card);
- controller.revealCards(sourceObject.getIdName(), cards, game);
+ game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice());
+ FilterCard filterSubtype = new FilterCard();
+ filterSubtype.add(SubType.byDescription(typeChoice.getChoice()).getPredicate());
- if (card != null) {
- // If that card is a creature card of the chosen type, put it into your hand.
- if (filterSubtype.match(card, game)) {
- controller.moveCards(card, Zone.HAND, source, game);
- // Otherwise, put it into your graveyard.
- } else {
- controller.moveCards(card, Zone.GRAVEYARD, source, game);
- }
+ // Reveal the top card of your library.
+ if (controller.getLibrary().hasCards()) {
+ Card card = controller.getLibrary().getFromTop(game);
+ Cards cards = new CardsImpl(card);
+ controller.revealCards(sourceObject.getIdName(), cards, game);
+
+ if (card != null) {
+ // If that card is a creature card of the chosen type, put it into your hand.
+ if (filterSubtype.match(card, game)) {
+ controller.moveCards(card, Zone.HAND, source, game);
+ // Otherwise, put it into your graveyard.
+ } else {
+ controller.moveCards(card, Zone.GRAVEYARD, source, game);
}
}
- return true;
}
- return false;
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodmadVampire.java b/Mage.Sets/src/mage/cards/b/BloodmadVampire.java
index 1666d8b7b1c..39e228db340 100644
--- a/Mage.Sets/src/mage/cards/b/BloodmadVampire.java
+++ b/Mage.Sets/src/mage/cards/b/BloodmadVampire.java
@@ -29,7 +29,7 @@ public final class BloodmadVampire extends CardImpl {
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), false));
// Madness {1}{R}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{1}{R}")));
}
private BloodmadVampire(final BloodmadVampire card) {
diff --git a/Mage.Sets/src/mage/cards/b/BloodriteInvoker.java b/Mage.Sets/src/mage/cards/b/BloodriteInvoker.java
index d7eaa877878..78e904835cb 100644
--- a/Mage.Sets/src/mage/cards/b/BloodriteInvoker.java
+++ b/Mage.Sets/src/mage/cards/b/BloodriteInvoker.java
@@ -29,7 +29,7 @@ public final class BloodriteInvoker extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(1);
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(3), new GenericManaCost(8));
- ability.addEffect(new GainLifeEffect(3));
+ ability.addEffect(new GainLifeEffect(3).concatBy("and"));
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodstokeHowler.java b/Mage.Sets/src/mage/cards/b/BloodstokeHowler.java
index c699f30b94c..1ba54e6320c 100644
--- a/Mage.Sets/src/mage/cards/b/BloodstokeHowler.java
+++ b/Mage.Sets/src/mage/cards/b/BloodstokeHowler.java
@@ -34,7 +34,7 @@ public final class BloodstokeHowler extends CardImpl {
this.toughness = new MageInt(4);
// Morph {6}{R}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{6}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{6}{R}")));
// When Bloodstoke Howler is turned face up, Beast creatures you control get +3/+0 until end of turn.
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new BoostControlledEffect(3, 0, Duration.EndOfTurn, filter)));
diff --git a/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java b/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java
index 164776fc09f..98961f8e187 100644
--- a/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java
+++ b/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java
@@ -2,9 +2,10 @@ package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
-import mage.abilities.common.GoadAttachedAbility;
+import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.combat.GoadAttachedEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -27,10 +28,12 @@ public final class BloodthirstyBlade extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+0 and is goaded.
- this.addAbility(new GoadAttachedAbility(new BoostEquippedEffect(2, 0)));
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 0));
+ ability.addEffect(new GoadAttachedEffect());
+ this.addAbility(ability);
// {1}: Attach Bloodthirsty Blade to target creature an opponent controls. Active this ability only any time you could cast a sorcery.
- Ability ability = new ActivateAsSorceryActivatedAbility(
+ ability = new ActivateAsSorceryActivatedAbility(
Zone.BATTLEFIELD,
new AttachEffect(
Outcome.Detriment, "Attach {this} to target creature an opponent controls"
diff --git a/Mage.Sets/src/mage/cards/b/BlossomPrancer.java b/Mage.Sets/src/mage/cards/b/BlossomPrancer.java
new file mode 100644
index 00000000000..4cd309b21df
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BlossomPrancer.java
@@ -0,0 +1,89 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
+import mage.abilities.keyword.ReachAbility;
+import mage.cards.*;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.predicate.Predicates;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BlossomPrancer extends CardImpl {
+
+ public BlossomPrancer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
+
+ this.subtype.add(SubType.SPIRIT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Reach
+ this.addAbility(ReachAbility.getInstance());
+
+ // When Blossom Prancer enters the battlefield, look at the top five cards of your library.
+ // You may reveal a creature or enchantment card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in a random order.
+ // If you didn't put a card into your hand this way, you gain 4 life.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new BlossomPrancerEffect()));
+ }
+
+ private BlossomPrancer(final BlossomPrancer card) {
+ super(card);
+ }
+
+ @Override
+ public BlossomPrancer copy() {
+ return new BlossomPrancer(this);
+ }
+}
+
+class BlossomPrancerEffect extends LookLibraryAndPickControllerEffect {
+
+ private static final FilterCard filter = new FilterCard("creature or enchantment card");
+
+ static {
+ filter.add(Predicates.or(
+ CardType.CREATURE.getPredicate(),
+ CardType.ENCHANTMENT.getPredicate()
+ ));
+ }
+
+ BlossomPrancerEffect() {
+ super(5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM);
+ }
+
+ private BlossomPrancerEffect(final BlossomPrancerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BlossomPrancerEffect copy() {
+ return new BlossomPrancerEffect(this);
+ }
+
+ @Override
+ public boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) {
+ super.actionWithPickedCards(game, source, player, pickedCards, otherCards);
+ if (pickedCards.isEmpty()) {
+ player.gainLife(4, game, source);
+ }
+ return true;
+ }
+
+ @Override
+ public String getText(Mode mode) {
+ return super.getText(mode).concat(". If you didn't put a card into your hand this way, you gain 4 life");
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BlueElementalBlast.java b/Mage.Sets/src/mage/cards/b/BlueElementalBlast.java
index b8b48cadacb..55d1601c202 100644
--- a/Mage.Sets/src/mage/cards/b/BlueElementalBlast.java
+++ b/Mage.Sets/src/mage/cards/b/BlueElementalBlast.java
@@ -37,8 +37,7 @@ public final class BlueElementalBlast extends CardImpl {
this.getSpellAbility().addEffect(new CounterTargetEffect());
this.getSpellAbility().addTarget(new TargetSpell(filterSpell));
- Mode mode = new Mode();
- mode.addEffect(new DestroyTargetEffect());
+ Mode mode = new Mode(new DestroyTargetEffect());
mode.addTarget(new TargetPermanent(filterPermanent));
this.getSpellAbility().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/b/BlueWard.java b/Mage.Sets/src/mage/cards/b/BlueWard.java
index 3366356ce0d..8c2e631858c 100644
--- a/Mage.Sets/src/mage/cards/b/BlueWard.java
+++ b/Mage.Sets/src/mage/cards/b/BlueWard.java
@@ -1,36 +1,29 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.FilterCard;
-import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LoneFox
*/
public final class BlueWard extends CardImpl {
- private static final FilterCard filter = new FilterCard("blue");
-
- static {
- filter.add(new ColorPredicate(ObjectColor.BLUE));
- }
-
public BlueWard(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
this.subtype.add(SubType.AURA);
// Enchant creature
@@ -38,12 +31,11 @@ public final class BlueWard extends CardImpl {
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Protect));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
+
// Enchanted creature has protection from blue. This effect doesn't remove Blue Ward.
- ProtectionAbility gainedAbility = new ProtectionAbility(filter);
- gainedAbility.setAuraIdNotToBeRemoved(this.getId());
- Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA);
- effect.setText("Enchanted creature has protection from blue. This effect doesn't remove {this}.");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect(
+ ProtectionAbility.from(ObjectColor.BLUE), AttachmentType.AURA
+ ).setDoesntRemoveItself(true)));
}
private BlueWard(final BlueWard card) {
diff --git a/Mage.Sets/src/mage/cards/b/Blustersquall.java b/Mage.Sets/src/mage/cards/b/Blustersquall.java
index 1611be826cf..7d316f63a5a 100644
--- a/Mage.Sets/src/mage/cards/b/Blustersquall.java
+++ b/Mage.Sets/src/mage/cards/b/Blustersquall.java
@@ -30,8 +30,7 @@ public final class Blustersquall extends CardImpl {
this.getSpellAbility().addEffect(new TapTargetEffect());
// Overload {3}{U} (You may cast this spell for its overload cost. If you do, change its text by replacing all instances of "target" with "each.")
- this.addAbility(new OverloadAbility(this, new BlustersqallTapAllEffect(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL), new ManaCostsImpl("{3}{U}")));
-
+ this.addAbility(new OverloadAbility(this, new BlustersqallTapAllEffect(), new ManaCostsImpl("{3}{U}")));
}
private Blustersquall(final Blustersquall card) {
@@ -46,22 +45,18 @@ public final class Blustersquall extends CardImpl {
class BlustersqallTapAllEffect extends OneShotEffect {
- protected FilterCreaturePermanent filter;
-
- BlustersqallTapAllEffect(FilterCreaturePermanent filter) {
+ BlustersqallTapAllEffect() {
super(Outcome.Tap);
- this.filter = filter;
staticText = "Tap each creature you don't control";
}
private BlustersqallTapAllEffect(final BlustersqallTapAllEffect effect) {
super(effect);
- this.filter = effect.filter;
}
@Override
public boolean apply(Game game, Ability source) {
- for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, source.getControllerId(), source, game)) {
creature.tap(source, game);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java b/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java
index ebaa10ff365..f8539a32c22 100644
--- a/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java
+++ b/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java
@@ -1,12 +1,11 @@
package mage.cards.b;
import java.util.UUID;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.HistoricPredicate;
@@ -27,10 +26,7 @@ public final class BoardTheWeatherlight extends CardImpl {
// Look at the top five cards of your library. You may reveal a historic card from among them and put it into your hand. Put the rest on the bottom of your library in random order.
this.getSpellAbility().addEffect(
- new LookLibraryAndPickControllerEffect(
- StaticValue.get(5), false, StaticValue.get(1), filter,
- Zone.LIBRARY, false, true, false, Zone.HAND, true, false, false)
- .setBackInRandomOrder(true)
+ new LookLibraryAndPickControllerEffect(5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM)
.setText("Look at the top five cards of your library. You may reveal a historic card from among them"
+ " and put it into your hand. Put the rest on the bottom of your library in a random order. "
+ "(Artifacts, legendaries, and Sagas are historic.)")
diff --git a/Mage.Sets/src/mage/cards/b/BoardedWindow.java b/Mage.Sets/src/mage/cards/b/BoardedWindow.java
index a762fc91c62..141d2dc8920 100644
--- a/Mage.Sets/src/mage/cards/b/BoardedWindow.java
+++ b/Mage.Sets/src/mage/cards/b/BoardedWindow.java
@@ -66,8 +66,8 @@ class BoardedWindowFilter extends FilterAttackingCreature {
}
@Override
- public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
- if (!super.match(permanent, sourceId, playerId, game)) {
+ public boolean match(Permanent permanent, UUID playerId, Ability source, Game game) {
+ if (!super.match(permanent, playerId, source, game)) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/b/BodyCount.java b/Mage.Sets/src/mage/cards/b/BodyCount.java
new file mode 100644
index 00000000000..c095dce2569
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BodyCount.java
@@ -0,0 +1,73 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
+import mage.abilities.keyword.SpectacleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.Game;
+import mage.watchers.common.CreaturesDiedWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BodyCount extends CardImpl {
+
+ private static final Hint hint = new ValueHint(
+ "Creatures that died under your control this turn", BodyCountValue.instance
+ );
+
+ public BodyCount(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}");
+
+ // Spectacle {B}
+ this.addAbility(new SpectacleAbility(this, new ManaCostsImpl<>("{B}")));
+
+ // Draw a card for each creature that died under your control this turn.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(BodyCountValue.instance));
+ this.getSpellAbility().addHint(hint);
+ }
+
+ private BodyCount(final BodyCount card) {
+ super(card);
+ }
+
+ @Override
+ public BodyCount copy() {
+ return new BodyCount(this);
+ }
+}
+
+enum BodyCountValue implements DynamicValue {
+ instance;
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ return game.getState()
+ .getWatcher(CreaturesDiedWatcher.class)
+ .getAmountOfCreaturesDiedThisTurnByController(sourceAbility.getControllerId());
+ }
+
+ @Override
+ public BodyCountValue copy() {
+ return this;
+ }
+
+ @Override
+ public String getMessage() {
+ return "creature that died under your control this turn";
+ }
+
+ @Override
+ public String toString() {
+ return "1";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BodyDouble.java b/Mage.Sets/src/mage/cards/b/BodyDouble.java
index 77684c2a4f5..0aeb944e0fe 100644
--- a/Mage.Sets/src/mage/cards/b/BodyDouble.java
+++ b/Mage.Sets/src/mage/cards/b/BodyDouble.java
@@ -65,8 +65,8 @@ class BodyDoubleCopyEffect extends OneShotEffect {
if (player != null) {
Target target = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard"));
target.setNotTarget(true);
- if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
- player.choose(outcome, target, source.getSourceId(), game);
+ if (target.canChoose(source.getControllerId(), source, game)) {
+ player.choose(outcome, target, source, game);
Card copyFromCard = game.getCard(target.getFirstTarget());
if (copyFromCard != null) {
CopyEffect copyEffect = new CopyEffect(Duration.Custom, copyFromCard, source.getSourceId());
diff --git a/Mage.Sets/src/mage/cards/b/BodyDropper.java b/Mage.Sets/src/mage/cards/b/BodyDropper.java
new file mode 100644
index 00000000000..88ad2cf6a60
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BodyDropper.java
@@ -0,0 +1,58 @@
+package mage.cards.b;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SacrificePermanentTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.MenaceAbility;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class BodyDropper extends CardImpl {
+
+ public BodyDropper(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}");
+
+ this.subtype.add(SubType.DEVIL);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever you sacrifice another creature, put a +1/+1 counter on Body Dropper.
+ this.addAbility(new SacrificePermanentTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
+ StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE
+ ));
+
+ // {B}{R}, Sacrifice another creature: Body Dropper gains menace until end of turn.
+ Ability ability = new SimpleActivatedAbility(
+ new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn),
+ new ManaCostsImpl<>("{B}{R}")
+ );
+ ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE));
+ this.addAbility(ability);
+ }
+
+ private BodyDropper(final BodyDropper card) {
+ super(card);
+ }
+
+ @Override
+ public BodyDropper copy() {
+ return new BodyDropper(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BodyLaunderer.java b/Mage.Sets/src/mage/cards/b/BodyLaunderer.java
new file mode 100644
index 00000000000..7fe27f8bc1c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BodyLaunderer.java
@@ -0,0 +1,94 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesCreatureTriggeredAbility;
+import mage.abilities.common.DiesSourceTriggeredAbility;
+import mage.abilities.effects.Effects;
+import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
+import mage.abilities.effects.keyword.ConniveSourceEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreatureCard;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AnotherPredicate;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.filter.predicate.permanent.TokenPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCardInYourGraveyard;
+import mage.target.targetadjustment.TargetAdjuster;
+
+import java.util.UUID;
+
+/**
+ * @author weirddan455
+ */
+public final class BodyLaunderer extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter
+ = new FilterControlledCreaturePermanent("another nontoken creature you control");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(TokenPredicate.FALSE);
+ }
+
+ public BodyLaunderer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
+
+ this.subtype.add(SubType.OGRE);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Deathtouch
+ this.addAbility(DeathtouchAbility.getInstance());
+
+ // Whenever another nontoken creature you control dies, Body Launderer connives.
+ this.addAbility(new DiesCreatureTriggeredAbility(new ConniveSourceEffect("{this}"), false, filter));
+
+ // When Body Launderer dies, return another target non-Rogue creature card with power less than or equal to Body Launderer from your graveyard to the battlefield.
+ Ability ability = new DiesSourceTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()
+ .setText("return another target non-Rogue creature card with equal or lesser power from your graveyard to the battlefield")
+ );
+ ability.setTargetAdjuster(BodyLaundererAdjuster.instance);
+ this.addAbility(ability);
+ }
+
+ private BodyLaunderer(final BodyLaunderer card) {
+ super(card);
+ }
+
+ @Override
+ public BodyLaunderer copy() {
+ return new BodyLaunderer(this);
+ }
+}
+
+enum BodyLaundererAdjuster implements TargetAdjuster {
+ instance;
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ int power = 0;
+ Effects effects = ability.getEffects();
+ if (!effects.isEmpty()) {
+ Object died = effects.get(0).getValue("permanentLeftBattlefield");
+ if (died instanceof Permanent) {
+ power = ((Permanent) died).getPower().getValue();
+ }
+ }
+ FilterCreatureCard filter = new FilterCreatureCard("another target non-Rogue creature card with power less than or equal to Body Launderer from your graveyard");
+ filter.add(AnotherPredicate.instance);
+ filter.add(Predicates.not(SubType.ROGUE.getPredicate()));
+ filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, power + 1));
+ ability.getTargets().clear();
+ ability.addTarget(new TargetCardInYourGraveyard(filter));
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BodyOfKnowledge.java b/Mage.Sets/src/mage/cards/b/BodyOfKnowledge.java
index b28e836ac1d..1f82d8433ad 100644
--- a/Mage.Sets/src/mage/cards/b/BodyOfKnowledge.java
+++ b/Mage.Sets/src/mage/cards/b/BodyOfKnowledge.java
@@ -1,18 +1,19 @@
package mage.cards.b;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.DealtDamageToSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.game.Game;
-import mage.players.Player;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
import java.util.UUID;
@@ -44,8 +45,7 @@ public final class BodyOfKnowledge extends CardImpl {
// Whenever Body of Knowledge is dealt damage, draw that many cards.
this.addAbility(new DealtDamageToSourceTriggeredAbility(
- new BodyOfKnowledgeEffect(), false, false
- ));
+ new DrawCardSourceControllerEffect(SavedDamageValue.MANY), false));
}
private BodyOfKnowledge(final BodyOfKnowledge card) {
@@ -57,29 +57,3 @@ public final class BodyOfKnowledge extends CardImpl {
return new BodyOfKnowledge(this);
}
}
-
-class BodyOfKnowledgeEffect extends OneShotEffect {
-
- BodyOfKnowledgeEffect() {
- super(Outcome.Benefit);
- staticText = "draw that many cards";
- }
-
- private BodyOfKnowledgeEffect(final BodyOfKnowledgeEffect effect) {
- super(effect);
- }
-
- @Override
- public BodyOfKnowledgeEffect copy() {
- return new BodyOfKnowledgeEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- int amount = (Integer) getValue("damage");
- Player player = game.getPlayer(source.getControllerId());
- return player != null
- && amount > 0
- && player.drawCards(amount, source, game) > 0;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BoggartBirthRite.java b/Mage.Sets/src/mage/cards/b/BoggartBirthRite.java
index efd73cd9480..a4dfc023ee1 100644
--- a/Mage.Sets/src/mage/cards/b/BoggartBirthRite.java
+++ b/Mage.Sets/src/mage/cards/b/BoggartBirthRite.java
@@ -1,8 +1,6 @@
-
package mage.cards.b;
-import java.util.UUID;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -10,8 +8,9 @@ import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class BoggartBirthRite extends CardImpl {
@@ -23,10 +22,10 @@ public final class BoggartBirthRite extends CardImpl {
}
public BoggartBirthRite(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.TRIBAL,CardType.SORCERY},"{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{B}");
this.subtype.add(SubType.GOBLIN);
- this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter));
}
diff --git a/Mage.Sets/src/mage/cards/b/BoggartMob.java b/Mage.Sets/src/mage/cards/b/BoggartMob.java
index 711f4c89f75..d7425701433 100644
--- a/Mage.Sets/src/mage/cards/b/BoggartMob.java
+++ b/Mage.Sets/src/mage/cards/b/BoggartMob.java
@@ -33,7 +33,7 @@ public final class BoggartMob extends CardImpl {
this.toughness = new MageInt(5);
// Champion a Goblin
- this.addAbility(new ChampionAbility(this, SubType.GOBLIN, false));
+ this.addAbility(new ChampionAbility(this, SubType.GOBLIN));
// Whenever a Goblin you control deals combat damage to a player, you may create a 1/1 black Goblin Rogue creature token.
this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility(
diff --git a/Mage.Sets/src/mage/cards/b/BoggartShenanigans.java b/Mage.Sets/src/mage/cards/b/BoggartShenanigans.java
index 32ac7a90116..83bf41637b6 100644
--- a/Mage.Sets/src/mage/cards/b/BoggartShenanigans.java
+++ b/Mage.Sets/src/mage/cards/b/BoggartShenanigans.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
@@ -9,21 +7,22 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.TargetController;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetPlayerOrPlaneswalker;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class BoggartShenanigans extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another Goblin you control");
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.GOBLIN);
static {
- filter.add(TargetController.YOU.getControllerPredicate());
- filter.add(SubType.GOBLIN.getPredicate());
+ filter.add(AnotherPredicate.instance);
}
public BoggartShenanigans(UUID ownerId, CardSetInfo setInfo) {
@@ -31,7 +30,9 @@ public final class BoggartShenanigans extends CardImpl {
this.subtype.add(SubType.GOBLIN);
// Whenever another Goblin you control dies, you may have Boggart Shenanigans deal 1 damage to target player.
- Ability ability = new DiesCreatureTriggeredAbility(new DamageTargetEffect(1), true, filter, false);
+ Ability ability = new DiesCreatureTriggeredAbility(
+ new DamageTargetEffect(1), true, filter, false
+ ).setTriggerPhrase("Whenever another Goblin you control is put into a graveyard from the battlefield, ");
ability.addTarget(new TargetPlayerOrPlaneswalker());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BojukaBrigand.java b/Mage.Sets/src/mage/cards/b/BojukaBrigand.java
index 894ae198362..1769d3ea9cc 100644
--- a/Mage.Sets/src/mage/cards/b/BojukaBrigand.java
+++ b/Mage.Sets/src/mage/cards/b/BojukaBrigand.java
@@ -26,7 +26,7 @@ public final class BojukaBrigand extends CardImpl {
this.toughness = new MageInt(1);
this.addAbility(new CantBlockAbility());
- this.addAbility(new AllyEntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true));
+ this.addAbility(new AllyEntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true).setAbilityWord(null));
}
private BojukaBrigand(final BojukaBrigand card) {
diff --git a/Mage.Sets/src/mage/cards/b/BondOfDiscipline.java b/Mage.Sets/src/mage/cards/b/BondOfDiscipline.java
index ebc07aa9de8..a0274d07211 100644
--- a/Mage.Sets/src/mage/cards/b/BondOfDiscipline.java
+++ b/Mage.Sets/src/mage/cards/b/BondOfDiscipline.java
@@ -7,9 +7,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterOpponentsCreaturePermanent;
import java.util.UUID;
@@ -18,14 +16,11 @@ import java.util.UUID;
*/
public final class BondOfDiscipline extends CardImpl {
- private static final FilterPermanent filter
- = new FilterOpponentsCreaturePermanent("creatures your opponents control");
-
public BondOfDiscipline(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}");
// Tap all creatures your opponents control. Creatures you control gain lifelink until end of turn.
- this.getSpellAbility().addEffect(new TapAllEffect(filter));
+ this.getSpellAbility().addEffect(new TapAllEffect(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES));
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
LifelinkAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_PERMANENT_CREATURES
diff --git a/Mage.Sets/src/mage/cards/b/BondOfFlourishing.java b/Mage.Sets/src/mage/cards/b/BondOfFlourishing.java
index 840a0fe5767..de08f840a85 100644
--- a/Mage.Sets/src/mage/cards/b/BondOfFlourishing.java
+++ b/Mage.Sets/src/mage/cards/b/BondOfFlourishing.java
@@ -1,8 +1,8 @@
package mage.cards.b;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -16,17 +16,14 @@ import java.util.UUID;
*/
public final class BondOfFlourishing extends CardImpl {
- private static final FilterCard filter = new FilterPermanentCard();
+ private static final FilterCard filter = new FilterPermanentCard("a permanent card");
public BondOfFlourishing(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
// Look at the top three card of your library. You may reveal a permanent card from among them and put it into your hand. Put the rest on the bottom of your library in any order. You gain 3 life.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(3), false,
- StaticValue.get(1), filter, false
- ));
- this.getSpellAbility().addEffect(new GainLifeEffect(3).setText("You gain 3 life."));
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(3, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY));
+ this.getSpellAbility().addEffect(new GainLifeEffect(3));
}
private BondOfFlourishing(final BondOfFlourishing card) {
diff --git a/Mage.Sets/src/mage/cards/b/BondOfInsight.java b/Mage.Sets/src/mage/cards/b/BondOfInsight.java
index 960fe72b091..e36f25f79c2 100644
--- a/Mage.Sets/src/mage/cards/b/BondOfInsight.java
+++ b/Mage.Sets/src/mage/cards/b/BondOfInsight.java
@@ -73,7 +73,7 @@ class BondOfInsightEffect extends OneShotEffect {
TargetCard target = new TargetCardInYourGraveyard(
0, 2, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, true
);
- if (!player.choose(outcome, target, source.getSourceId(), game)) {
+ if (!player.choose(outcome, target, source, game)) {
return false;
}
Cards cards = new CardsImpl(target.getTargets());
diff --git a/Mage.Sets/src/mage/cards/b/BondsOfFaith.java b/Mage.Sets/src/mage/cards/b/BondsOfFaith.java
index 8a55f11cdfc..ff6b461f474 100644
--- a/Mage.Sets/src/mage/cards/b/BondsOfFaith.java
+++ b/Mage.Sets/src/mage/cards/b/BondsOfFaith.java
@@ -1,48 +1,55 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
import mage.abilities.condition.InvertCondition;
import mage.abilities.condition.common.EquippedHasSubtypeCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.decorator.ConditionalRestrictionEffect;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.combat.CantAttackBlockAttachedEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
* @author nantuko
*/
public final class BondsOfFaith extends CardImpl {
- private static final String rule = "Enchanted creature gets +2/+2 as long as it's a Human";
+ private static final Condition condition1 = new EquippedHasSubtypeCondition(SubType.HUMAN);
+ private static final Condition condition2 = new InvertCondition(condition1);
public BondsOfFaith(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
this.subtype.add(SubType.AURA);
-
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Neutral));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// Enchanted creature gets +2/+2 as long as it's a Human. Otherwise, it can't attack or block.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(2, 2), new EquippedHasSubtypeCondition(SubType.HUMAN), rule)));
- Effect effect = new ConditionalRestrictionEffect(new CantAttackBlockAttachedEffect(AttachmentType.AURA), new InvertCondition(new EquippedHasSubtypeCondition(SubType.HUMAN)));
- effect.setText("Otherwise, it can't attack or block");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new BoostEquippedEffect(2, 2), condition1,
+ "Enchanted creature gets +2/+2 as long as it's a Human"
+ ));
+ ability.addEffect(new ConditionalRestrictionEffect(
+ new CantAttackBlockAttachedEffect(AttachmentType.AURA),
+ condition2, "Otherwise, it can't attack or block"
+ ));
+ this.addAbility(ability);
}
private BondsOfFaith(final BondsOfFaith card) {
diff --git a/Mage.Sets/src/mage/cards/b/BondsOfMortality.java b/Mage.Sets/src/mage/cards/b/BondsOfMortality.java
index cb6c2b19578..c2b32b3ec0c 100644
--- a/Mage.Sets/src/mage/cards/b/BondsOfMortality.java
+++ b/Mage.Sets/src/mage/cards/b/BondsOfMortality.java
@@ -5,7 +5,7 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.costs.mana.ColoredManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.LoseAbilityAllEffect;
@@ -14,10 +14,9 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
-import mage.constants.TargetController;
-import mage.constants.Zone;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.StaticFilters;
/**
*
@@ -25,12 +24,6 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class BondsOfMortality extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public BondsOfMortality(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}");
@@ -38,10 +31,12 @@ public final class BondsOfMortality extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false));
// {G}: Creatures your opponents control lose hexproof and indestructible until end of turn.
- Effect effect = new LoseAbilityAllEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, filter);
+ Effect effect = new LoseAbilityAllEffect(
+ HexproofAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES);
effect.setText("Creatures your opponents control lose hexproof");
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{G}"));
- effect = new LoseAbilityAllEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn, filter);
+ Ability ability = new SimpleActivatedAbility(effect, new ColoredManaCost(ColoredManaSymbol.G));
+ effect = new LoseAbilityAllEffect(
+ IndestructibleAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES);
effect.setText("and indestructible until end of turn");
ability.addEffect(effect);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BoneDragon.java b/Mage.Sets/src/mage/cards/b/BoneDragon.java
index b5a67d9c643..f356a27c55e 100644
--- a/Mage.Sets/src/mage/cards/b/BoneDragon.java
+++ b/Mage.Sets/src/mage/cards/b/BoneDragon.java
@@ -1,24 +1,24 @@
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileFromGraveCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
-import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
-import mage.filter.predicate.mageobject.AnotherCardPredicate;
+import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class BoneDragon extends CardImpl {
@@ -26,7 +26,7 @@ public final class BoneDragon extends CardImpl {
private static final FilterCard filter = new FilterCard("other cards");
static {
- filter.add(new AnotherCardPredicate());
+ filter.add(AnotherPredicate.instance);
}
public BoneDragon(UUID ownerId, CardSetInfo setInfo) {
@@ -44,7 +44,7 @@ public final class BoneDragon extends CardImpl {
Ability ability = new SimpleActivatedAbility(
Zone.GRAVEYARD,
new ReturnSourceFromGraveyardToBattlefieldEffect(true),
- new ManaCostsImpl("{3}{B}{B}")
+ new ManaCostsImpl<>("{3}{B}{B}")
);
ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(7, filter)));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BoneShards.java b/Mage.Sets/src/mage/cards/b/BoneShards.java
index 94b45c7385e..8b79ba03d06 100644
--- a/Mage.Sets/src/mage/cards/b/BoneShards.java
+++ b/Mage.Sets/src/mage/cards/b/BoneShards.java
@@ -22,8 +22,8 @@ public final class BoneShards extends CardImpl {
// As an additional cost to cast this spell, sacrifice a creature or discard a card.
this.getSpellAbility().addCost(new OrCost(
- new SacrificeTargetCost(new TargetControlledCreaturePermanent()),
- new DiscardCardCost(), "sacrifice a creature or discard a card"
+ "sacrifice a creature or discard a card", new SacrificeTargetCost(new TargetControlledCreaturePermanent()),
+ new DiscardCardCost()
));
// Destroy target creature or planeswalker.
diff --git a/Mage.Sets/src/mage/cards/b/Boneknitter.java b/Mage.Sets/src/mage/cards/b/Boneknitter.java
index edea575b885..ec9b2274ad9 100644
--- a/Mage.Sets/src/mage/cards/b/Boneknitter.java
+++ b/Mage.Sets/src/mage/cards/b/Boneknitter.java
@@ -40,7 +40,7 @@ public final class Boneknitter extends CardImpl {
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
// Morph {2}{B}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{B}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{2}{B}")));
}
private Boneknitter(final Boneknitter card) {
diff --git a/Mage.Sets/src/mage/cards/b/BonescytheSliver.java b/Mage.Sets/src/mage/cards/b/BonescytheSliver.java
index d386ccdd282..fc222e32f03 100644
--- a/Mage.Sets/src/mage/cards/b/BonescytheSliver.java
+++ b/Mage.Sets/src/mage/cards/b/BonescytheSliver.java
@@ -30,7 +30,7 @@ public final class BonescytheSliver extends CardImpl {
// Sliver creatures you control have double strike.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(),
- Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS)));
+ Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_SLIVERS)));
}
private BonescytheSliver(final BonescytheSliver card) {
diff --git a/Mage.Sets/src/mage/cards/b/BonesplitterSliver.java b/Mage.Sets/src/mage/cards/b/BonesplitterSliver.java
index a3b89d1af4a..70c8ec855c0 100644
--- a/Mage.Sets/src/mage/cards/b/BonesplitterSliver.java
+++ b/Mage.Sets/src/mage/cards/b/BonesplitterSliver.java
@@ -27,7 +27,7 @@ public final class BonesplitterSliver extends CardImpl {
// All Sliver creatures get +2/+0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
- new BoostAllEffect(2, 0, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, false)));
+ new BoostAllEffect(2, 0, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS, false)));
}
private BonesplitterSliver(final BonesplitterSliver card) {
diff --git a/Mage.Sets/src/mage/cards/b/BoneyardParley.java b/Mage.Sets/src/mage/cards/b/BoneyardParley.java
index b72c702aa0b..24ae9d6aec0 100644
--- a/Mage.Sets/src/mage/cards/b/BoneyardParley.java
+++ b/Mage.Sets/src/mage/cards/b/BoneyardParley.java
@@ -79,7 +79,7 @@ class BoneyardParleyEffect extends OneShotEffect {
}
if (!cards.isEmpty() && player.moveCards(cards, Zone.EXILED, source, game)) {
TargetOpponent targetOpponent = new TargetOpponent(true);
- if (player.choose(Outcome.Neutral, targetOpponent, source.getSourceId(), game)) {
+ if (player.choose(Outcome.Neutral, targetOpponent, source, game)) {
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
if (opponent != null) {
TargetCard targetCards = new TargetCard(0, cards.size(), Zone.EXILED, new FilterCard("cards to put in the first pile"));
diff --git a/Mage.Sets/src/mage/cards/b/BoneyardScourge.java b/Mage.Sets/src/mage/cards/b/BoneyardScourge.java
index 12aeba51068..453c598235d 100644
--- a/Mage.Sets/src/mage/cards/b/BoneyardScourge.java
+++ b/Mage.Sets/src/mage/cards/b/BoneyardScourge.java
@@ -64,7 +64,7 @@ public final class BoneyardScourge extends CardImpl {
class DiesWhileInGraveyardTriggeredAbility extends TriggeredAbilityImpl {
- protected FilterCreaturePermanent filter;
+ private final FilterCreaturePermanent filter;
public DiesWhileInGraveyardTriggeredAbility(Effect effect, FilterCreaturePermanent filter) {
super(Zone.GRAVEYARD, effect, false);
@@ -89,22 +89,19 @@ class DiesWhileInGraveyardTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ if (!zEvent.isDiesEvent()) { return false; }
+
for (Zone z : Zone.values()) {
if (game.getShortLivingLKI(sourceId, z) && z != Zone.GRAVEYARD) {
return false;
}
}
- if (zEvent.isDiesEvent()) {
- if (filter.match(zEvent.getTarget(), sourceId, controllerId, game)) {
- return true;
- }
- }
- return false;
+
+ return filter.match(zEvent.getTarget(), controllerId,this, game);
}
@Override
public String getTriggerPhrase() {
return "Whenever " + filter.getMessage() + " dies while {this} is in your graveyard, " ;
}
-
}
diff --git a/Mage.Sets/src/mage/cards/b/BoonOfBoseiju.java b/Mage.Sets/src/mage/cards/b/BoonOfBoseiju.java
index 868f4ecc395..a7a896e7549 100644
--- a/Mage.Sets/src/mage/cards/b/BoonOfBoseiju.java
+++ b/Mage.Sets/src/mage/cards/b/BoonOfBoseiju.java
@@ -53,7 +53,7 @@ enum BoonOfBoseijuValue implements DynamicValue {
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_PERMANENT,
- sourceAbility.getControllerId(), sourceAbility.getSourceId(), game
+ sourceAbility.getControllerId(), sourceAbility, game
).stream().mapToInt(MageObject::getManaValue).sum();
}
diff --git a/Mage.Sets/src/mage/cards/b/BoonOfSafety.java b/Mage.Sets/src/mage/cards/b/BoonOfSafety.java
new file mode 100644
index 00000000000..7ecff9bf54b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BoonOfSafety.java
@@ -0,0 +1,37 @@
+package mage.cards.b;
+
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.counters.CounterType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BoonOfSafety extends CardImpl {
+
+ public BoonOfSafety(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
+
+ // Put a shield counter on target creature.
+ this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.SHIELD.createInstance()));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+
+ // Scry 1.
+ this.getSpellAbility().addEffect(new ScryEffect(1, false).concatBy("
"));
+ }
+
+ private BoonOfSafety(final BoonOfSafety card) {
+ super(card);
+ }
+
+ @Override
+ public BoonOfSafety copy() {
+ return new BoonOfSafety(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BoonweaverGiant.java b/Mage.Sets/src/mage/cards/b/BoonweaverGiant.java
index 24766e3ecad..058afd270ab 100644
--- a/Mage.Sets/src/mage/cards/b/BoonweaverGiant.java
+++ b/Mage.Sets/src/mage/cards/b/BoonweaverGiant.java
@@ -54,7 +54,8 @@ class BoonweaverGiantEffect extends OneShotEffect {
public BoonweaverGiantEffect() {
super(Outcome.UnboostCreature);
- this.staticText = "you may search your graveyard, hand, and/or library for an Aura card and put it onto the battlefield attached to {this}. If you search your library this way, shuffle.";
+ this.staticText = "you may search your graveyard, hand, and/or library for an Aura card and put it onto the battlefield attached to {this}." +
+ "If you search your library this way, shuffle.";
}
public BoonweaverGiantEffect(final BoonweaverGiantEffect effect) {
@@ -69,45 +70,40 @@ class BoonweaverGiantEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller == null) {
- return false;
- }
+ if (controller == null) { return false; }
FilterCard filter = new FilterCard("Aura card");
filter.add(CardType.ENCHANTMENT.getPredicate());
filter.add(SubType.AURA.getPredicate());
Card card = null;
- Zone zone = null;
+
+ // Choose card from graveyard
if (controller.chooseUse(Outcome.Neutral, "Search your graveyard for an Aura card?", source, game)) {
TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filter);
if (controller.choose(Outcome.PutCardInPlay, controller.getGraveyard(), target, game)) {
card = game.getCard(target.getFirstTarget());
- if (card != null) {
- zone = Zone.GRAVEYARD;
- }
}
}
+
+ // Choose card from your hand
if (card == null && controller.chooseUse(Outcome.Neutral, "Search your Hand for an Aura card?", source, game)) {
TargetCardInHand target = new TargetCardInHand(filter);
if (controller.choose(Outcome.PutCardInPlay, controller.getHand(), target, game)) {
card = game.getCard(target.getFirstTarget());
- if (card != null) {
- zone = Zone.HAND;
- }
}
}
+
+ // Choose a card from your library
if (card == null) {
TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (controller.searchLibrary(target, source, game)) {
card = game.getCard(target.getFirstTarget());
- if (card != null) {
- zone = Zone.LIBRARY;
- }
}
controller.shuffleLibrary(source, game);
}
- // aura card found - attach it
+
+ // Aura card found - attach it
if (card != null) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BootleggersStash.java b/Mage.Sets/src/mage/cards/b/BootleggersStash.java
new file mode 100644
index 00000000000..5998ae4d555
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BootleggersStash.java
@@ -0,0 +1,41 @@
+package mage.cards.b;
+
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.filter.StaticFilters;
+import mage.game.permanent.token.TreasureToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BootleggersStash extends CardImpl {
+
+ public BootleggersStash(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}{G}");
+
+ // Lands you control have "{T}: Create a Treasure token."
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
+ new SimpleActivatedAbility(
+ new CreateTokenEffect(new TreasureToken()), new TapSourceCost()
+ ), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS
+ )));
+ }
+
+ private BootleggersStash(final BootleggersStash card) {
+ super(card);
+ }
+
+ @Override
+ public BootleggersStash copy() {
+ return new BootleggersStash(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BoreasCharger.java b/Mage.Sets/src/mage/cards/b/BoreasCharger.java
index 7169a5d1240..b84fa7fddae 100644
--- a/Mage.Sets/src/mage/cards/b/BoreasCharger.java
+++ b/Mage.Sets/src/mage/cards/b/BoreasCharger.java
@@ -92,7 +92,7 @@ class BoreasChargerEffect extends OneShotEffect {
return false;
}
TargetPlayer target = new TargetPlayer(1, 1, true, filter);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
Player opponent = game.getPlayer(target.getFirstTarget());
if (opponent == null) {
controller.shuffleLibrary(source, game);
diff --git a/Mage.Sets/src/mage/cards/b/BorosCharm.java b/Mage.Sets/src/mage/cards/b/BorosCharm.java
index bc624d16edf..4a714829ab5 100644
--- a/Mage.Sets/src/mage/cards/b/BorosCharm.java
+++ b/Mage.Sets/src/mage/cards/b/BorosCharm.java
@@ -32,8 +32,7 @@ public final class BorosCharm extends CardImpl {
IndestructibleAbility.getInstance(), Duration.EndOfTurn
)));
//or target creature gains double strike until end of turn.
- Mode mode2 = new Mode();
- mode2.addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn));
+ Mode mode2 = new Mode(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn));
mode2.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addMode(mode2);
}
diff --git a/Mage.Sets/src/mage/cards/b/BorosReckoner.java b/Mage.Sets/src/mage/cards/b/BorosReckoner.java
index bc3a19a925c..1d20671065b 100644
--- a/Mage.Sets/src/mage/cards/b/BorosReckoner.java
+++ b/Mage.Sets/src/mage/cards/b/BorosReckoner.java
@@ -31,8 +31,8 @@ public final class BorosReckoner extends CardImpl {
this.toughness = new MageInt(3);
// Whenever Boros Reckoner is dealt damage, it deals that much damage to any target.
- Ability ability = new DealtDamageToSourceTriggeredAbility(new DamageTargetEffect(SavedDamageValue.instance)
- .setText("it deals that much damage to any target"), false, false);
+ Ability ability = new DealtDamageToSourceTriggeredAbility(
+ new DamageTargetEffect(SavedDamageValue.MUCH, "it"), false);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BorrowedGrace.java b/Mage.Sets/src/mage/cards/b/BorrowedGrace.java
index c31ecdaf35b..0aa8bc4cffb 100644
--- a/Mage.Sets/src/mage/cards/b/BorrowedGrace.java
+++ b/Mage.Sets/src/mage/cards/b/BorrowedGrace.java
@@ -31,8 +31,7 @@ public final class BorrowedGrace extends CardImpl {
this.getSpellAbility().addEffect(new BoostControlledEffect(2, 0, Duration.EndOfTurn));
// Creatures you control get +0/+2 until end of turn.
- Mode mode = new Mode();
- mode.addEffect(new BoostControlledEffect(0, 2, Duration.EndOfTurn));
+ Mode mode = new Mode(new BoostControlledEffect(0, 2, Duration.EndOfTurn));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/b/BorrowedHostility.java b/Mage.Sets/src/mage/cards/b/BorrowedHostility.java
index 18948ab3096..780b8319a26 100644
--- a/Mage.Sets/src/mage/cards/b/BorrowedHostility.java
+++ b/Mage.Sets/src/mage/cards/b/BorrowedHostility.java
@@ -41,10 +41,9 @@ public final class BorrowedHostility extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filterBoost).withChooseHint("gets +3/+0 until end of turn"));
// Target creature gains first strike until end of turn.
- Mode mode = new Mode();
effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn);
effect.setText("Target creature gains first strike until end of turn");
- mode.addEffect(effect);
+ Mode mode = new Mode(effect);
mode.addTarget(new TargetCreaturePermanent(filterFirstStrike).withChooseHint("gains first strike until end of turn"));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/b/BorrowedMalevolence.java b/Mage.Sets/src/mage/cards/b/BorrowedMalevolence.java
index 06af14582c2..f427b1c6db0 100644
--- a/Mage.Sets/src/mage/cards/b/BorrowedMalevolence.java
+++ b/Mage.Sets/src/mage/cards/b/BorrowedMalevolence.java
@@ -39,10 +39,9 @@ public final class BorrowedMalevolence extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filterCreaturePlus).withChooseHint("gets +1/+1 until end of turn"));
// Target creature gets -1/-1 until end of turn.
- Mode mode = new Mode();
effect = new BoostTargetEffect(-1, -1, Duration.EndOfTurn);
effect.setText("Target creature gets -1/-1 until end of turn");
- mode.addEffect(effect);
+ Mode mode = new Mode(effect);
mode.addTarget(new TargetCreaturePermanent(filterCreatureMinus).withChooseHint("gets -1/-1 until end of turn"));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/b/Borrowing100000Arrows.java b/Mage.Sets/src/mage/cards/b/Borrowing100000Arrows.java
index 815623ebc9d..d2f033af6d8 100644
--- a/Mage.Sets/src/mage/cards/b/Borrowing100000Arrows.java
+++ b/Mage.Sets/src/mage/cards/b/Borrowing100000Arrows.java
@@ -64,7 +64,7 @@ class Borrowing100000ArrowsEffect extends OneShotEffect {
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(TappedPredicate.TAPPED);
filter.add(new ControllerIdPredicate(opponent.getId()));
- return new DrawCardSourceControllerEffect(game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game)).apply(game, source);
+ return new DrawCardSourceControllerEffect(game.getBattlefield().count(filter, source.getControllerId(), source, game)).apply(game, source);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/b/BoseijuReachesSkyward.java b/Mage.Sets/src/mage/cards/b/BoseijuReachesSkyward.java
index ca783adf1e1..61aa70ab4e1 100644
--- a/Mage.Sets/src/mage/cards/b/BoseijuReachesSkyward.java
+++ b/Mage.Sets/src/mage/cards/b/BoseijuReachesSkyward.java
@@ -12,7 +12,7 @@ import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
-import mage.filter.StaticFilters;
+import mage.filter.common.FilterLandCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCardInYourGraveyard;
@@ -24,6 +24,7 @@ import java.util.UUID;
public final class BoseijuReachesSkyward extends CardImpl {
private static final FilterCard filter = new FilterCard("basic Forest cards");
+ private static final FilterCard filter2 = new FilterLandCard("land card from your graveyard");
static {
filter.add(SuperType.BASIC.getPredicate());
@@ -51,7 +52,7 @@ public final class BoseijuReachesSkyward extends CardImpl {
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II,
new PutOnLibraryTargetEffect(true),
- new TargetCardInYourGraveyard(0, 1, StaticFilters.FILTER_CARD_LAND)
+ new TargetCardInYourGraveyard(0, 1, filter2)
);
// III — Exile this Saga, then return it to the battlefield transformed under your control.
diff --git a/Mage.Sets/src/mage/cards/b/BoseijuWhoEndures.java b/Mage.Sets/src/mage/cards/b/BoseijuWhoEndures.java
new file mode 100644
index 00000000000..ae970ea5782
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BoseijuWhoEndures.java
@@ -0,0 +1,121 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.costadjusters.LegendaryCreatureCostAdjuster;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.ChannelAbility;
+import mage.abilities.mana.GreenManaAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterLandCard;
+import mage.filter.predicate.Predicates;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BoseijuWhoEndures extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterPermanent("artifact, enchantment, or nonbasic land an opponent controls");
+
+ static {
+ filter.add(TargetController.OPPONENT.getControllerPredicate());
+ filter.add(Predicates.or(
+ CardType.ARTIFACT.getPredicate(),
+ CardType.ENCHANTMENT.getPredicate(),
+ Predicates.and(
+ Predicates.not(SuperType.BASIC.getPredicate()),
+ CardType.LAND.getPredicate()
+ )
+ ));
+ }
+
+ public BoseijuWhoEndures(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ this.addSuperType(SuperType.LEGENDARY);
+
+ // {T}: Add {G}.
+ this.addAbility(new GreenManaAbility());
+
+ // Channel — {1}{G}, Discard Boseiju, Who Endures: Destroy target artifact, enchantment, or nonbasic land an opponent controls. That player may search their library for a land card with a basic land type, put it onto the battlefield, then shuffle. This ability costs {1} less to activate for each legendary creature you control.
+ Ability ability = new ChannelAbility("{1}{G}", new BoseijuWhoEnduresEffect());
+ ability.addTarget(new TargetPermanent(filter));
+ ability.setCostAdjuster(LegendaryCreatureCostAdjuster.instance);
+ this.addAbility(ability.addHint(LegendaryCreatureCostAdjuster.getHint()));
+ }
+
+ private BoseijuWhoEndures(final BoseijuWhoEndures card) {
+ super(card);
+ }
+
+ @Override
+ public BoseijuWhoEndures copy() {
+ return new BoseijuWhoEndures(this);
+ }
+}
+
+class BoseijuWhoEnduresEffect extends OneShotEffect {
+
+ private static final FilterCard filter = new FilterLandCard("land card with a basic land type");
+
+ static {
+ filter.add(Predicates.or(
+ SubType.PLAINS.getPredicate(),
+ SubType.ISLAND.getPredicate(),
+ SubType.SWAMP.getPredicate(),
+ SubType.MOUNTAIN.getPredicate(),
+ SubType.FOREST.getPredicate()
+ ));
+ }
+
+ BoseijuWhoEnduresEffect() {
+ super(Outcome.Benefit);
+ staticText = "destroy target artifact, enchantment, or nonbasic land an opponent controls. " +
+ "That player may search their library for a land card with a basic land type, " +
+ "put it onto the battlefield, then shuffle. " +
+ "This ability costs {1} less to activate for each legendary creature you control";
+ }
+
+ private BoseijuWhoEnduresEffect(final BoseijuWhoEnduresEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BoseijuWhoEnduresEffect copy() {
+ return new BoseijuWhoEnduresEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (controller == null || permanent == null) {
+ return false;
+ }
+ Player player = game.getPlayer(permanent.getControllerId());
+ permanent.destroy(source, game);
+ if (!player.chooseUse(Outcome.PutCardInPlay, "Search your library for a land card?", source, game)) {
+ return true;
+ }
+ TargetCardInLibrary target = new TargetCardInLibrary(filter);
+ player.searchLibrary(target, source, game);
+ Card card = player.getLibrary().getCard(target.getFirstTarget(), game);
+ if (card != null) {
+ player.moveCards(card, Zone.BATTLEFIELD, source, game);
+ }
+ player.shuffleLibrary(source, game);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java b/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java
index 54d3d5ab997..d3e5160a38c 100644
--- a/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java
+++ b/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java
@@ -112,7 +112,7 @@ class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifyingEffe
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject != null) {
return "This spell can't be countered because mana from " + sourceObject.getName() + " was spent to cast it.";
}
diff --git a/Mage.Sets/src/mage/cards/b/BosiumStrip.java b/Mage.Sets/src/mage/cards/b/BosiumStrip.java
index bc0a5e4dc70..179cfaf8577 100644
--- a/Mage.Sets/src/mage/cards/b/BosiumStrip.java
+++ b/Mage.Sets/src/mage/cards/b/BosiumStrip.java
@@ -109,13 +109,13 @@ class BosiumStripReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Card card = (Card) game.getState().getValue("BosiumStrip");
- if (card != null) {
- ((ZoneChangeEvent) event).setToZone(Zone.EXILED);
- }
- }
- return false;
+ if (controller == null) { return false; }
+
+ Card card = (Card) game.getState().getValue("BosiumStrip");
+ if (card == null) { return false; }
+
+ ((ZoneChangeEvent) event).setToZone(Zone.EXILED);
+ return true;
}
@Override
@@ -126,16 +126,16 @@ class BosiumStripReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- if (zEvent.getToZone() == Zone.GRAVEYARD) {
- Card card = game.getCard(event.getSourceId());
- if (card != null
- && StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(card, game)) {
- CastFromGraveyardWatcher watcher = game.getState().getWatcher(CastFromGraveyardWatcher.class);
- return watcher != null
- && watcher.spellWasCastFromGraveyard(event.getTargetId(),
- game.getState().getZoneChangeCounter(event.getTargetId()));
- }
- }
- return false;
+ if (zEvent.getToZone() != Zone.GRAVEYARD) { return false; }
+
+ Card card = game.getCard(event.getSourceId());
+ if (card == null) { return false; }
+
+ if (!StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(card, game)) { return false; }
+
+ CastFromGraveyardWatcher watcher = game.getState().getWatcher(CastFromGraveyardWatcher.class);
+ return watcher != null
+ && watcher.spellWasCastFromGraveyard(event.getTargetId(),
+ game.getState().getZoneChangeCounter(event.getTargetId()));
}
}
diff --git a/Mage.Sets/src/mage/cards/b/Bossk.java b/Mage.Sets/src/mage/cards/b/Bossk.java
index f4f07f8928b..cb63516b910 100644
--- a/Mage.Sets/src/mage/cards/b/Bossk.java
+++ b/Mage.Sets/src/mage/cards/b/Bossk.java
@@ -70,7 +70,7 @@ class BosskTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkInterveningIfClause(Game game) {
- return game.getBattlefield().count(new FilterControlledLandPermanent(), getSourceId(), getControllerId(), game) > 4;
+ return game.getBattlefield().count(new FilterControlledLandPermanent(), getControllerId(), this, game) > 4;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BosssChauffeur.java b/Mage.Sets/src/mage/cards/b/BosssChauffeur.java
new file mode 100644
index 00000000000..c00536a31fb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BosssChauffeur.java
@@ -0,0 +1,72 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.AllianceAbility;
+import mage.abilities.common.DiesSourceTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.dynamicvalue.AdditiveDynamicValue;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.CountersSourceCount;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.permanent.token.CitizenGreenWhiteToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BosssChauffeur extends CardImpl {
+
+ private static final DynamicValue xValue = new AdditiveDynamicValue(
+ StaticValue.get(1),
+ new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)
+ );
+ private static final Hint hint = new ValueHint(
+ "Other creatures you control",
+ new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)
+ );
+ private static final DynamicValue counterCount = new CountersSourceCount(CounterType.P1P1);
+
+ public BosssChauffeur(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.CITIZEN);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // Boss's Chauffeur enters the battlefield with a number of +1/+1 counters on it equal to one plus the number of other creatures you control.
+ this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(
+ CounterType.P1P1.createInstance(), xValue, false
+ ), "with a number of +1/+1 counters on it equal to " +
+ "one plus the number of other creatures you control").addHint(hint));
+
+ // Alliance — Whenever another creature enters the battlefield under your control, put a +1/+1 counter on Boss's Chauffeur.
+ this.addAbility(new AllianceAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())));
+
+ // When Boss's Chauffeur dies, create a 1/1 green and white Citizen creature token for each +1/+1 counter on it.
+ this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(
+ new CitizenGreenWhiteToken(), counterCount
+ ).setText("create a 1/1 green and white Citizen creature token for each +1/+1 counter on it")));
+ }
+
+ private BosssChauffeur(final BosssChauffeur card) {
+ super(card);
+ }
+
+ @Override
+ public BosssChauffeur copy() {
+ return new BosssChauffeur(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BotanicalPlaza.java b/Mage.Sets/src/mage/cards/b/BotanicalPlaza.java
new file mode 100644
index 00000000000..3afbf283892
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BotanicalPlaza.java
@@ -0,0 +1,50 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTappedAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.mana.GreenManaAbility;
+import mage.abilities.mana.WhiteManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BotanicalPlaza extends CardImpl {
+
+ public BotanicalPlaza(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Botanical Plaza enters the battlefield tapped.
+ this.addAbility(new EntersBattlefieldTappedAbility());
+
+ // {T}: Add {G} or {W}.
+ this.addAbility(new GreenManaAbility());
+ this.addAbility(new WhiteManaAbility());
+
+ // {2}{G}{W}, {T}, Sacrifice Botanical Plaza: Draw a card.
+ Ability ability = new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{2}{G}{W}")
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ private BotanicalPlaza(final BotanicalPlaza card) {
+ super(card);
+ }
+
+ @Override
+ public BotanicalPlaza copy() {
+ return new BotanicalPlaza(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BouncersBeatdown.java b/Mage.Sets/src/mage/cards/b/BouncersBeatdown.java
new file mode 100644
index 00000000000..e0033956622
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BouncersBeatdown.java
@@ -0,0 +1,58 @@
+package mage.cards.b;
+
+import mage.ObjectColor;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.SourceTargetsPermanentCondition;
+import mage.abilities.dynamicvalue.common.GreatestPowerAmongControlledCreaturesValue;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.ExileTargetIfDiesEffect;
+import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.target.common.TargetCreatureOrPlaneswalker;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BouncersBeatdown extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterPermanent("a black permanent");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.BLACK));
+ }
+
+ private static final Condition condition = new SourceTargetsPermanentCondition(filter);
+
+ public BouncersBeatdown(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
+
+ // This spell costs {2} less to cast if it targets a black permanent.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new SpellCostReductionSourceEffect(2, condition).setCanWorksOnStackOnly(true)
+ ).setRuleAtTheTop(true));
+
+ // Bouncer's Beatdown deals X damage to target creature or planeswalker, where X is the greatest power among creatures you control. If that creature or planeswalker would die this turn, exile it instead.
+ this.getSpellAbility().addEffect(new DamageTargetEffect(GreatestPowerAmongControlledCreaturesValue.instance));
+ this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
+ this.getSpellAbility().addEffect(new ExileTargetIfDiesEffect("creature or planeswalker"));
+ this.getSpellAbility().addHint(GreatestPowerAmongControlledCreaturesValue.getHint());
+ }
+
+ private BouncersBeatdown(final BouncersBeatdown card) {
+ super(card);
+ }
+
+ @Override
+ public BouncersBeatdown copy() {
+ return new BouncersBeatdown(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BoundDetermined.java b/Mage.Sets/src/mage/cards/b/BoundDetermined.java
index 09c349f5d76..f218090357f 100644
--- a/Mage.Sets/src/mage/cards/b/BoundDetermined.java
+++ b/Mage.Sets/src/mage/cards/b/BoundDetermined.java
@@ -81,7 +81,7 @@ class BoundEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, new FilterControlledCreaturePermanent("a creature (to sacrifice)"), true);
- if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
+ if (target.canChoose(controller.getId(), source, game)) {
if (controller.chooseTarget(outcome, target, source, game)) {
Permanent toSacrifice = game.getPermanent(target.getFirstTarget());
if (toSacrifice != null) {
@@ -126,7 +126,7 @@ class DeterminedEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject != null) {
return "This spell can't be countered (" + sourceObject.getIdName() + ").";
}
diff --git a/Mage.Sets/src/mage/cards/b/BountifulHarvest.java b/Mage.Sets/src/mage/cards/b/BountifulHarvest.java
index 9b9a4af9a00..69370f5a64b 100644
--- a/Mage.Sets/src/mage/cards/b/BountifulHarvest.java
+++ b/Mage.Sets/src/mage/cards/b/BountifulHarvest.java
@@ -1,29 +1,26 @@
-
-
package mage.cards.b;
-import java.util.UUID;
-import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.dynamicvalue.common.LandsYouControlCount;
import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.hint.common.LandsYouControlHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterControlledLandPermanent;
-import mage.filter.common.FilterControlledPermanent;
+
+import java.util.UUID;
/**
* @author Loki
*/
public final class BountifulHarvest extends CardImpl {
- private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
-
public BountifulHarvest(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}");
// You gain 1 life for each land you control.
- this.getSpellAbility().addEffect(new GainLifeEffect(new PermanentsOnBattlefieldCount(filter)));
+ this.getSpellAbility().addEffect(new GainLifeEffect(LandsYouControlCount.instance)
+ .setText("you gain 1 life for each land you control"));
+ this.getSpellAbility().addHint(LandsYouControlHint.instance);
}
private BountifulHarvest(final BountifulHarvest card) {
@@ -34,5 +31,4 @@ public final class BountifulHarvest extends CardImpl {
public BountifulHarvest copy() {
return new BountifulHarvest(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/b/BountyOfTheHunt.java b/Mage.Sets/src/mage/cards/b/BountyOfTheHunt.java
index 16aeceb2d3b..6def70de482 100644
--- a/Mage.Sets/src/mage/cards/b/BountyOfTheHunt.java
+++ b/Mage.Sets/src/mage/cards/b/BountyOfTheHunt.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.ExileFromHandCost;
@@ -11,29 +9,35 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.common.FilterOwnedCard;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreaturePermanentAmount;
+import java.util.UUID;
+
/**
- *
* @author LoneFox
*/
public final class BountyOfTheHunt extends CardImpl {
+ private static final FilterOwnedCard filter
+ = new FilterOwnedCard("a green card from your hand");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.GREEN));
+ }
+
public BountyOfTheHunt(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}{G}");
// You may exile a green card from your hand rather than pay Bounty of the Hunt's mana cost.
- FilterOwnedCard filter = new FilterOwnedCard("green card from your hand");
- filter.add(new ColorPredicate(ObjectColor.GREEN));
- filter.add(Predicates.not(new CardIdPredicate(this.getId()))); // the exile cost can never be paid with the card itself
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter))));
// Distribute three +1/+1 counters among one, two, or three target creatures. For each +1/+1 counter you put on a creature this way, remove a +1/+1 counter from that creature at the beginning of the next cleanup step.
- this.getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.P1P1, 3, true, "one, two, or three target creatures"));
+ this.getSpellAbility().addEffect(new DistributeCountersEffect(
+ CounterType.P1P1, 3, true,
+ "one, two, or three target creatures"
+ ));
this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(3));
}
diff --git a/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java b/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java
index 29297c7beb5..6725f4af51d 100644
--- a/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java
+++ b/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java
@@ -26,9 +26,10 @@ public final class BountyOfTheLuxa extends CardImpl {
public BountyOfTheLuxa(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{U}");
- //At the beginning of your precombat main phase, remove all flood counters from Bounty of the Luxa. If no counters were removed this way, put a flood counter on Bounty of the Luxa and draw a card. Otherwise, add {C}{G}{U}.
+ // At the beginning of your precombat main phase, remove all flood counters from Bounty of the Luxa.
+ // If no counters were removed this way, put a flood counter on Bounty of the Luxa and draw a card.
+ // Otherwise, add {C}{G}{U}.
this.addAbility(new BeginningOfPreCombatMainTriggeredAbility(new BountyOfTheLuxaEffect(), TargetController.YOU, false));
-
}
private BountyOfTheLuxa(final BountyOfTheLuxa card) {
@@ -46,7 +47,9 @@ class BountyOfTheLuxaEffect extends OneShotEffect {
public BountyOfTheLuxaEffect() {
super(Outcome.Benefit);
- staticText = "remove all flood counters from {this}. If no counters were removed this way, put a flood counter on {this} and draw a card. Otherwise, add {C}{G}{U}";
+ staticText = "remove all flood counters from {this}. " +
+ "If no counters were removed this way, put a flood counter on {this} and draw a card. " +
+ "Otherwise, add {C}{G}{U}";
}
public BountyOfTheLuxaEffect(final BountyOfTheLuxaEffect effect) {
@@ -65,26 +68,25 @@ class BountyOfTheLuxaEffect extends OneShotEffect {
if (bountyOfLuxa != null && bountyOfLuxa.getZoneChangeCounter(game) != source.getSourceObjectZoneChangeCounter()) {
bountyOfLuxa = null;
}
- if (controller != null) {
- if (bountyOfLuxa != null
- && bountyOfLuxa.getCounters(game).getCount(CounterType.FLOOD) > 0) {
- bountyOfLuxa.removeCounters(CounterType.FLOOD.createInstance(bountyOfLuxa.getCounters(game).getCount(CounterType.FLOOD)), source, game);
- if (bountyOfLuxa.getCounters(game).getCount(CounterType.FLOOD) == 0) {
- Mana manaToAdd = new Mana();
- manaToAdd.increaseColorless();
- manaToAdd.increaseGreen();
- manaToAdd.increaseBlue();
- controller.getManaPool().addMana(manaToAdd, game, source);
- }
- } else {
- if (bountyOfLuxa != null) {
- new AddCountersSourceEffect(CounterType.FLOOD.createInstance()).apply(game, source);
- }
- controller.drawCards(1, source, game);
+ if (controller == null) { return false; }
+
+ if (bountyOfLuxa != null
+ && bountyOfLuxa.getCounters(game).getCount(CounterType.FLOOD) > 0) {
+ bountyOfLuxa.removeCounters(CounterType.FLOOD.createInstance(bountyOfLuxa.getCounters(game).getCount(CounterType.FLOOD)), source, game);
+ if (bountyOfLuxa.getCounters(game).getCount(CounterType.FLOOD) == 0) {
+ Mana manaToAdd = new Mana();
+ manaToAdd.increaseColorless();
+ manaToAdd.increaseGreen();
+ manaToAdd.increaseBlue();
+ controller.getManaPool().addMana(manaToAdd, game, source);
}
- return true;
+ } else {
+ if (bountyOfLuxa != null) {
+ new AddCountersSourceEffect(CounterType.FLOOD.createInstance()).apply(game, source);
+ }
+ controller.drawCards(1, source, game);
}
- return false;
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BowOfNylea.java b/Mage.Sets/src/mage/cards/b/BowOfNylea.java
index c5ad23462ea..486ad38298d 100644
--- a/Mage.Sets/src/mage/cards/b/BowOfNylea.java
+++ b/Mage.Sets/src/mage/cards/b/BowOfNylea.java
@@ -48,17 +48,14 @@ public final class BowOfNylea extends CardImpl {
ability.addTarget(new TargetCreaturePermanent());
ability.addCost(new TapSourceCost());
// or Bow of Nylea deals 2 damage to target creature with flying;
- Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(2));
+ Mode mode = new Mode(new DamageTargetEffect(2));
mode.addTarget(new TargetCreaturePermanent(filterFlying));
ability.addMode(mode);
// or you gain 3 life;
- mode = new Mode();
- mode.addEffect(new GainLifeEffect(3));
+ mode = new Mode(new GainLifeEffect(3));
ability.addMode(mode);
// or put up to four target cards from your graveyard on the bottom of your library in any order.
- mode = new Mode();
- mode.addEffect(new PutOnLibraryTargetEffect(false, "put up to four target cards from your graveyard on the bottom of your library in any order"));
+ mode = new Mode(new PutOnLibraryTargetEffect(false, "put up to four target cards from your graveyard on the bottom of your library in any order"));
mode.addTarget(new TargetCardInYourGraveyard(0, 4, StaticFilters.FILTER_CARDS_FROM_YOUR_GRAVEYARD));
ability.addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/b/BoxingRing.java b/Mage.Sets/src/mage/cards/b/BoxingRing.java
new file mode 100644
index 00000000000..60fe7e037fc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BoxingRing.java
@@ -0,0 +1,165 @@
+package mage.cards.b;
+
+import mage.MageObject;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.decorator.ConditionalActivatedAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.WatcherScope;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.TreasureToken;
+import mage.target.TargetPermanent;
+import mage.watchers.Watcher;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BoxingRing extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creature you don't control with the same mana value");
+
+ static {
+ filter.add(BoxingRingPredicate.instance);
+ }
+
+ public BoxingRing(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{G}");
+
+ // Whenever a creature enters the battlefield under your control, it fights up to one target creature you don't control with the same mana value.
+ Ability ability = new EntersBattlefieldControlledTriggeredAbility(
+ new BoxingRingFightEffect(), StaticFilters.FILTER_PERMANENT_A_CREATURE
+ );
+ ability.addTarget(new TargetPermanent(0, 1, filter));
+ this.addAbility(ability);
+
+ // {T}: Create a Treasure token. Activate only if you control a creature that fought this turn.
+ this.addAbility(new ConditionalActivatedAbility(
+ Zone.BATTLEFIELD, new CreateTokenEffect(new TreasureToken()),
+ new TapSourceCost(), BoxingRingCondition.instance
+ ), new BoxingRingWatcher());
+ }
+
+ private BoxingRing(final BoxingRing card) {
+ super(card);
+ }
+
+ @Override
+ public BoxingRing copy() {
+ return new BoxingRing(this);
+ }
+}
+
+enum BoxingRingPredicate implements ObjectSourcePlayerPredicate {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ return input
+ .getObject()
+ .getManaValue()
+ == input
+ .getSource()
+ .getEffects()
+ .stream()
+ .map(effect -> effect.getValue("permanentEnteringBattlefield"))
+ .map(Permanent.class::cast)
+ .filter(Objects::nonNull)
+ .map(MageObject::getManaValue)
+ .findFirst()
+ .orElse(-1);
+ }
+}
+
+class BoxingRingFightEffect extends OneShotEffect {
+
+ BoxingRingFightEffect() {
+ super(Outcome.Benefit);
+ staticText = "it fights up to one target creature you don't control with the same mana value";
+ }
+
+ private BoxingRingFightEffect(final BoxingRingFightEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BoxingRingFightEffect copy() {
+ return new BoxingRingFightEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = (Permanent) getValue("permanentEnteringBattlefield");
+ Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
+ return permanent != null && creature != null && permanent.fight(creature, source, game);
+ }
+}
+
+enum BoxingRingCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return BoxingRingWatcher.checkPlayer(source.getControllerId(), game);
+ }
+
+ @Override
+ public String toString() {
+ return "you control a creature that fought this turn";
+ }
+}
+
+class BoxingRingWatcher extends Watcher {
+
+ private final Set morSet = new HashSet<>();
+
+ BoxingRingWatcher() {
+ super(WatcherScope.GAME);
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() == GameEvent.EventType.FIGHTED_PERMANENT) {
+ morSet.add(new MageObjectReference(game.getPermanent(event.getTargetId()), game));
+ }
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ morSet.clear();
+ }
+
+ static boolean checkPlayer(UUID playerId, Game game) {
+ return game
+ .getState()
+ .getWatcher(BoxingRingWatcher.class)
+ .morSet
+ .stream()
+ .filter(mor -> mor.zoneCounterIsCurrent(game))
+ .map(MageObjectReference::getSourceId)
+ .map(game::getControllerId)
+ .anyMatch(playerId::equals);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BraceForImpact.java b/Mage.Sets/src/mage/cards/b/BraceForImpact.java
index 63e33ff0552..cf43d37fb21 100644
--- a/Mage.Sets/src/mage/cards/b/BraceForImpact.java
+++ b/Mage.Sets/src/mage/cards/b/BraceForImpact.java
@@ -72,24 +72,23 @@ class BraceForImpactPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
- if (!game.replaceEvent(preventEvent)) {
- int prevented = 0;
- int damage = event.getAmount();
- event.setAmount(0);
- game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
- prevented = damage;
+ if (game.replaceEvent(preventEvent)) { return false; }
+ int prevented;
+ int damage = event.getAmount();
+ event.setAmount(0);
+ game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
+ prevented = damage;
- // add counters now
- if (prevented > 0) {
- Permanent targetPermanent = game.getPermanent(source.getTargets().getFirstTarget());
- if (targetPermanent != null) {
- targetPermanent.addCounters(CounterType.P1P1.createInstance(prevented), source.getControllerId(), source, game);
- game.informPlayers("Brace for Impact: Prevented " + prevented + " damage ");
- game.informPlayers("Brace for Impact: Adding " + prevented + " +1/+1 counters to " + targetPermanent.getName());
- }
+ // add counters now
+ if (prevented > 0) {
+ Permanent targetPermanent = game.getPermanent(source.getTargets().getFirstTarget());
+ if (targetPermanent != null) {
+ targetPermanent.addCounters(CounterType.P1P1.createInstance(prevented), source.getControllerId(), source, game);
+ game.informPlayers("Brace for Impact: Prevented " + prevented + " damage ");
+ game.informPlayers("Brace for Impact: Adding " + prevented + " +1/+1 counters to " + targetPermanent.getName());
}
}
- return false;
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BrackwaterElemental.java b/Mage.Sets/src/mage/cards/b/BrackwaterElemental.java
index 99c585ef54f..4b1b1dc4b98 100644
--- a/Mage.Sets/src/mage/cards/b/BrackwaterElemental.java
+++ b/Mage.Sets/src/mage/cards/b/BrackwaterElemental.java
@@ -1,41 +1,38 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.SacrificeTargetEffect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.keyword.UnearthAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class BrackwaterElemental extends CardImpl {
public BrackwaterElemental(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When Brackwater Elemental attacks or blocks, sacrifice it at the beginning of the next end step.
- this.addAbility(new AttacksOrBlocksTriggeredAbility(new BrackwaterElementalSacrificeEffect(), false));
+ this.addAbility(new AttacksOrBlocksTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(
+ new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect())
+ ).setText("sacrifice it at the beginning of the next end step"), false).setTriggerPhrase("When {this} attacks or blocks, "));
+
// Unearth {2}{U}
- this.addAbility(new UnearthAbility(new ManaCostsImpl("{2}{U}")));
+ this.addAbility(new UnearthAbility(new ManaCostsImpl<>("{2}{U}")));
}
private BrackwaterElemental(final BrackwaterElemental card) {
@@ -47,31 +44,3 @@ public final class BrackwaterElemental extends CardImpl {
return new BrackwaterElemental(this);
}
}
-
-class BrackwaterElementalSacrificeEffect extends OneShotEffect {
-
- public BrackwaterElementalSacrificeEffect() {
- super(Outcome.Sacrifice);
- this.staticText = "sacrifice it at the beginning of the next end step";
- }
-
- public BrackwaterElementalSacrificeEffect(final BrackwaterElementalSacrificeEffect effect) {
- super(effect);
- }
-
- @Override
- public BrackwaterElementalSacrificeEffect copy() {
- return new BrackwaterElementalSacrificeEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent sourcePermanent = game.getPermanent(source.getSourceId());
- if (sourcePermanent != null) {
- SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice {this}");
- sacrificeEffect.setTargetPointer(new FixedTarget(sourcePermanent.getId(), game));
- game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect), source);
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BrainGorgers.java b/Mage.Sets/src/mage/cards/b/BrainGorgers.java
index 35ba29de4ff..0f9842996af 100644
--- a/Mage.Sets/src/mage/cards/b/BrainGorgers.java
+++ b/Mage.Sets/src/mage/cards/b/BrainGorgers.java
@@ -37,7 +37,7 @@ public final class BrainGorgers extends CardImpl {
this.addAbility(new CastSourceTriggeredAbility(new BrainGorgersCounterSourceEffect()));
// Madness {1}{B}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl<>("{1}{B}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{1}{B}")));
}
private BrainGorgers(final BrainGorgers card) {
diff --git a/Mage.Sets/src/mage/cards/b/BrainInAJar.java b/Mage.Sets/src/mage/cards/b/BrainInAJar.java
index f2362fcefd7..c383abea1fa 100644
--- a/Mage.Sets/src/mage/cards/b/BrainInAJar.java
+++ b/Mage.Sets/src/mage/cards/b/BrainInAJar.java
@@ -1,7 +1,5 @@
package mage.cards.b;
-import java.util.UUID;
-import mage.ApprovingObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
@@ -10,13 +8,11 @@ import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
-import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.common.FilterInstantOrSorceryCard;
@@ -24,10 +20,11 @@ import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
-import mage.target.common.TargetCardInHand;
+import mage.util.CardUtil;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class BrainInAJar extends CardImpl {
@@ -39,20 +36,17 @@ public final class BrainInAJar extends CardImpl {
// cast an instant or sorcery card with converted mana costs equal
// to the number of charge counters on Brain in a Jar from your
// hand without paying its mana cost.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new AddCountersSourceEffect(CounterType.CHARGE.createInstance()),
- new GenericManaCost(1));
+ Ability ability = new SimpleActivatedAbility(
+ new AddCountersSourceEffect(CounterType.CHARGE.createInstance()), new GenericManaCost(1)
+ );
ability.addEffect(new BrainInAJarCastEffect());
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {3}, {T}, Remove X charge counters from Brain in a Jar: Scry X.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new BrainInAJarScryEffect(),
- new GenericManaCost(3));
+ ability = new SimpleActivatedAbility(new BrainInAJarScryEffect(), new GenericManaCost(3));
ability.addCost(new TapSourceCost());
- ability.addCost(new RemoveVariableCountersSourceCost(
- CounterType.CHARGE.createInstance()));
+ ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance()));
this.addAbility(ability);
}
@@ -87,32 +81,14 @@ class BrainInAJarCastEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (controller != null
- && sourceObject != null) {
- int counters = sourceObject.getCounters(game).getCount(CounterType.CHARGE);
- FilterCard filter = new FilterInstantOrSorceryCard();
- filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, counters));
- int cardsToCast = controller.getHand().count(filter, source.getControllerId(),
- source.getSourceId(), game);
- if (cardsToCast > 0
- && controller.chooseUse(Outcome.PlayForFree,
- "Cast an instant or sorcery card with mana values of "
- + counters + " from your hand without paying its mana cost?",
- source, game)) {
- TargetCardInHand target = new TargetCardInHand(filter);
- controller.chooseTarget(outcome, target, source, game);
- Card card = game.getCard(target.getFirstTarget());
- if (card != null) {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- controller.cast(controller.chooseAbilityForCast(card, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- }
- }
- return true;
+ Permanent sourceObject = source.getSourcePermanentOrLKI(game);
+ if (controller == null || sourceObject == null) {
+ return false;
}
- return false;
+ int counters = sourceObject.getCounters(game).getCount(CounterType.CHARGE);
+ FilterCard filter = new FilterInstantOrSorceryCard();
+ filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, counters));
+ return CardUtil.castSpellWithAttributesForFree(controller, source, game, controller.getHand(), filter);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BrainPry.java b/Mage.Sets/src/mage/cards/b/BrainPry.java
index cc8eb1e4bdd..1d1e4475fa8 100644
--- a/Mage.Sets/src/mage/cards/b/BrainPry.java
+++ b/Mage.Sets/src/mage/cards/b/BrainPry.java
@@ -55,7 +55,7 @@ class BrainPryEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (targetPlayer != null && controller != null && sourceObject != null && cardName != null) {
boolean hasDiscarded = false;
diff --git a/Mage.Sets/src/mage/cards/b/BrambleCreeper.java b/Mage.Sets/src/mage/cards/b/BrambleCreeper.java
index 1a83109712b..d73292b1387 100644
--- a/Mage.Sets/src/mage/cards/b/BrambleCreeper.java
+++ b/Mage.Sets/src/mage/cards/b/BrambleCreeper.java
@@ -24,7 +24,7 @@ public final class BrambleCreeper extends CardImpl {
this.power = new MageInt(0);
this.toughness = new MageInt(3);
// Whenever Bramble Creeper attacks, it gets +5/+0 until end of turn.
- this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(5, 0, Duration.EndOfTurn), false));
+ this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(5, 0, Duration.EndOfTurn).setText("it gets +5/+0 until end of turn"), false));
}
private BrambleCreeper(final BrambleCreeper card) {
diff --git a/Mage.Sets/src/mage/cards/b/Bramblesnap.java b/Mage.Sets/src/mage/cards/b/Bramblesnap.java
index 94ce24eab1d..a9a4a40b2b4 100644
--- a/Mage.Sets/src/mage/cards/b/Bramblesnap.java
+++ b/Mage.Sets/src/mage/cards/b/Bramblesnap.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapTargetCost;
@@ -13,16 +11,27 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.target.common.TargetControlledCreaturePermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
/**
- *
* @author North
*/
public final class Bramblesnap extends CardImpl {
+ private static final FilterControlledPermanent filter
+ = new FilterControlledCreaturePermanent("untapped creature you control");
+
+ static {
+ filter.add(TappedPredicate.UNTAPPED);
+ }
+
public Bramblesnap(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(1);
@@ -31,7 +40,7 @@ public final class Bramblesnap extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
new BoostSourceEffect(1, 1, Duration.EndOfTurn),
- new TapTargetCost(new TargetControlledCreaturePermanent())));
+ new TapTargetCost(new TargetControlledPermanent(filter))));
}
private Bramblesnap(final Bramblesnap card) {
diff --git a/Mage.Sets/src/mage/cards/b/BranchingBolt.java b/Mage.Sets/src/mage/cards/b/BranchingBolt.java
index f1a9e0dac28..3c6497eae72 100644
--- a/Mage.Sets/src/mage/cards/b/BranchingBolt.java
+++ b/Mage.Sets/src/mage/cards/b/BranchingBolt.java
@@ -41,8 +41,7 @@ public final class BranchingBolt extends CardImpl {
this.getSpellAbility().addEffect(new DamageTargetEffect(3));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filterFlying).withChooseHint("deals 3 damage, without flying"));
// or Branching Bolt deals 3 damage to target creature without flying.
- Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(3));
+ Mode mode = new Mode(new DamageTargetEffect(3));
mode.addTarget(new TargetCreaturePermanent(filterNotFlying).withChooseHint("deals 3 damage, without flying"));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/b/BranchsnapLorian.java b/Mage.Sets/src/mage/cards/b/BranchsnapLorian.java
index 08a23e8dc2f..35a0ffef142 100644
--- a/Mage.Sets/src/mage/cards/b/BranchsnapLorian.java
+++ b/Mage.Sets/src/mage/cards/b/BranchsnapLorian.java
@@ -26,7 +26,7 @@ public final class BranchsnapLorian extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// Morph {G}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{G}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{G}")));
}
private BranchsnapLorian(final BranchsnapLorian card) {
diff --git a/Mage.Sets/src/mage/cards/b/BrandOfIllOmen.java b/Mage.Sets/src/mage/cards/b/BrandOfIllOmen.java
index 7cfb2e6c03e..a676d10bcce 100644
--- a/Mage.Sets/src/mage/cards/b/BrandOfIllOmen.java
+++ b/Mage.Sets/src/mage/cards/b/BrandOfIllOmen.java
@@ -78,7 +78,7 @@ class BrandOfIllOmenEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't cast creature spells (" + mageObject.getLogName() + " on the battlefield).";
}
diff --git a/Mage.Sets/src/mage/cards/b/BrashTaunter.java b/Mage.Sets/src/mage/cards/b/BrashTaunter.java
index ca83be0f181..56703a2d804 100644
--- a/Mage.Sets/src/mage/cards/b/BrashTaunter.java
+++ b/Mage.Sets/src/mage/cards/b/BrashTaunter.java
@@ -6,20 +6,17 @@ import mage.abilities.common.DealtDamageToSourceTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
+import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.FightTargetSourceEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
-import mage.game.Game;
-import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetOpponent;
@@ -48,15 +45,15 @@ public final class BrashTaunter extends CardImpl {
this.addAbility(IndestructibleAbility.getInstance());
// Whenever Brash Taunter is dealt damage, it deals that much damage to target opponent.
- Ability ability = new DealtDamageToSourceTriggeredAbility(new BrashTaunterEffect(), false, false);
+ Ability ability = new DealtDamageToSourceTriggeredAbility(new DamageTargetEffect(SavedDamageValue.MUCH, "it"), false);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
// {2}{R}, {T}: Brash Taunter fights another target creature.
- Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new FightTargetSourceEffect(), new ManaCostsImpl("{2}{R}"));
- ability1.addCost(new TapSourceCost());
- ability1.addTarget(new TargetPermanent(filter));
- this.addAbility(ability1);
+ ability = new SimpleActivatedAbility(new FightTargetSourceEffect(), new ManaCostsImpl("{2}{R}"));
+ ability.addCost(new TapSourceCost());
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
}
private BrashTaunter(final BrashTaunter card) {
@@ -68,33 +65,3 @@ public final class BrashTaunter extends CardImpl {
return new BrashTaunter(this);
}
}
-
-class BrashTaunterEffect extends OneShotEffect {
-
- public BrashTaunterEffect() {
- super(Outcome.Damage);
- this.staticText = "it deals that much damage to target opponent";
- }
-
- public BrashTaunterEffect(final BrashTaunterEffect effect) {
- super(effect);
- }
-
- @Override
- public BrashTaunterEffect copy() {
- return new BrashTaunterEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- int amount = (Integer) getValue("damage");
- if (amount > 0) {
- Player player = game.getPlayer(targetPointer.getFirst(game, source));
- if (player != null) {
- player.damage(amount, source.getSourceId(), source, game);
- return true;
- }
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BrassKnuckles.java b/Mage.Sets/src/mage/cards/b/BrassKnuckles.java
new file mode 100644
index 00000000000..9e6dbc2839e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrassKnuckles.java
@@ -0,0 +1,81 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.CastSourceTriggeredAbility;
+import mage.abilities.effects.common.CopySourceSpellEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.DoubleStrikeAbility;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+/**
+ * @author TheElk801
+ */
+public final class BrassKnuckles extends CardImpl {
+
+ public BrassKnuckles(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // When you cast this spell, copy it.
+ this.addAbility(new CastSourceTriggeredAbility(new CopySourceSpellEffect().setText("copy it")));
+
+ // Equipped creature has double strike as long as two or more Equipment are attached to it.
+ this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new GainAbilityAttachedEffect(
+ DoubleStrikeAbility.getInstance(), AttachmentType.EQUIPMENT
+ ), BrassKnucklesCondition.instance, "equipped creature has double strike " +
+ "as long as two or more Equipment are attached to it"
+ )));
+
+ // Equip {1}
+ this.addAbility(new EquipAbility(1));
+ }
+
+ private BrassKnuckles(final BrassKnuckles card) {
+ super(card);
+ }
+
+ @Override
+ public BrassKnuckles copy() {
+ return new BrassKnuckles(this);
+ }
+}
+
+enum BrassKnucklesCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return Optional
+ .of(source.getSourcePermanentIfItStillExists(game))
+ .filter(Objects::nonNull)
+ .map(Permanent::getAttachedTo)
+ .map(game::getPermanent)
+ .filter(Objects::nonNull)
+ .map(Permanent::getAttachments)
+ .map(Collection::stream)
+ .map(stream -> stream.map(game::getPermanent))
+ .map(stream -> stream.filter(Objects::nonNull))
+ .map(stream -> stream.filter(p -> p.hasSubtype(SubType.EQUIPMENT, game)))
+ .map(Stream::count)
+ .map(x -> x >= 2)
+ .orElse(false);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/Bravado.java b/Mage.Sets/src/mage/cards/b/Bravado.java
index 60493c8cce2..0f96ef39fe5 100644
--- a/Mage.Sets/src/mage/cards/b/Bravado.java
+++ b/Mage.Sets/src/mage/cards/b/Bravado.java
@@ -68,7 +68,7 @@ class BravadoBoostEnchantedEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
- int count = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) - 1;
+ int count = game.getBattlefield().count(filter, source.getControllerId(), source, game) - 1;
if (count > 0) {
Permanent enchantment = game.getPermanent(source.getSourceId());
if (enchantment != null && enchantment.getAttachedTo() != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BrawlersPlate.java b/Mage.Sets/src/mage/cards/b/BrawlersPlate.java
index a951d96bea2..1e65814a8ff 100644
--- a/Mage.Sets/src/mage/cards/b/BrawlersPlate.java
+++ b/Mage.Sets/src/mage/cards/b/BrawlersPlate.java
@@ -4,7 +4,7 @@ package mage.cards.b;
import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
-import mage.abilities.effects.Effect;
+import mage.abilities.Ability;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EquipAbility;
@@ -23,14 +23,10 @@ public final class BrawlersPlate extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
this.subtype.add(SubType.EQUIPMENT);
- // Equipped creature gets +2/+2
- Effect effect = new BoostEquippedEffect(2, 2);
- effect.setText("Equipped creature gets +2/+2");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
- // and has trample.
- effect = new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.EQUIPMENT);
- effect.setText("and has trample");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ // Equipped creature gets +2/+2 and has trample
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2));
+ ability.addEffect(new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has trample"));
+ this.addAbility(ability);
// Equip {4}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4)));
diff --git a/Mage.Sets/src/mage/cards/b/BrazenUpstart.java b/Mage.Sets/src/mage/cards/b/BrazenUpstart.java
new file mode 100644
index 00000000000..2d6b63d5b15
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrazenUpstart.java
@@ -0,0 +1,45 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.DiesSourceTriggeredAbility;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrazenUpstart extends CardImpl {
+
+ public BrazenUpstart(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}{W}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.SHAMAN);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // When Brazen Upstart dies, look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+ this.addAbility(new DiesSourceTriggeredAbility(new LookLibraryAndPickControllerEffect(
+ 5, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM)));
+ }
+
+ private BrazenUpstart(final BrazenUpstart card) {
+ super(card);
+ }
+
+ @Override
+ public BrazenUpstart copy() {
+ return new BrazenUpstart(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BreachingLeviathan.java b/Mage.Sets/src/mage/cards/b/BreachingLeviathan.java
index 771bcb9febc..9a42d85e5de 100644
--- a/Mage.Sets/src/mage/cards/b/BreachingLeviathan.java
+++ b/Mage.Sets/src/mage/cards/b/BreachingLeviathan.java
@@ -82,7 +82,7 @@ class BreachingLeviathanEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
List doNotUntapNextUntapStep = new ArrayList<>();
- for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
creature.tap(source, game);
doNotUntapNextUntapStep.add(creature);
}
diff --git a/Mage.Sets/src/mage/cards/b/BreakingEntering.java b/Mage.Sets/src/mage/cards/b/BreakingEntering.java
index 6911b38c1d1..2cca2af2e2f 100644
--- a/Mage.Sets/src/mage/cards/b/BreakingEntering.java
+++ b/Mage.Sets/src/mage/cards/b/BreakingEntering.java
@@ -71,7 +71,7 @@ class EnteringReturnFromGraveyardToBattlefieldEffect extends OneShotEffect {
if (controller != null) {
Target target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE);
target.setNotTarget(true);
- if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
+ if (target.canChoose(source.getControllerId(), source, game)
&& controller.chooseTarget(outcome, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BreakingPoint.java b/Mage.Sets/src/mage/cards/b/BreakingPoint.java
index 717cd509807..29efe1f3e33 100644
--- a/Mage.Sets/src/mage/cards/b/BreakingPoint.java
+++ b/Mage.Sets/src/mage/cards/b/BreakingPoint.java
@@ -78,7 +78,7 @@ class BreakingPointDestroyEffect extends OneShotEffect {
}
}
if (destroyCreatures) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(FILTER_PERMANENT_CREATURES, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(FILTER_PERMANENT_CREATURES, source.getControllerId(), source, game)) {
permanent.destroy(source, game, true);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BreakingWave.java b/Mage.Sets/src/mage/cards/b/BreakingWave.java
index f66663ea5b1..bb1e3aaae88 100644
--- a/Mage.Sets/src/mage/cards/b/BreakingWave.java
+++ b/Mage.Sets/src/mage/cards/b/BreakingWave.java
@@ -64,7 +64,7 @@ class BreakingWaveEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
List creatures = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE,
- source.getControllerId(), source.getSourceId(), game);
+ source.getControllerId(), source, game);
for (Permanent creature : creatures) {
if (creature.isTapped()) {
creature.untap(game);
diff --git a/Mage.Sets/src/mage/cards/b/Breakthrough.java b/Mage.Sets/src/mage/cards/b/Breakthrough.java
index 09806be9f12..62bc8b18ae6 100644
--- a/Mage.Sets/src/mage/cards/b/Breakthrough.java
+++ b/Mage.Sets/src/mage/cards/b/Breakthrough.java
@@ -68,7 +68,7 @@ class BreakthroughEffect extends OneShotEffect {
} else if (amountToKeep < player.getHand().size()) {
TargetCardInHand target = new TargetCardInHand(amountToKeep, new FilterCard());
target.setTargetName("cards to keep");
- target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game);
+ target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), source, game);
Cards cards = player.getHand().copy();
cards.removeIf(target.getTargets()::contains);
player.discard(cards, false, source, game);
diff --git a/Mage.Sets/src/mage/cards/b/BreathOfFury.java b/Mage.Sets/src/mage/cards/b/BreathOfFury.java
index cf437b32809..061eb9e8382 100644
--- a/Mage.Sets/src/mage/cards/b/BreathOfFury.java
+++ b/Mage.Sets/src/mage/cards/b/BreathOfFury.java
@@ -16,7 +16,6 @@ import mage.filter.predicate.permanent.CanBeEnchantedByPredicate;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.turn.TurnMod;
import mage.players.Player;
@@ -130,8 +129,8 @@ class BreathOfFuryEffect extends OneShotEffect {
// Commanders going to the command zone and Rest in Peace style replacement effects don't make Permanent.sacrifice return false.
if (enchantedCreature != null && controller != null
&& enchantedCreature.sacrifice(source, game)
- && target.canChoose(source.getSourceId(), controller.getId(), game)) {
- controller.choose(outcome, target, source.getSourceId(), game);
+ && target.canChoose(controller.getId(), source, game)) {
+ controller.choose(outcome, target, source, game);
Permanent newCreature = game.getPermanent(target.getFirstTarget());
boolean success = false;
if (newCreature != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BreenaTheDemagogue.java b/Mage.Sets/src/mage/cards/b/BreenaTheDemagogue.java
index 6f3192bfd0c..5849e71eafd 100644
--- a/Mage.Sets/src/mage/cards/b/BreenaTheDemagogue.java
+++ b/Mage.Sets/src/mage/cards/b/BreenaTheDemagogue.java
@@ -125,13 +125,13 @@ class BreenaTheDemagogueEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player == null || game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_CREATURE,
- source.getSourceId(), source.getControllerId(), game
+ source.getControllerId(), source, game
) < 1) {
return false;
}
TargetPermanent target = new TargetControlledCreaturePermanent();
target.setNotTarget(true);
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
return permanent != null && permanent.addCounters(
CounterType.P1P1.createInstance(2),
diff --git a/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java b/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java
index ea67f1cd8d5..664cdd4b20d 100644
--- a/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java
+++ b/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java
@@ -49,14 +49,12 @@ public final class BreyaEtheriumShaper extends CardImpl {
ability.addTarget(new TargetPlayerOrPlaneswalker());
// Target creature gets -4/-4 until end of turn.
- Mode mode = new Mode();
- mode.addEffect(new BoostTargetEffect(-4, -4, Duration.EndOfTurn));
+ Mode mode = new Mode(new BoostTargetEffect(-4, -4, Duration.EndOfTurn));
mode.addTarget(new TargetCreaturePermanent());
ability.addMode(mode);
// or You gain 5 life.
- mode = new Mode();
- mode.addEffect(new GainLifeEffect(5));
+ mode = new Mode(new GainLifeEffect(5));
ability.addMode(mode);
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BreyasApprentice.java b/Mage.Sets/src/mage/cards/b/BreyasApprentice.java
index 9110c2b6648..bc062ac069f 100644
--- a/Mage.Sets/src/mage/cards/b/BreyasApprentice.java
+++ b/Mage.Sets/src/mage/cards/b/BreyasApprentice.java
@@ -85,7 +85,7 @@ class BreyasApprenticeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller == null || sourceObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/b/BriarberryCohort.java b/Mage.Sets/src/mage/cards/b/BriarberryCohort.java
index 135b78470e5..edbe30cab86 100644
--- a/Mage.Sets/src/mage/cards/b/BriarberryCohort.java
+++ b/Mage.Sets/src/mage/cards/b/BriarberryCohort.java
@@ -35,7 +35,7 @@ public final class BriarberryCohort extends CardImpl {
filter.add(AnotherPredicate.instance);
}
- private String rule = "{this} gets +1/+1 as long as you control another blue creature";
+ private static final String rule = "{this} gets +1/+1 as long as you control another blue creature";
public BriarberryCohort(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}");
diff --git a/Mage.Sets/src/mage/cards/b/BribeTaker.java b/Mage.Sets/src/mage/cards/b/BribeTaker.java
new file mode 100644
index 00000000000..7538ac2afa5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BribeTaker.java
@@ -0,0 +1,116 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class BribeTaker extends CardImpl {
+
+ public BribeTaker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}");
+
+ this.subtype.add(SubType.RHINO);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // When Bribe Taker enters the battlefield, for each kind of counter on permanents you control, you may put your choice of a +1/+1 counter or a counter of that kind on Bribe Taker.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new BribeTakerEffect()));
+ }
+
+ private BribeTaker(final BribeTaker card) {
+ super(card);
+ }
+
+ @Override
+ public BribeTaker copy() {
+ return new BribeTaker(this);
+ }
+}
+
+class BribeTakerEffect extends OneShotEffect {
+
+ private static final String plusName = CounterType.P1P1.getName();
+
+ BribeTakerEffect() {
+ super(Outcome.Benefit);
+ staticText = "for each kind of counter on permanents you control, " +
+ "you may put your choice of a +1/+1 counter or a counter of that kind on {this}";
+ }
+
+ private BribeTakerEffect(final BribeTakerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BribeTakerEffect copy() {
+ return new BribeTakerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ Permanent permanent = source.getSourcePermanentIfItStillExists(game);
+ if (player == null || permanent == null) {
+ return false;
+ }
+ Set counterTypes = game
+ .getBattlefield()
+ .getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_CREATURE,
+ source.getControllerId(), source, game
+ ).stream()
+ .map(p -> p.getCounters(game))
+ .map(HashMap::keySet)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toSet());
+ if (counterTypes.contains(plusName)) {
+ if (player.chooseUse(outcome, "Put a " + plusName +
+ " counter on " + permanent.getName() + '?', source, game)) {
+ permanent.addCounters(CounterType.P1P1.createInstance(), source, game);
+ }
+ counterTypes.remove(plusName);
+ }
+ if (counterTypes.isEmpty()) {
+ return true;
+ }
+ for (String cType : counterTypes) {
+ if (!player.chooseUse(
+ outcome, "Put a " + cType + " counter or " + plusName +
+ " counter on " + permanent.getName() + '?', source, game
+ )) {
+ continue;
+ }
+ CounterType counterType = player.chooseUse(
+ outcome, "Choose " + cType + " counter or " + plusName +
+ " counter", null, cType, plusName, source, game
+ ) ? CounterType.findByName(cType) : CounterType.P1P1;
+ permanent.addCounters(counterType.createInstance(), source, game);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BridgeFromBelow.java b/Mage.Sets/src/mage/cards/b/BridgeFromBelow.java
index 7ec702193ba..aa737a43cc6 100644
--- a/Mage.Sets/src/mage/cards/b/BridgeFromBelow.java
+++ b/Mage.Sets/src/mage/cards/b/BridgeFromBelow.java
@@ -57,7 +57,7 @@ public final class BridgeFromBelow extends CardImpl {
class BridgeFromBelowAbility extends TriggeredAbilityImpl {
- protected FilterCreaturePermanent filter;
+ private final FilterCreaturePermanent filter;
public BridgeFromBelowAbility(Effect effect, FilterCreaturePermanent filter) {
super(Zone.GRAVEYARD, effect, false);
@@ -82,14 +82,12 @@ class BridgeFromBelowAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- if (zEvent.isDiesEvent()) {
- Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
- if (permanent != null
- && filter.match(permanent, sourceId, controllerId, game)) {
- return true;
- }
- }
- return false;
+ if (!zEvent.isDiesEvent()) { return false; }
+
+ Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
+ if (permanent == null) { return false; }
+
+ return filter.match(permanent, controllerId, this, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/Brightflame.java b/Mage.Sets/src/mage/cards/b/Brightflame.java
index cdb83cbc2f2..1b6a3054074 100644
--- a/Mage.Sets/src/mage/cards/b/Brightflame.java
+++ b/Mage.Sets/src/mage/cards/b/Brightflame.java
@@ -64,24 +64,24 @@ class BrightflameEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Permanent target = game.getPermanent(targetPointer.getFirst(game, source));
int damageDealt = 0;
- if (target != null) {
- ObjectColor color = target.getColor(game);
- damageDealt += target.damage(amount.calculate(game, source, this), source.getSourceId(), source, game);
- for (Permanent p : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
- if (!target.getId().equals(p.getId()) && p.getColor(game).shares(color)) {
- damageDealt += p.damage(amount.calculate(game, source, this), source.getSourceId(), source, game, false, true);
- }
- }
- Player you = game.getPlayer(source.getControllerId());
- if (you != null && damageDealt > 0) {
- you.gainLife(damageDealt, game, source);
+ Permanent target = game.getPermanent(targetPointer.getFirst(game, source));
+ if (target == null) { return false; }
+
+ ObjectColor color = target.getColor(game);
+ damageDealt += target.damage(amount.calculate(game, source, this), source.getSourceId(), source, game);
+ for (Permanent p : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
+ if (!target.getId().equals(p.getId()) && p.getColor(game).shares(color)) {
+ damageDealt += p.damage(amount.calculate(game, source, this), source.getSourceId(), source, game, false, true);
}
- return true;
}
- return false;
+
+ Player you = game.getPlayer(source.getControllerId());
+ if (you != null && damageDealt > 0) {
+ you.gainLife(damageDealt, game, source);
+ }
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BrightwoodTracker.java b/Mage.Sets/src/mage/cards/b/BrightwoodTracker.java
index 8f84a876eca..489ccb31177 100644
--- a/Mage.Sets/src/mage/cards/b/BrightwoodTracker.java
+++ b/Mage.Sets/src/mage/cards/b/BrightwoodTracker.java
@@ -6,11 +6,11 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
import java.util.UUID;
@@ -28,11 +28,11 @@ public final class BrightwoodTracker extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(4);
- // {5}{G}, {T}: Look at the top four cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
- Ability ability = new SimpleActivatedAbility(new LookLibraryAndPickControllerEffect(
- 4, 1, StaticFilters.FILTER_CARD_CREATURE_A,
- true, false, Zone.HAND, true
- ).setBackInRandomOrder(true), new ManaCostsImpl("{5}{G}"));
+ // {5}{G}, {T}: Look at the top four cards of your library. You may reveal a creature card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in a random order.
+ Ability ability = new SimpleActivatedAbility(
+ new LookLibraryAndPickControllerEffect(4, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM),
+ new ManaCostsImpl("{5}{G}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BrigidHeroOfKinsbaile.java b/Mage.Sets/src/mage/cards/b/BrigidHeroOfKinsbaile.java
index 4c08237e243..7191cc4db7b 100644
--- a/Mage.Sets/src/mage/cards/b/BrigidHeroOfKinsbaile.java
+++ b/Mage.Sets/src/mage/cards/b/BrigidHeroOfKinsbaile.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -6,15 +5,12 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.common.FilterAttackingOrBlockingCreature;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
+import mage.filter.StaticFilters;
import mage.target.TargetPlayer;
/**
@@ -35,10 +31,11 @@ public final class BrigidHeroOfKinsbaile extends CardImpl {
this.addAbility(FirstStrikeAbility.getInstance());
// {T}: Brigid, Hero of Kinsbaile deals 2 damage to each attacking or blocking creature target player controls.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BrigidHeroOfKinsbaileEffect(), new TapSourceCost());
+ Ability ability = new SimpleActivatedAbility(
+ new DamageAllControlledTargetEffect(2, StaticFilters.FILTER_ATTACKING_OR_BLOCKING_CREATURE),
+ new TapSourceCost());
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
-
}
private BrigidHeroOfKinsbaile(final BrigidHeroOfKinsbaile card) {
@@ -50,32 +47,3 @@ public final class BrigidHeroOfKinsbaile extends CardImpl {
return new BrigidHeroOfKinsbaile(this);
}
}
-
-class BrigidHeroOfKinsbaileEffect extends OneShotEffect {
-
- public BrigidHeroOfKinsbaileEffect() {
- super(Outcome.Damage);
- staticText = "{this} deals 2 damage to each attacking or blocking creature target player controls";
- }
-
- public BrigidHeroOfKinsbaileEffect(final BrigidHeroOfKinsbaileEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
- if (targetPlayer != null) {
- for (Permanent creature : game.getBattlefield().getAllActivePermanents(new FilterAttackingOrBlockingCreature(), targetPlayer.getId(), game)) {
- creature.damage(2, source.getSourceId(), source, game, false, true);
- }
- return true;
- }
- return false;
- }
-
- @Override
- public BrigidHeroOfKinsbaileEffect copy() {
- return new BrigidHeroOfKinsbaileEffect(this);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java
index 158bfc6d391..21308bfd4c0 100644
--- a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java
+++ b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java
@@ -59,7 +59,7 @@ class BrilliantUltimatumEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller == null || sourceObject == null) {
return false;
}
@@ -69,7 +69,7 @@ class BrilliantUltimatumEffect extends OneShotEffect {
controller.moveCardsToExile(pile2.getCards(game), source, game, true, source.getSourceId(), sourceObject.getIdName());
TargetOpponent targetOpponent = new TargetOpponent(true);
- targetOpponent.choose(outcome, source.getControllerId(), source.getSourceId(), game);
+ targetOpponent.choose(outcome, source.getControllerId(), source.getSourceId(), source, game);
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
if (opponent != null) {
TargetCard target = new TargetCard(0, pile2.size(), Zone.EXILED, new FilterCard("cards to put in the first pile"));
diff --git a/Mage.Sets/src/mage/cards/b/BrimazKingOfOreskos.java b/Mage.Sets/src/mage/cards/b/BrimazKingOfOreskos.java
index f0b431005cb..e0521d4bcc5 100644
--- a/Mage.Sets/src/mage/cards/b/BrimazKingOfOreskos.java
+++ b/Mage.Sets/src/mage/cards/b/BrimazKingOfOreskos.java
@@ -5,7 +5,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
-import mage.abilities.common.BlocksSourceTriggeredAbility;
+import mage.abilities.common.BlocksCreatureTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.VigilanceAbility;
@@ -43,7 +43,7 @@ public final class BrimazKingOfOreskos extends CardImpl {
this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect(new CatSoldierCreatureToken(), 1, false, true), false));
// Whenever Brimaz blocks a creature, create a 1/1 white Cat Soldier creature token with vigilance blocking that creature.
- this.addAbility(new BlocksSourceTriggeredAbility(new BrimazKingOfOreskosEffect(), false, true));
+ this.addAbility(new BlocksCreatureTriggeredAbility(new BrimazKingOfOreskosEffect()));
}
private BrimazKingOfOreskos(final BrimazKingOfOreskos card) {
@@ -75,31 +75,30 @@ class BrimazKingOfOreskosEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false; }
- if (controller != null) {
- Token token = new CatSoldierCreatureToken();
- token.putOntoBattlefield(1, game, source, source.getControllerId());
- Permanent attackingCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
- if (attackingCreature != null && game.getState().getCombat() != null) {
- // Possible ruling (see Aetherplasm)
- // The token you created is blocking the attacking creature,
- // even if the block couldn't legally be declared (for example, if that creature
- // enters the battlefield tapped, or it can't block, or the attacking creature
- // has protection from it)
- CombatGroup combatGroup = game.getState().getCombat().findGroup(attackingCreature.getId());
- if (combatGroup != null) {
- for (UUID tokenId : token.getLastAddedTokenIds()) {
- Permanent catToken = game.getPermanent(tokenId);
- if (catToken != null) {
- combatGroup.addBlocker(tokenId, source.getControllerId(), game);
- game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game);
- }
- }
- combatGroup.pickBlockerOrder(attackingCreature.getControllerId(), game);
- }
- }
- return true;
+ Token token = new CatSoldierCreatureToken();
+ token.putOntoBattlefield(1, game, source, source.getControllerId());
+ Permanent attackingCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (attackingCreature == null || game.getState().getCombat() == null) { return true; }
+
+ // Possible ruling (see Aetherplasm)
+ // The token you created is blocking the attacking creature,
+ // even if the block couldn't legally be declared (for example, if that creature
+ // enters the battlefield tapped, or it can't block, or the attacking creature
+ // has protection from it)
+ CombatGroup combatGroup = game.getState().getCombat().findGroup(attackingCreature.getId());
+ if (combatGroup == null) { return true; }
+
+ for (UUID tokenId : token.getLastAddedTokenIds()) {
+ Permanent catToken = game.getPermanent(tokenId);
+ if (catToken == null) { continue; }
+
+ combatGroup.addBlocker(tokenId, source.getControllerId(), game);
+ game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game);
}
- return false;
+ combatGroup.pickBlockerOrder(attackingCreature.getControllerId(), game);
+
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BrineElemental.java b/Mage.Sets/src/mage/cards/b/BrineElemental.java
index 04bc60512b0..9089063a22c 100644
--- a/Mage.Sets/src/mage/cards/b/BrineElemental.java
+++ b/Mage.Sets/src/mage/cards/b/BrineElemental.java
@@ -32,7 +32,7 @@ public final class BrineElemental extends CardImpl {
this.toughness = new MageInt(4);
// Morph {5}{U}{U}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{U}{U}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{5}{U}{U}")));
// When Brine Elemental is turned face up, each opponent skips their next untap step.
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new BrineElementalEffect()));
diff --git a/Mage.Sets/src/mage/cards/b/BrineHag.java b/Mage.Sets/src/mage/cards/b/BrineHag.java
index fde66fdf7a9..af7b561d760 100644
--- a/Mage.Sets/src/mage/cards/b/BrineHag.java
+++ b/Mage.Sets/src/mage/cards/b/BrineHag.java
@@ -68,26 +68,27 @@ class BrineHagEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false; }
+
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (sourcePermanent != null) {
- List list = new ArrayList<>();
- for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
- Player player = game.getPlayer(playerId);
- if (player != null) {
- for (Permanent creature : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game)) {
- if (sourcePermanent.getDealtDamageByThisTurn().contains(new MageObjectReference(creature.getId(), game))) {
- list.add(creature);
- }
- }
+ if (sourcePermanent == null) { return false; }
+
+ List list = new ArrayList<>();
+ for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
+ Player player = game.getPlayer(playerId);
+ if (player == null) { continue; }
+
+ for (Permanent creature : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game)) {
+ if (sourcePermanent.getDealtDamageByThisTurn().contains(new MageObjectReference(creature.getId(), game))) {
+ list.add(creature);
}
}
- if (!list.isEmpty()) {
- FilterCreaturePermanent filter = new FilterCreaturePermanent();
- filter.add(new PermanentInListPredicate(list));
- game.addEffect(new SetPowerToughnessAllEffect(0, 2, Duration.Custom, filter, true), source);
- }
- return true;
}
- return false;
+ if (!list.isEmpty()) {
+ FilterCreaturePermanent filter = new FilterCreaturePermanent();
+ filter.add(new PermanentInListPredicate(list));
+ game.addEffect(new SetPowerToughnessAllEffect(0, 2, Duration.Custom, filter, true), source);
+ }
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BringToLight.java b/Mage.Sets/src/mage/cards/b/BringToLight.java
index 5e229d42f1c..795f1e95e7f 100644
--- a/Mage.Sets/src/mage/cards/b/BringToLight.java
+++ b/Mage.Sets/src/mage/cards/b/BringToLight.java
@@ -1,23 +1,21 @@
package mage.cards.b;
-import java.util.UUID;
-import mage.ApprovingObject;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.ColorsOfManaSpentToCastCount;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.ComparisonType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
+import mage.util.CardUtil;
+
+import java.util.UUID;
/**
* @author LevelX2
@@ -31,6 +29,7 @@ public final class BringToLight extends CardImpl {
// cost less than or equal to the number of colors of mana spent to cast Bring to Light, exile that card,
// then shuffle your library. You may cast that card without paying its mana cost.
this.getSpellAbility().addEffect(new BringToLightEffect());
+ this.getSpellAbility().setAbilityWord(AbilityWord.CONVERGE);
}
private BringToLight(final BringToLight card) {
@@ -47,8 +46,8 @@ class BringToLightEffect extends OneShotEffect {
public BringToLightEffect() {
super(Outcome.PlayForFree);
- this.staticText = "Converge — Search your library for a creature, instant, or sorcery card with mana "
- + "value less than or equal to the number of colors of mana spent to cast this spell, exile that card, "
+ this.staticText = "search your library for a creature, instant, or sorcery card with mana value " +
+ "less than or equal to the number of colors of mana spent to cast this spell, exile that card, "
+ "then shuffle. You may cast that card without paying its mana cost";
}
@@ -64,31 +63,23 @@ class BringToLightEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- int numberColors = ColorsOfManaSpentToCastCount.getInstance().calculate(game, source, this);
- FilterCard filter = new FilterCard("a creature, instant, or sorcery card with mana value "
- + "less than or equal to " + numberColors);
- filter.add(Predicates.or(CardType.CREATURE.getPredicate(),
- CardType.INSTANT.getPredicate(), CardType.SORCERY.getPredicate()));
- filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, numberColors + 1));
- TargetCardInLibrary target = new TargetCardInLibrary(filter);
- controller.searchLibrary(target, source, game);
- Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
- if (card != null) {
- controller.moveCards(card, Zone.EXILED, source, game);
- }
- controller.shuffleLibrary(source, game);
- if (card != null) {
- if (controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName()
- + " without paying its mana cost?", source, game)) {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- }
- }
- return true;
+ if (controller == null) {
+ return false;
}
- return false;
+ int numberColors = ColorsOfManaSpentToCastCount.getInstance().calculate(game, source, this);
+ FilterCard filter = new FilterCard("a creature, instant, or sorcery card with mana value "
+ + "less than or equal to " + numberColors);
+ filter.add(Predicates.or(CardType.CREATURE.getPredicate(),
+ CardType.INSTANT.getPredicate(), CardType.SORCERY.getPredicate()));
+ filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, numberColors + 1));
+ TargetCardInLibrary target = new TargetCardInLibrary(filter);
+ controller.searchLibrary(target, source, game);
+ Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
+ if (card != null) {
+ controller.moveCards(card, Zone.EXILED, source, game);
+ }
+ controller.shuffleLibrary(source, game);
+ CardUtil.castSpellWithAttributesForFree(controller, source, game, card);
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BringerOfTheWhiteDawn.java b/Mage.Sets/src/mage/cards/b/BringerOfTheWhiteDawn.java
index 4077285857b..ebcdc4ec167 100644
--- a/Mage.Sets/src/mage/cards/b/BringerOfTheWhiteDawn.java
+++ b/Mage.Sets/src/mage/cards/b/BringerOfTheWhiteDawn.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@@ -15,17 +13,18 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
-import mage.filter.common.FilterArtifactCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author Plopman
*/
public final class BringerOfTheWhiteDawn extends CardImpl {
public BringerOfTheWhiteDawn(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{7}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{W}{W}");
this.subtype.add(SubType.BRINGER);
this.power = new MageInt(5);
@@ -37,7 +36,7 @@ public final class BringerOfTheWhiteDawn extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// At the beginning of your upkeep, you may return target artifact card from your graveyard to the battlefield.
Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), TargetController.YOU, true);
- ability.addTarget(new TargetCardInYourGraveyard(new FilterArtifactCard("artifact card from your graveyard")));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BrinkOfDisaster.java b/Mage.Sets/src/mage/cards/b/BrinkOfDisaster.java
index 34ac4baf7a3..342113fa044 100644
--- a/Mage.Sets/src/mage/cards/b/BrinkOfDisaster.java
+++ b/Mage.Sets/src/mage/cards/b/BrinkOfDisaster.java
@@ -43,7 +43,7 @@ public final class BrinkOfDisaster extends CardImpl {
this.addAbility(ability);
// When enchanted permanent becomes tapped, destroy it.
- this.addAbility(new BecomesTappedAttachedTriggeredAbility(new DestroyAttachedToEffect("it"), "enchanted permanent"));
+ this.addAbility(new BecomesTappedAttachedTriggeredAbility(new DestroyAttachedToEffect("it"), "").setTriggerPhrase("When enchanted permanent becomes tapped, "));
}
private BrinkOfDisaster(final BrinkOfDisaster card) {
diff --git a/Mage.Sets/src/mage/cards/b/BrionStoutarm.java b/Mage.Sets/src/mage/cards/b/BrionStoutarm.java
index a0a6865c344..f4ad0f30562 100644
--- a/Mage.Sets/src/mage/cards/b/BrionStoutarm.java
+++ b/Mage.Sets/src/mage/cards/b/BrionStoutarm.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -14,25 +12,22 @@ import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.predicate.mageobject.AnotherPredicate;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.StaticFilters;
import mage.game.Game;
-import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class BrionStoutarm extends CardImpl {
- private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature other than Brion Stoutarm");
-
- static {
- filter.add(AnotherPredicate.instance);
- }
-
public BrionStoutarm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{W}");
addSuperType(SuperType.LEGENDARY);
@@ -43,10 +38,11 @@ public final class BrionStoutarm extends CardImpl {
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
+
// {R}, {tap}, Sacrifice a creature other than Brion Stoutarm: Brion Stoutarm deals damage equal to the sacrificed creature's power to target player.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BrionStoutarmEffect(), new ManaCostsImpl("{R}"));
+ Ability ability = new SimpleActivatedAbility(new BrionStoutarmEffect(), new ManaCostsImpl<>("{R}"));
ability.addCost(new TapSourceCost());
- ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)));
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)));
ability.addTarget(new TargetPlayerOrPlaneswalker());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BriselaVoiceOfNightmares.java b/Mage.Sets/src/mage/cards/b/BriselaVoiceOfNightmares.java
index 981bbaffdd1..e6cce7f8790 100644
--- a/Mage.Sets/src/mage/cards/b/BriselaVoiceOfNightmares.java
+++ b/Mage.Sets/src/mage/cards/b/BriselaVoiceOfNightmares.java
@@ -82,7 +82,7 @@ class BriselaVoiceOfNightmaresCantCastEffect extends ContinuousRuleModifyingEffe
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't cast spells with mana value 3 or less (" + mageObject.getIdName() + ").";
}
diff --git a/Mage.Sets/src/mage/cards/b/BrokenConcentration.java b/Mage.Sets/src/mage/cards/b/BrokenConcentration.java
index d1e134e9791..a72805845a2 100644
--- a/Mage.Sets/src/mage/cards/b/BrokenConcentration.java
+++ b/Mage.Sets/src/mage/cards/b/BrokenConcentration.java
@@ -23,7 +23,7 @@ public final class BrokenConcentration extends CardImpl {
this.getSpellAbility().addEffect(new CounterTargetEffect());
this.getSpellAbility().addTarget(new TargetSpell());
// Madness {3}{U}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{3}{U}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{3}{U}")));
}
private BrokenConcentration(final BrokenConcentration card) {
diff --git a/Mage.Sets/src/mage/cards/b/BrokersAscendancy.java b/Mage.Sets/src/mage/cards/b/BrokersAscendancy.java
new file mode 100644
index 00000000000..6a6605170aa
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrokersAscendancy.java
@@ -0,0 +1,43 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersAllEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrokersAscendancy extends CardImpl {
+
+ public BrokersAscendancy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}{W}{U}");
+
+ // At the beginning of your end step, put a +1/+1 counter on each creature you control and a loyalty counter on each planeswalker you control.
+ Ability ability = new BeginningOfEndStepTriggeredAbility(new AddCountersAllEffect(
+ CounterType.P1P1.createInstance(),
+ StaticFilters.FILTER_CONTROLLED_CREATURE
+ ), TargetController.YOU, false);
+ ability.addEffect(new AddCountersAllEffect(
+ CounterType.LOYALTY.createInstance(),
+ StaticFilters.FILTER_CONTROLLED_PERMANENT_PLANESWALKER
+ ).setText("and a loyalty counter on each planeswalker you control"));
+ this.addAbility(ability);
+ }
+
+ private BrokersAscendancy(final BrokersAscendancy card) {
+ super(card);
+ }
+
+ @Override
+ public BrokersAscendancy copy() {
+ return new BrokersAscendancy(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BrokersCharm.java b/Mage.Sets/src/mage/cards/b/BrokersCharm.java
new file mode 100644
index 00000000000..dbca73f54df
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrokersCharm.java
@@ -0,0 +1,57 @@
+package mage.cards.b;
+
+import mage.abilities.Mode;
+import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.common.TargetEnchantmentPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrokersCharm extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreatureOrPlaneswalkerPermanent("creature or planeswalker an opponent controls");
+
+ static {
+ filter.add(TargetController.OPPONENT.getControllerPredicate());
+ }
+
+ public BrokersCharm(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}{W}{U}");
+
+ // Choose one —
+ // • Target creature you control gets +1/+0 until end of turn. It deals damage equal to its power to target creature or planeswalker an opponent controls.
+ this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0));
+ this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect("it"));
+ this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+
+ // • Destroy target enchantment.
+ this.getSpellAbility().addMode(new Mode(new DestroyTargetEffect()).addTarget(new TargetEnchantmentPermanent()));
+
+ // • Draw two cards.
+ this.getSpellAbility().addMode(new Mode(new DrawCardSourceControllerEffect(2)));
+ }
+
+ private BrokersCharm(final BrokersCharm card) {
+ super(card);
+ }
+
+ @Override
+ public BrokersCharm copy() {
+ return new BrokersCharm(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BrokersConfluence.java b/Mage.Sets/src/mage/cards/b/BrokersConfluence.java
new file mode 100644
index 00000000000..7b8a5d603a3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrokersConfluence.java
@@ -0,0 +1,46 @@
+package mage.cards.b;
+
+import mage.abilities.Mode;
+import mage.abilities.effects.common.CounterTargetEffect;
+import mage.abilities.effects.common.PhaseOutTargetEffect;
+import mage.abilities.effects.common.counter.ProliferateEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetActivatedOrTriggeredAbility;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrokersConfluence extends CardImpl {
+
+ public BrokersConfluence(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}{W}{U}");
+
+ // Choose three. You may choose the same mode more than once.
+ this.getSpellAbility().getModes().setMinModes(3);
+ this.getSpellAbility().getModes().setMaxModes(3);
+ this.getSpellAbility().getModes().setEachModeMoreThanOnce(true);
+
+ // • Proliferate.
+ this.getSpellAbility().addEffect(new ProliferateEffect());
+
+ // • Target creature phases out.
+ this.getSpellAbility().addMode(new Mode(new PhaseOutTargetEffect()).addTarget(new TargetCreaturePermanent()));
+
+ // • Counter target activated or triggered ability.
+ this.getSpellAbility().addMode(new Mode(new CounterTargetEffect()).addTarget(new TargetActivatedOrTriggeredAbility()));
+ }
+
+ private BrokersConfluence(final BrokersConfluence card) {
+ super(card);
+ }
+
+ @Override
+ public BrokersConfluence copy() {
+ return new BrokersConfluence(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BrokersHideout.java b/Mage.Sets/src/mage/cards/b/BrokersHideout.java
new file mode 100644
index 00000000000..021c7b7f5d3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrokersHideout.java
@@ -0,0 +1,58 @@
+package mage.cards.b;
+
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.effects.common.DoWhenCostPaid;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.FilterCard;
+import mage.filter.predicate.Predicates;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrokersHideout extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("a basic Forest, Plains, or Island card");
+
+ static {
+ filter.add(SuperType.BASIC.getPredicate());
+ filter.add(Predicates.or(
+ SubType.FOREST.getPredicate(),
+ SubType.PLAINS.getPredicate(),
+ SubType.ISLAND.getPredicate()
+ ));
+ }
+
+ public BrokersHideout(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+
+ // When Brokers Hideout enters the battlefield, sacrifice it. When you do, search your library for a basic Forest, Plains, or Island card, put it onto the battlefield tapped, then shuffle and you gain 1 life.
+ ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new SearchLibraryPutInPlayEffect(
+ new TargetCardInLibrary(filter), true, true
+ ), false);
+ ability.addEffect(new GainLifeEffect(1).concatBy("and"));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
+ ability, new SacrificeSourceCost().setText("sacrifice it"), null, false
+ )));
+ }
+
+ private BrokersHideout(final BrokersHideout card) {
+ super(card);
+ }
+
+ @Override
+ public BrokersHideout copy() {
+ return new BrokersHideout(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BrokersInitiate.java b/Mage.Sets/src/mage/cards/b/BrokersInitiate.java
new file mode 100644
index 00000000000..a3f31144014
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrokersInitiate.java
@@ -0,0 +1,43 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubLayer;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrokersInitiate extends CardImpl {
+
+ public BrokersInitiate(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
+
+ this.subtype.add(SubType.CAT);
+ this.subtype.add(SubType.CITIZEN);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(4);
+
+ // {4}{G/U}: Brokers Initiate has base power and toughness 5/5 until end of turn.
+ this.addAbility(new SimpleActivatedAbility(new SetPowerToughnessSourceEffect(
+ 5, 5, Duration.EndOfTurn, SubLayer.SetPT_7b
+ ), new ManaCostsImpl<>("{4}{G/U}")));
+ }
+
+ private BrokersInitiate(final BrokersInitiate card) {
+ super(card);
+ }
+
+ @Override
+ public BrokersInitiate copy() {
+ return new BrokersInitiate(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BrokersVeteran.java b/Mage.Sets/src/mage/cards/b/BrokersVeteran.java
new file mode 100644
index 00000000000..ad1a2307561
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrokersVeteran.java
@@ -0,0 +1,45 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesSourceTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrokersVeteran extends CardImpl {
+
+ public BrokersVeteran(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // When Brokers Veteran dies, put a shield counter on target creature you control.
+ Ability ability = new DiesSourceTriggeredAbility(
+ new AddCountersTargetEffect(CounterType.SHIELD.createInstance())
+ );
+ ability.addTarget(new TargetControlledCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private BrokersVeteran(final BrokersVeteran card) {
+ super(card);
+ }
+
+ @Override
+ public BrokersVeteran copy() {
+ return new BrokersVeteran(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BronzeCudgels.java b/Mage.Sets/src/mage/cards/b/BronzeCudgels.java
index c095a827a9d..608b9a6d8d6 100644
--- a/Mage.Sets/src/mage/cards/b/BronzeCudgels.java
+++ b/Mage.Sets/src/mage/cards/b/BronzeCudgels.java
@@ -76,7 +76,7 @@ class BronzeCudgelsEffect extends OneShotEffect {
return false;
}
game.addEffect(new BoostTargetEffect(resolvedCount, 0)
- .setTargetPointer(new FixedTarget(permanent.getOwnerId(), game)), source);
+ .setTargetPointer(new FixedTarget(permanent.getAttachedTo(), game)), source);
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BronzehideLion.java b/Mage.Sets/src/mage/cards/b/BronzehideLion.java
index da5b0187de9..fbd92ad8a99 100644
--- a/Mage.Sets/src/mage/cards/b/BronzehideLion.java
+++ b/Mage.Sets/src/mage/cards/b/BronzehideLion.java
@@ -88,7 +88,7 @@ class BronzehideLionReturnEffect extends OneShotEffect {
}
TargetPermanent target = new TargetControlledCreaturePermanent();
target.setNotTarget(true);
- if (controller.choose(outcome, target, source.getSourceId(), game)
+ if (controller.choose(outcome, target, source, game)
&& game.getPermanent(target.getFirstTarget()) != null) {
game.getState().setValue("attachTo:" + source.getSourceId(), target.getFirstTarget());
}
diff --git a/Mage.Sets/src/mage/cards/b/BronzeplateBoar.java b/Mage.Sets/src/mage/cards/b/BronzeplateBoar.java
index 68e64d1fbed..8895f8b47f7 100644
--- a/Mage.Sets/src/mage/cards/b/BronzeplateBoar.java
+++ b/Mage.Sets/src/mage/cards/b/BronzeplateBoar.java
@@ -36,6 +36,7 @@ public final class BronzeplateBoar extends CardImpl {
ability.addEffect(new GainAbilityAttachedEffect(
TrampleAbility.getInstance(), AttachmentType.EQUIPMENT
).setText("and has trample"));
+ this.addAbility(ability);
// Reconfigure {5}
this.addAbility(new ReconfigureAbility("{5}"));
diff --git a/Mage.Sets/src/mage/cards/b/BroodhatchNantuko.java b/Mage.Sets/src/mage/cards/b/BroodhatchNantuko.java
index 81ce22ee1c6..44c86ea0107 100644
--- a/Mage.Sets/src/mage/cards/b/BroodhatchNantuko.java
+++ b/Mage.Sets/src/mage/cards/b/BroodhatchNantuko.java
@@ -1,22 +1,17 @@
-
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.DealtDamageToSourceTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.MorphAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.game.Game;
import mage.game.permanent.token.InsectToken;
-import mage.players.Player;
/**
*
@@ -31,9 +26,11 @@ public final class BroodhatchNantuko extends CardImpl {
this.toughness = new MageInt(1);
// Whenever Broodhatch Nantuko is dealt damage, you may create that many 1/1 green Insect creature tokens.
- this.addAbility(new DealtDamageToSourceTriggeredAbility(new BroodhatchNantukoDealDamageEffect(), true, false));
+ this.addAbility(new DealtDamageToSourceTriggeredAbility(
+ new CreateTokenEffect(new InsectToken(), SavedDamageValue.MANY), true));
+
// Morph {2}{G}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{G}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl<>("{2}{G}")));
}
private BroodhatchNantuko(final BroodhatchNantuko card) {
@@ -45,32 +42,3 @@ public final class BroodhatchNantuko extends CardImpl {
return new BroodhatchNantuko(this);
}
}
-
-class BroodhatchNantukoDealDamageEffect extends OneShotEffect {
-
- public BroodhatchNantukoDealDamageEffect() {
- super(Outcome.Damage);
- this.staticText = "create that many 1/1 green Insect creature tokens";
- }
-
- public BroodhatchNantukoDealDamageEffect(final BroodhatchNantukoDealDamageEffect effect) {
- super(effect);
- }
-
- @Override
- public BroodhatchNantukoDealDamageEffect copy() {
- return new BroodhatchNantukoDealDamageEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
- if (player != null) {
- int amount = (Integer) getValue("damage");
- if (amount > 0) {
- return new CreateTokenEffect(new InsectToken(), amount).apply(game, source);
- }
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BroodmateDragon.java b/Mage.Sets/src/mage/cards/b/BroodmateDragon.java
index cd337e76900..cee58d55f3f 100644
--- a/Mage.Sets/src/mage/cards/b/BroodmateDragon.java
+++ b/Mage.Sets/src/mage/cards/b/BroodmateDragon.java
@@ -19,7 +19,7 @@ import mage.game.permanent.token.DragonToken;
*/
public final class BroodmateDragon extends CardImpl {
- private static DragonToken dragonToken = new DragonToken();
+ private static final DragonToken dragonToken = new DragonToken();
public BroodmateDragon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{R}{G}");
diff --git a/Mage.Sets/src/mage/cards/b/BrothersYamazaki.java b/Mage.Sets/src/mage/cards/b/BrothersYamazaki.java
index eb339a13ba0..ee936a0012f 100644
--- a/Mage.Sets/src/mage/cards/b/BrothersYamazaki.java
+++ b/Mage.Sets/src/mage/cards/b/BrothersYamazaki.java
@@ -99,7 +99,7 @@ class BrothersYamazakiIgnoreLegendRuleEffectEffect extends ContinuousRuleModifyi
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.getName().equals("Brothers Yamazaki")) {
- return game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) == 2;
+ return game.getBattlefield().count(filter, source.getControllerId(), source, game) == 2;
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java b/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java
index 32540571ce7..863c43269ab 100644
--- a/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java
+++ b/Mage.Sets/src/mage/cards/b/BrudicladTelchorEngineer.java
@@ -94,7 +94,7 @@ class BrudicladTelchorEngineerEffect extends OneShotEffect {
TargetControlledPermanent target = new TargetControlledPermanent(0, 1, filter, true);
target.setNotTarget(true);
if (controller.chooseUse(outcome, "Select a token to copy?", source, game)
- && controller.choose(Outcome.Neutral, target, source.getSourceId(), game)) {
+ && controller.choose(Outcome.Neutral, target, source, game)) {
Permanent toCopyFromPermanent = game.getPermanent(target.getFirstTarget());
if (toCopyFromPermanent != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BruenorBattlehammer.java b/Mage.Sets/src/mage/cards/b/BruenorBattlehammer.java
index c70f83bd04b..17d6ecbaa5e 100644
--- a/Mage.Sets/src/mage/cards/b/BruenorBattlehammer.java
+++ b/Mage.Sets/src/mage/cards/b/BruenorBattlehammer.java
@@ -72,7 +72,7 @@ class BruenorBattlehammerBoostEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
- source.getControllerId(), source.getSourceId(), game
+ source.getControllerId(), source, game
)) {
int equipped = permanent
.getAttachments()
diff --git a/Mage.Sets/src/mage/cards/b/BrunaLightOfAlabaster.java b/Mage.Sets/src/mage/cards/b/BrunaLightOfAlabaster.java
index 9329557a7b0..9a6da1ee603 100644
--- a/Mage.Sets/src/mage/cards/b/BrunaLightOfAlabaster.java
+++ b/Mage.Sets/src/mage/cards/b/BrunaLightOfAlabaster.java
@@ -75,8 +75,10 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- UUID bruna = source.getSourceId();
Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) { return false; }
+
+ UUID bruna = source.getSourceId();
FilterPermanent filterAura = new FilterPermanent("Aura");
FilterCard filterAuraCard = new FilterCard("Aura card");
@@ -88,13 +90,9 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
filterAuraCard.add(SubType.AURA.getPredicate());
filterAuraCard.add(new AuraCardCanAttachToPermanentId(bruna));
- if (controller == null) {
- return false;
- }
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
- if (sourcePermanent == null) {
- return false;
- }
+ if (sourcePermanent == null) { return false; }
+
List fromBattlefield = new ArrayList<>();
List fromHandGraveyard = new ArrayList<>();
@@ -104,16 +102,17 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
&& controller.chooseUse(Outcome.Benefit, "Attach an Aura from the battlefield?", source, game)) {
Target targetAura = new TargetPermanent(filterAura);
targetAura.setNotTarget(true);
- if (controller.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) {
- Permanent aura = game.getPermanent(targetAura.getFirstTarget());
- if (aura != null) {
- Target target = aura.getSpellAbility().getTargets().get(0);
- if (target != null) {
- fromBattlefield.add(aura);
- filterAura.add(Predicates.not(new CardIdPredicate(aura.getId())));
- }
- }
- }
+ if (!controller.choose(Outcome.Benefit, targetAura, source, game)) { continue; }
+
+ Permanent aura = game.getPermanent(targetAura.getFirstTarget());
+ if (aura == null) { continue; }
+
+ Target target = aura.getSpellAbility().getTargets().get(0);
+ if (target == null) { continue; }
+
+ fromBattlefield.add(aura);
+ filterAura.add(Predicates.not(new CardIdPredicate(aura.getId())));
+
countBattlefield = game.getBattlefield().getAllActivePermanents(filterAura, game).size() - sourcePermanent.getAttachments().size();
}
@@ -122,16 +121,16 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
&& countHand > 0
&& controller.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", source, game)) {
TargetCard targetAura = new TargetCard(Zone.HAND, filterAuraCard);
- if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) {
- Card aura = game.getCard(targetAura.getFirstTarget());
- if (aura != null) {
- Target target = aura.getSpellAbility().getTargets().get(0);
- if (target != null) {
- fromHandGraveyard.add(aura);
- filterAuraCard.add(Predicates.not(new CardIdPredicate(aura.getId())));
- }
- }
- }
+ if (!controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) { continue; }
+
+ Card aura = game.getCard(targetAura.getFirstTarget());
+ if (aura == null) { continue; }
+
+ Target target = aura.getSpellAbility().getTargets().get(0);
+ if (target == null) { continue; }
+ fromHandGraveyard.add(aura);
+ filterAuraCard.add(Predicates.not(new CardIdPredicate(aura.getId())));
+
countHand = controller.getHand().count(filterAuraCard, game);
}
@@ -140,18 +139,20 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
&& countGraveyard > 0
&& controller.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", source, game)) {
TargetCard targetAura = new TargetCard(Zone.GRAVEYARD, filterAuraCard);
- if (controller.choose(Outcome.Benefit, controller.getGraveyard(), targetAura, game)) {
- Card aura = game.getCard(targetAura.getFirstTarget());
- if (aura != null) {
- Target target = aura.getSpellAbility().getTargets().get(0);
- if (target != null) {
- fromHandGraveyard.add(aura);
- filterAuraCard.add(Predicates.not(new CardIdPredicate(aura.getId())));
- }
- }
- }
+ if (!controller.choose(Outcome.Benefit, controller.getGraveyard(), targetAura, game)) { continue; }
+
+ Card aura = game.getCard(targetAura.getFirstTarget());
+ if (aura == null) { continue; }
+
+ Target target = aura.getSpellAbility().getTargets().get(0);
+ if (target == null) { continue; }
+
+ fromHandGraveyard.add(aura);
+ filterAuraCard.add(Predicates.not(new CardIdPredicate(aura.getId())));
+
countGraveyard = controller.getGraveyard().count(filterAuraCard, game);
}
+
// Move permanents
for (Permanent aura : fromBattlefield) {
Permanent attachedTo = game.getPermanent(aura.getAttachedTo());
@@ -160,13 +161,14 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
}
sourcePermanent.addAttachment(aura.getId(), source, game);
}
+
// Move cards
for (Card aura : fromHandGraveyard) {
- if (aura != null) {
- game.getState().setValue("attachTo:" + aura.getId(), sourcePermanent);
- controller.moveCards(aura, Zone.BATTLEFIELD, source, game);
- sourcePermanent.addAttachment(aura.getId(), source, game);
- }
+ if (aura == null) { continue; }
+
+ game.getState().setValue("attachTo:" + aura.getId(), sourcePermanent);
+ controller.moveCards(aura, Zone.BATTLEFIELD, source, game);
+ sourcePermanent.addAttachment(aura.getId(), source, game);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/b/BrutalExpulsion.java b/Mage.Sets/src/mage/cards/b/BrutalExpulsion.java
index 51421920af7..8eec6a17a4a 100644
--- a/Mage.Sets/src/mage/cards/b/BrutalExpulsion.java
+++ b/Mage.Sets/src/mage/cards/b/BrutalExpulsion.java
@@ -42,8 +42,7 @@ public final class BrutalExpulsion extends CardImpl {
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetSpellOrPermanent(1, 1, filter, false).withChooseHint("return to its owner's hand"));
// or Brutal Expulsion deals 2 damage to target creature or planeswalker. If that permanent would be put into a graveyard this turn, exile it instead.
- Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(2));
+ Mode mode = new Mode(new DamageTargetEffect(2));
Effect effect = new DealtDamageToCreatureBySourceDies(this, Duration.EndOfTurn);
effect.setText("If that creature or planeswalker would die this turn, exile it instead");
mode.addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java
index 8b0eb470a61..7f9ae4c09e6 100644
--- a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java
+++ b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java
@@ -12,7 +12,7 @@ import mage.abilities.effects.common.combat.ChooseBlockersEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@@ -26,12 +26,6 @@ import java.util.UUID;
*/
public final class BrutalHordechief extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public BrutalHordechief(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.ORC, SubType.WARRIOR);
@@ -43,7 +37,8 @@ public final class BrutalHordechief extends CardImpl {
// {3}{R/W}{R/W}: Creatures your opponents control block this turn if able, and you choose how those creatures block.
Ability ability = new SimpleActivatedAbility(
- new BlocksIfAbleAllEffect(filter, Duration.EndOfTurn), new ManaCostsImpl<>("{3}{R/W}{R/W}")
+ new BlocksIfAbleAllEffect(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES, Duration.EndOfTurn),
+ new ManaCostsImpl<>("{3}{R/W}{R/W}")
);
ability.addEffect(new ChooseBlockersEffect(Duration.EndOfTurn).setText("and you choose how those creatures block"));
ability.addWatcher(new ControlCombatRedundancyWatcher());
diff --git a/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java b/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java
index c5e1ef23a76..83068067577 100644
--- a/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java
+++ b/Mage.Sets/src/mage/cards/b/BrutalizerExarch.java
@@ -47,8 +47,7 @@ public final class BrutalizerExarch extends CardImpl {
TargetCardInLibrary target = new TargetCardInLibrary(new FilterCreatureCard("a creature card"));
Ability ability = new EntersBattlefieldTriggeredAbility(new SearchLibraryPutOnLibraryEffect(target, true, true), false);
// or put target noncreature permanent on the bottom of its owner's library.
- Mode mode = new Mode();
- mode.addEffect(new BrutalizerExarchEffect2());
+ Mode mode = new Mode(new BrutalizerExarchEffect2());
mode.addTarget(new TargetPermanent(filter));
ability.addMode(mode);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BuccaneersBravado.java b/Mage.Sets/src/mage/cards/b/BuccaneersBravado.java
index 160dbbe01a6..5c8ea2a66f5 100644
--- a/Mage.Sets/src/mage/cards/b/BuccaneersBravado.java
+++ b/Mage.Sets/src/mage/cards/b/BuccaneersBravado.java
@@ -37,10 +37,9 @@ public final class BuccaneersBravado extends CardImpl {
this.getSpellAbility().addEffect(new BoostTargetEffect(1, 1, Duration.EndOfTurn).setText("Target creature gets +1/+1"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn).setText("and gains first strike until end of turn"));
// Target Pirate gets +1/+1 and gains double strike until end of turn.
- Mode mode = new Mode();
- mode.addTarget(new TargetPermanent(filter));
- mode.addEffect(new BoostTargetEffect(1, 1, Duration.EndOfTurn).setText("Target Pirate gets +1/+1"));
+ Mode mode = new Mode(new BoostTargetEffect(1, 1, Duration.EndOfTurn).setText("Target Pirate gets +1/+1"));
mode.addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn).setText("and gains double strike until end of turn"));
+ mode.addTarget(new TargetPermanent(filter));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/b/BudokaGardener.java b/Mage.Sets/src/mage/cards/b/BudokaGardener.java
index 58d601a750b..68fc7a99d10 100644
--- a/Mage.Sets/src/mage/cards/b/BudokaGardener.java
+++ b/Mage.Sets/src/mage/cards/b/BudokaGardener.java
@@ -70,13 +70,12 @@ class BudokaGardenerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- if (game.getBattlefield().count(filterLands, source.getSourceId(), source.getControllerId(), game) >= 10) {
- new FlipSourceEffect(new DokaiWeaverofLife()).apply(game, source);
- }
- return true;
+ if (controller == null) { return false; }
+ if (game.getBattlefield().count(filterLands, source.getControllerId(), source, game) < 10) {
+ return false;
}
- return false;
+
+ return new FlipSourceEffect(new DokaiWeaverofLife()).apply(game, source);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BuiltToLast.java b/Mage.Sets/src/mage/cards/b/BuiltToLast.java
index 470831846d1..40ed0f96d73 100644
--- a/Mage.Sets/src/mage/cards/b/BuiltToLast.java
+++ b/Mage.Sets/src/mage/cards/b/BuiltToLast.java
@@ -28,7 +28,7 @@ public final class BuiltToLast extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), new LockedInCondition(new TargetHasCardTypeCondition(CardType.ARTIFACT)),
- "If its an artifact creature, it gains indestructible until end of turn"));
+ "If it's an artifact creature, it gains indestructible until end of turn"));
}
diff --git a/Mage.Sets/src/mage/cards/b/BuiltToSmash.java b/Mage.Sets/src/mage/cards/b/BuiltToSmash.java
index 90664118ba8..2ed5b937989 100644
--- a/Mage.Sets/src/mage/cards/b/BuiltToSmash.java
+++ b/Mage.Sets/src/mage/cards/b/BuiltToSmash.java
@@ -28,7 +28,7 @@ public final class BuiltToSmash extends CardImpl {
this.getSpellAbility().addTarget(new TargetAttackingCreature());
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), new LockedInCondition(new TargetHasCardTypeCondition(CardType.ARTIFACT)),
- "If its an artifact creature, it gains trample until end of turn"));
+ "If it's an artifact creature, it gains trample until end of turn"));
}
private BuiltToSmash(final BuiltToSmash card) {
diff --git a/Mage.Sets/src/mage/cards/b/BullElephant.java b/Mage.Sets/src/mage/cards/b/BullElephant.java
index 2328b9e52f8..75c8a137bab 100644
--- a/Mage.Sets/src/mage/cards/b/BullElephant.java
+++ b/Mage.Sets/src/mage/cards/b/BullElephant.java
@@ -15,7 +15,7 @@ import java.util.UUID;
public final class BullElephant extends CardImpl {
- private static FilterControlledLandPermanent controlledForest = new FilterControlledLandPermanent("Forests");
+ private static final FilterControlledLandPermanent controlledForest = new FilterControlledLandPermanent("Forests");
static {
controlledForest.add(SubType.FOREST.getPredicate());
@@ -25,10 +25,14 @@ public final class BullElephant extends CardImpl {
public BullElephant(UUID cardId, CardSetInfo cardSetInfo) {
super(cardId, cardSetInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.ELEPHANT);
+
power = new MageInt(4);
toughness = new MageInt(4);
-//When Bull Elephant enters the battlefield, sacrifice it unless you return two Forests you control to their owner's hand.
- addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(2, 2, controlledForest, false)))));
+
+ // When Bull Elephant enters the battlefield, sacrifice it unless you return two Forests you control to their owner's hand.
+ addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(
+ new TargetControlledPermanent(2, 2, controlledForest, false)
+ ))));
}
public BullElephant(BullElephant other) {
diff --git a/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java b/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java
index f824f61baf9..6b49922a8a8 100644
--- a/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java
+++ b/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java
@@ -50,7 +50,7 @@ class BurdenOfGreedCount implements DynamicValue {
FilterArtifactPermanent filter = new FilterArtifactPermanent();
filter.add(TappedPredicate.TAPPED);
filter.add(new ControllerIdPredicate(sourceAbility.getFirstTarget()));
- return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game);
+ return game.getBattlefield().count(filter, sourceAbility.getControllerId(), sourceAbility, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BuriedRuin.java b/Mage.Sets/src/mage/cards/b/BuriedRuin.java
index 77e4c5a873b..e323ef27004 100644
--- a/Mage.Sets/src/mage/cards/b/BuriedRuin.java
+++ b/Mage.Sets/src/mage/cards/b/BuriedRuin.java
@@ -1,36 +1,33 @@
-
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.filter.common.FilterArtifactCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
* @author Loki
*/
public final class BuriedRuin extends CardImpl {
public BuriedRuin(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.addAbility(new ColorlessManaAbility());
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new GenericManaCost(2));
+ Ability ability = new SimpleActivatedAbility(new ReturnFromGraveyardToHandTargetEffect(), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
- ability.addTarget(new TargetCardInYourGraveyard(new FilterArtifactCard("artifact card from your graveyard")));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
-
}
private BuriedRuin(final BuriedRuin card) {
@@ -41,5 +38,4 @@ public final class BuriedRuin extends CardImpl {
public BuriedRuin copy() {
return new BuriedRuin(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/b/BurnFromWithin.java b/Mage.Sets/src/mage/cards/b/BurnFromWithin.java
index 1a940c15833..7c11ae7dd31 100644
--- a/Mage.Sets/src/mage/cards/b/BurnFromWithin.java
+++ b/Mage.Sets/src/mage/cards/b/BurnFromWithin.java
@@ -32,7 +32,6 @@ public final class BurnFromWithin extends CardImpl {
// If that creature would die this turn, exile it instead.
this.getSpellAbility().addEffect(new BurnFromWithinEffect());
this.getSpellAbility().addTarget(new TargetAnyTarget());
-
}
private BurnFromWithin(final BurnFromWithin card) {
@@ -49,7 +48,9 @@ class BurnFromWithinEffect extends OneShotEffect {
public BurnFromWithinEffect() {
super(Outcome.Benefit);
- this.staticText = "{this} deals X damage to any target. If a creature is dealt damage this way, it loses indestructible until end of turn. If that creature would die this turn, exile it instead";
+ this.staticText = "{this} deals X damage to any target. " +
+ "If a creature is dealt damage this way, it loses indestructible until end of turn. " +
+ "If that creature would die this turn, exile it instead";
}
public BurnFromWithinEffect(final BurnFromWithinEffect effect) {
@@ -64,25 +65,31 @@ class BurnFromWithinEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
- int amount = source.getManaCostsToPay().getX();
- if (creature != null) {
- game.addEffect(new DiesReplacementEffect(new MageObjectReference(creature, game), Duration.EndOfTurn), source);
- int damageDealt = creature.damage(amount, source.getSourceId(), source, game, false, true);
- if (damageDealt > 0) {
- ContinuousEffect effect = new LoseAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn);
- effect.setTargetPointer(new FixedTarget(creature.getId(), game));
- game.addEffect(effect, source);
- }
- return true;
- }
- Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
- if (targetPlayer != null) {
- targetPlayer.damage(amount, source.getSourceId(), source, game);
- return true;
+ if (controller == null) { return false; }
+
+ int amount = source.getManaCostsToPay().getX();
+
+ // Target is a creature
+ Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (creature != null) {
+ game.addEffect(new DiesReplacementEffect(new MageObjectReference(creature, game), Duration.EndOfTurn), source);
+ int damageDealt = creature.damage(amount, source.getSourceId(), source, game, false, true);
+ if (damageDealt > 0) {
+ ContinuousEffect effect = new LoseAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(creature.getId(), game));
+ game.addEffect(effect, source);
}
+ return true;
}
+
+ // Target is a player
+ Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
+ if (targetPlayer != null) {
+ targetPlayer.damage(amount, source.getSourceId(), source, game);
+ return true;
+ }
+
+ // No valid target
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BurnTrail.java b/Mage.Sets/src/mage/cards/b/BurnTrail.java
index f2620442ca4..9c070b730ae 100644
--- a/Mage.Sets/src/mage/cards/b/BurnTrail.java
+++ b/Mage.Sets/src/mage/cards/b/BurnTrail.java
@@ -23,7 +23,7 @@ public final class BurnTrail extends CardImpl {
this.getSpellAbility().addTarget(new TargetAnyTarget());
// Conspire
- this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
+ this.addAbility(new ConspireAbility(ConspireAbility.ConspireTargets.ONE));
}
private BurnTrail(final BurnTrail card) {
diff --git a/Mage.Sets/src/mage/cards/b/BurningCinderFuryOfCrimsonChaosFire.java b/Mage.Sets/src/mage/cards/b/BurningCinderFuryOfCrimsonChaosFire.java
index c25450038a9..183e267127c 100644
--- a/Mage.Sets/src/mage/cards/b/BurningCinderFuryOfCrimsonChaosFire.java
+++ b/Mage.Sets/src/mage/cards/b/BurningCinderFuryOfCrimsonChaosFire.java
@@ -145,7 +145,7 @@ class BurningCinderFuryOfCrimsonChaosFireEffect extends OneShotEffect {
class BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect extends ContinuousEffectImpl {
- private UUID controller;
+ private final UUID controller;
public BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(Duration duration, UUID controller) {
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
diff --git a/Mage.Sets/src/mage/cards/b/BurningOfXinye.java b/Mage.Sets/src/mage/cards/b/BurningOfXinye.java
index 5e997123114..cc81dfbf8d5 100644
--- a/Mage.Sets/src/mage/cards/b/BurningOfXinye.java
+++ b/Mage.Sets/src/mage/cards/b/BurningOfXinye.java
@@ -61,37 +61,36 @@ class BurningOfXinyeEffect extends OneShotEffect{
@Override
public boolean apply(Game game, Ability source) {
boolean abilityApplied = false;
-
- Player controller = game.getPlayer(source.getControllerId());
+ Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
abilityApplied |= playerDestroys(game, source, controller);
}
-
- Player opponent = game.getPlayer(source.getFirstTarget());
- if (controller != null) {
+ Player opponent = game.getPlayer(source.getFirstTarget());
+ if (opponent != null) {
abilityApplied |= playerDestroys(game, source, opponent);
}
+
return abilityApplied;
}
- public boolean playerDestroys(Game game, Ability source,Player player){
+ private boolean playerDestroys(Game game, Ability source, Player player){
boolean abilityApplied = false;
int realCount = game.getBattlefield().countAll(filter, player.getId(), game);
int amount = Math.min(4, realCount);
Target target = new TargetControlledPermanent(amount, amount, filter, true);
- if (amount > 0 && target.canChoose(source.getSourceId(), player.getId(), game)) {
- while (!target.isChosen() && target.canChoose(source.getSourceId(), player.getId(), game) && player.canRespond()) {
- player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
+ if (amount > 0 && target.canChoose(player.getId(), source, game)) {
+ while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
+ player.choose(Outcome.Sacrifice, target, source, game);
}
- for ( int idx = 0; idx < target.getTargets().size(); idx++) {
- Permanent permanent = game.getPermanent(target.getTargets().get(idx));
+ for (UUID targetId : target.getTargets()) {
+ Permanent permanent = game.getPermanent(targetId);
- if ( permanent != null ) {
+ if (permanent != null) {
abilityApplied |= permanent.destroy(source, game, false);
}
}
@@ -103,5 +102,4 @@ class BurningOfXinyeEffect extends OneShotEffect{
public BurningOfXinyeEffect copy() {
return new BurningOfXinyeEffect(this);
}
-
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/b/BurningRuneDemon.java b/Mage.Sets/src/mage/cards/b/BurningRuneDemon.java
index 53e90462739..7092c4613ab 100644
--- a/Mage.Sets/src/mage/cards/b/BurningRuneDemon.java
+++ b/Mage.Sets/src/mage/cards/b/BurningRuneDemon.java
@@ -1,17 +1,14 @@
package mage.cards.b;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.FlyingAbility;
import mage.cards.*;
+import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.abilities.keyword.FlyingAbility;
-import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
@@ -21,11 +18,13 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
+import mage.target.common.TargetCardWithDifferentNameInLibrary;
import mage.target.common.TargetOpponent;
-import mage.util.CardUtil;
+
+import java.util.Set;
+import java.util.UUID;
/**
- *
* @author weirddan455
*/
public final class BurningRuneDemon extends CardImpl {
@@ -60,6 +59,13 @@ public final class BurningRuneDemon extends CardImpl {
class BurningRuneDemonEffect extends OneShotEffect {
+ private static final FilterCard filter
+ = new FilterCard("cards not named Burning-Rune Demon that have different names");
+
+ static {
+ filter.add(Predicates.not(new NamePredicate("Burning-Rune Demon")));
+ }
+
public BurningRuneDemonEffect() {
super(Outcome.Benefit);
staticText = "search your library for exactly two cards "
@@ -81,7 +87,7 @@ class BurningRuneDemonEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- TargetCardInLibrary targetCardInLibrary = new BurningRuneDemonTarget();
+ TargetCardInLibrary targetCardInLibrary = new TargetCardWithDifferentNameInLibrary(2, 2, filter);
if (controller.searchLibrary(targetCardInLibrary, source, game)) {
Cards cards = new CardsImpl(targetCardInLibrary.getTargets());
if (!cards.isEmpty()) {
@@ -115,41 +121,3 @@ class BurningRuneDemonEffect extends OneShotEffect {
return false;
}
}
-
-class BurningRuneDemonTarget extends TargetCardInLibrary {
-
- private static final FilterCard filter
- = new FilterCard("cards not named Burning-Rune Demon that have different names");
-
- static {
- filter.add(Predicates.not(new NamePredicate("Burning-Rune Demon")));
- }
-
- public BurningRuneDemonTarget() {
- super(2, filter);
- }
-
- private BurningRuneDemonTarget(final BurningRuneDemonTarget target) {
- super(target);
- }
-
- @Override
- public BurningRuneDemonTarget copy() {
- return new BurningRuneDemonTarget(this);
- }
-
- @Override
- public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
- if (!super.canTarget(playerId, id, source, game)) {
- return false;
- }
- Card card = game.getCard(id);
- return card != null
- && this.getTargets()
- .stream()
- .map(game::getCard)
- .filter(Objects::nonNull)
- .map(Card::getName)
- .noneMatch(n -> CardUtil.haveSameNames(card, n, game));
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BurstLightning.java b/Mage.Sets/src/mage/cards/b/BurstLightning.java
index 52c03e02f3f..72f91afae59 100644
--- a/Mage.Sets/src/mage/cards/b/BurstLightning.java
+++ b/Mage.Sets/src/mage/cards/b/BurstLightning.java
@@ -26,7 +26,7 @@ public final class BurstLightning extends CardImpl {
// Burst Lightning deals 2 damage to any target. If Burst Lightning was kicked, it deals 4 damage to that creature or player instead.
this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DamageTargetEffect(4),
- new DamageTargetEffect(2), KickedCondition.instance, "{this} deals 2 damage to any target. If this spell was kicked, it deals 4 damage to that permanent or player instead"));
+ new DamageTargetEffect(2), KickedCondition.instance, "{this} deals 2 damage to any target. If this spell was kicked, it deals 4 damage instead"));
}
private BurstLightning(final BurstLightning card) {
diff --git a/Mage.Sets/src/mage/cards/b/BurstOfSpeed.java b/Mage.Sets/src/mage/cards/b/BurstOfSpeed.java
index 1a2a7e001f1..02209baadaa 100644
--- a/Mage.Sets/src/mage/cards/b/BurstOfSpeed.java
+++ b/Mage.Sets/src/mage/cards/b/BurstOfSpeed.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
@@ -10,8 +8,9 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.StaticFilters;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class BurstOfSpeed extends CardImpl {
@@ -19,7 +18,10 @@ public final class BurstOfSpeed extends CardImpl {
public BurstOfSpeed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}");
- this.getSpellAbility().addEffect(new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE, false));
+ this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURES, false
+ ));
}
private BurstOfSpeed(final BurstOfSpeed card) {
diff --git a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java
index 7be8a1fb834..5219f808060 100644
--- a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java
+++ b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java
@@ -12,9 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.common.FilterControlledPermanent;
-import mage.filter.predicate.mageobject.AnotherPredicate;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -27,12 +25,6 @@ import java.util.UUID;
*/
public final class BushmeatPoacher extends CardImpl {
- private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("another creature");
-
- static {
- filter.add(AnotherPredicate.instance);
- }
-
public BushmeatPoacher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
@@ -44,7 +36,7 @@ public final class BushmeatPoacher extends CardImpl {
// {1}, {T}, Sacrifice another creature: You gain life equal to that creature's toughness. Draw a card.
Ability ability = new SimpleActivatedAbility(new BushmeatPoacherEffect(), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
- ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)));
this.addAbility(ability);
}
@@ -62,7 +54,7 @@ class BushmeatPoacherEffect extends OneShotEffect {
BushmeatPoacherEffect() {
super(Outcome.Benefit);
- staticText = "you gain life equal to that creature's toughness. Draw a card";
+ staticText = "you gain life equal to the sacrificed creature's toughness. Draw a card";
}
private BushmeatPoacherEffect(final BushmeatPoacherEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java b/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java
index e45a74da89a..79b81c565e8 100644
--- a/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java
+++ b/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java
@@ -71,7 +71,7 @@ class ButcherOfTheHordeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject != null && controller != null) {
Choice abilityChoice = new ChoiceImpl();
abilityChoice.setMessage("Choose an ability to add");
diff --git a/Mage.Sets/src/mage/cards/b/BuyYourSilence.java b/Mage.Sets/src/mage/cards/b/BuyYourSilence.java
new file mode 100644
index 00000000000..8b56d346ba1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BuyYourSilence.java
@@ -0,0 +1,65 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.TreasureToken;
+import mage.target.common.TargetNonlandPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BuyYourSilence extends CardImpl {
+
+ public BuyYourSilence(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}");
+
+ // Exile target nonland permanent. Its controller creates a Treasure token.
+ this.getSpellAbility().addEffect(new ExileTargetEffect());
+ this.getSpellAbility().addEffect(new BuyYourSilenceEffect());
+ this.getSpellAbility().addTarget(new TargetNonlandPermanent());
+ }
+
+ private BuyYourSilence(final BuyYourSilence card) {
+ super(card);
+ }
+
+ @Override
+ public BuyYourSilence copy() {
+ return new BuyYourSilence(this);
+ }
+}
+
+class BuyYourSilenceEffect extends OneShotEffect {
+
+ BuyYourSilenceEffect() {
+ super(Outcome.Benefit);
+ staticText = "Its controller creates a Treasure token";
+ }
+
+ private BuyYourSilenceEffect(final BuyYourSilenceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BuyYourSilenceEffect copy() {
+ return new BuyYourSilenceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
+ if (permanent == null) {
+ return false;
+ }
+ return new TreasureToken().putOntoBattlefield(1, game, source, permanent.getControllerId());
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CabalExecutioner.java b/Mage.Sets/src/mage/cards/c/CabalExecutioner.java
index 16ba71fdf8f..901009bd167 100644
--- a/Mage.Sets/src/mage/cards/c/CabalExecutioner.java
+++ b/Mage.Sets/src/mage/cards/c/CabalExecutioner.java
@@ -17,7 +17,6 @@ import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.target.targetpointer.FixedTarget;
/**
@@ -37,7 +36,7 @@ public final class CabalExecutioner extends CardImpl {
this.addAbility(new CabalExecutionerAbility());
// Morph {3}{B}{B}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{B}{B}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{3}{B}{B}")));
}
private CabalExecutioner(final CabalExecutioner card) {
diff --git a/Mage.Sets/src/mage/cards/c/CabalShrine.java b/Mage.Sets/src/mage/cards/c/CabalShrine.java
index 319eb43c873..6ba7d6f0adc 100644
--- a/Mage.Sets/src/mage/cards/c/CabalShrine.java
+++ b/Mage.Sets/src/mage/cards/c/CabalShrine.java
@@ -90,7 +90,7 @@ class CabalShrineEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int count = 0;
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if(mageObject != null) {
Spell spell = (Spell) game.getState().getValue("cabalShrine" + mageObject);
if (spell != null) {
diff --git a/Mage.Sets/src/mage/cards/c/CabalSurgeon.java b/Mage.Sets/src/mage/cards/c/CabalSurgeon.java
index ddad3a2ae89..c8db1c1a2af 100644
--- a/Mage.Sets/src/mage/cards/c/CabalSurgeon.java
+++ b/Mage.Sets/src/mage/cards/c/CabalSurgeon.java
@@ -1,24 +1,22 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileFromGraveCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author markedagain
*/
public final class CabalSurgeon extends CardImpl {
@@ -31,7 +29,7 @@ public final class CabalSurgeon extends CardImpl {
this.toughness = new MageInt(1);
// {2}{B}{B}, {tap}, Exile two cards from your graveyard: Return target creature card from your graveyard to your hand.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{2}{B}{B}"));
+ Ability ability = new SimpleActivatedAbility(new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl<>("{2}{B}{B}"));
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
ability.addCost(new TapSourceCost());
ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(2, StaticFilters.FILTER_CARDS_FROM_YOUR_GRAVEYARD)));
diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapist.java b/Mage.Sets/src/mage/cards/c/CabalTherapist.java
index 53997fd42a9..6f4395e7281 100644
--- a/Mage.Sets/src/mage/cards/c/CabalTherapist.java
+++ b/Mage.Sets/src/mage/cards/c/CabalTherapist.java
@@ -81,7 +81,7 @@ class CabalTherapistDiscardEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (targetPlayer == null || controller == null || sourceObject == null || cardName == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapy.java b/Mage.Sets/src/mage/cards/c/CabalTherapy.java
index 59cd97eef5f..73ec5c75673 100644
--- a/Mage.Sets/src/mage/cards/c/CabalTherapy.java
+++ b/Mage.Sets/src/mage/cards/c/CabalTherapy.java
@@ -65,7 +65,7 @@ class CabalTherapyEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (targetPlayer == null || controller == null || sourceObject == null || cardName == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/c/CabarettiAscendancy.java b/Mage.Sets/src/mage/cards/c/CabarettiAscendancy.java
new file mode 100644
index 00000000000..4201c564e64
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CabarettiAscendancy.java
@@ -0,0 +1,81 @@
+package mage.cards.c;
+
+import java.util.UUID;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.players.Player;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class CabarettiAscendancy extends CardImpl {
+
+ public CabarettiAscendancy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{G}{W}");
+
+ // At the beginning of your upkeep, look at the top card of your library. If it's a creature or planeswalker card, you may reveal it and put it in your hand. If you don't, you may put it on the bottom of your library.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CabarettiAscendencyEffect(), TargetController.YOU, false));
+ }
+
+ private CabarettiAscendancy(final CabarettiAscendancy card) {
+ super(card);
+ }
+
+ @Override
+ public CabarettiAscendancy copy() {
+ return new CabarettiAscendancy(this);
+ }
+}
+
+class CabarettiAscendencyEffect extends OneShotEffect {
+
+ public CabarettiAscendencyEffect() {
+ super(Outcome.DrawCard);
+ this.staticText = "look at the top card of your library. If it's a creature or planeswalker card, you may reveal it and put it into your hand. If you don't put the card into your hand, you may put it on the bottom of your library";
+ }
+
+ private CabarettiAscendencyEffect(final CabarettiAscendencyEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CabarettiAscendencyEffect copy() {
+ return new CabarettiAscendencyEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ Card card = controller.getLibrary().getFromTop(game);
+ if (card == null) {
+ return false;
+ }
+ MageObject sourceObject = source.getSourceObject(game);
+ String objectName = sourceObject == null ? "Cabaretti Ascendency" : sourceObject.getIdName();
+ controller.lookAtCards(objectName, card, game);
+ if ((card.isCreature(game) || card.isPlaneswalker(game)) && controller.chooseUse(
+ Outcome.DrawCard, "Reveal " + card.getIdName() + " and put it in your hand?", source, game)) {
+ controller.revealCards(source, new CardsImpl(card), game);
+ controller.moveCards(card, Zone.HAND, source, game);
+ } else if (controller.chooseUse(Outcome.Neutral, "Put " + card.getIdName() + " on the bottom of your library?", source, game)) {
+ controller.putCardsOnBottomOfLibrary(card, game, source, false);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CabarettiCharm.java b/Mage.Sets/src/mage/cards/c/CabarettiCharm.java
new file mode 100644
index 00000000000..3c30af0dc40
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CabarettiCharm.java
@@ -0,0 +1,59 @@
+package mage.cards.c;
+
+import mage.abilities.Mode;
+import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.hint.common.CreaturesYouControlHint;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.filter.StaticFilters;
+import mage.game.permanent.token.CitizenGreenWhiteToken;
+import mage.target.common.TargetCreatureOrPlaneswalker;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CabarettiCharm extends CardImpl {
+
+ public CabarettiCharm(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{G}{W}");
+
+ // Choose one —
+ // • Cabaretti Charm deals damage equal to the number of creatures you control to target creature or planeswalker.
+ this.getSpellAbility().addEffect(new DamageTargetEffect(CreaturesYouControlCount.instance)
+ .setText("{this} deals damage equal to the number of creatures you control to target creature or planeswalker"));
+ this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
+ this.getSpellAbility().addHint(CreaturesYouControlHint.instance);
+
+ // • Creatures you control get +1/+1 and gain trample until end of turn.
+ this.getSpellAbility().addMode(new Mode(
+ new BoostControlledEffect(
+ 1, 1, Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURES
+ ).setText("creatures you control get +1/+1")
+ ).addEffect(new GainAbilityControlledEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_CONTROLLED_CREATURE
+ ).setText("and gain trample until end of turn")));
+
+ // • Create two 1/1 green and white Citizen creature tokens.
+ this.getSpellAbility().addMode(new Mode(new CreateTokenEffect(new CitizenGreenWhiteToken(), 2)));
+ }
+
+ private CabarettiCharm(final CabarettiCharm card) {
+ super(card);
+ }
+
+ @Override
+ public CabarettiCharm copy() {
+ return new CabarettiCharm(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CabarettiConfluence.java b/Mage.Sets/src/mage/cards/c/CabarettiConfluence.java
new file mode 100644
index 00000000000..fa890c72189
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CabarettiConfluence.java
@@ -0,0 +1,96 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.abilities.effects.common.continuous.BoostAllEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.Game;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CabarettiConfluence extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(TargetController.SOURCE_TARGETS.getControllerPredicate());
+ }
+
+ public CabarettiConfluence(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{G}{W}");
+
+ // Choose three. You may choose the same mode more than once.
+ this.getSpellAbility().getModes().setMinModes(3);
+ this.getSpellAbility().getModes().setMaxModes(3);
+ this.getSpellAbility().getModes().setEachModeMoreThanOnce(true);
+
+ // • Create a token that's a copy of target creature you control. It gains haste. Sacrifice it at the beginning of the next end step.
+ this.getSpellAbility().addEffect(new CabarettiConfluenceEffect());
+ this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
+
+ // • Exile target artifact or enchantment.
+ this.getSpellAbility().addMode(new Mode(new ExileTargetEffect())
+ .addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)));
+
+ // • Creatures target player controls gets +1/+1 and gain first strike until end of turn.
+ this.getSpellAbility().addMode(new Mode(new BoostAllEffect(
+ 1, 1, Duration.EndOfTurn, filter, false
+ ).setText("creatures target player controls gets +1/+1")).addEffect(new GainAbilityAllEffect(
+ FirstStrikeAbility.getInstance(), Duration.EndOfTurn, filter
+ ).setText("and gain first strike until end of turn")));
+ }
+
+ private CabarettiConfluence(final CabarettiConfluence card) {
+ super(card);
+ }
+
+ @Override
+ public CabarettiConfluence copy() {
+ return new CabarettiConfluence(this);
+ }
+}
+
+class CabarettiConfluenceEffect extends OneShotEffect {
+
+ CabarettiConfluenceEffect() {
+ super(Outcome.Benefit);
+ staticText = "create a token that's a copy of target creature you control. " +
+ "It gains haste. Sacrifice it at the beginning of the next end step";
+ }
+
+ private CabarettiConfluenceEffect(final CabarettiConfluenceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CabarettiConfluenceEffect copy() {
+ return new CabarettiConfluenceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect();
+ effect.addAdditionalAbilities(HasteAbility.getInstance());
+ effect.apply(game, source);
+ effect.sacrificeTokensCreatedAtNextEndStep(game, source);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CabarettiCourtyard.java b/Mage.Sets/src/mage/cards/c/CabarettiCourtyard.java
new file mode 100644
index 00000000000..bad2a9c30b3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CabarettiCourtyard.java
@@ -0,0 +1,57 @@
+package mage.cards.c;
+
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.effects.common.DoWhenCostPaid;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.FilterCard;
+import mage.filter.predicate.Predicates;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CabarettiCourtyard extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("a basic Mountain, Forest, or Plains card");
+
+ static {
+ filter.add(SuperType.BASIC.getPredicate());
+ filter.add(Predicates.or(
+ SubType.MOUNTAIN.getPredicate(),
+ SubType.FOREST.getPredicate(),
+ SubType.PLAINS.getPredicate()
+ ));
+ }
+
+ public CabarettiCourtyard(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // When Cabaretti Courtyard enters the battlefield, sacrifice it. When you do, search your library for a basic Mountain, Forest, or Plains card, put it onto the battlefield tapped, then shuffle and you gain 1 life.
+ ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new SearchLibraryPutInPlayEffect(
+ new TargetCardInLibrary(filter), true, true
+ ), false);
+ ability.addEffect(new GainLifeEffect(1).concatBy("and"));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
+ ability, new SacrificeSourceCost().setText("sacrifice it"), null, false
+ )));
+ }
+
+ private CabarettiCourtyard(final CabarettiCourtyard card) {
+ super(card);
+ }
+
+ @Override
+ public CabarettiCourtyard copy() {
+ return new CabarettiCourtyard(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CabarettiInitiate.java b/Mage.Sets/src/mage/cards/c/CabarettiInitiate.java
new file mode 100644
index 00000000000..7453afb9b42
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CabarettiInitiate.java
@@ -0,0 +1,43 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.DoubleStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CabarettiInitiate extends CardImpl {
+
+ public CabarettiInitiate(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
+
+ this.subtype.add(SubType.RACCOON);
+ this.subtype.add(SubType.CITIZEN);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // {2}{R/W}: Cabaretti Initiate gains double strike until end of turn.
+ this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect(
+ DoubleStrikeAbility.getInstance(), Duration.EndOfTurn
+ ), new ManaCostsImpl<>("{2}{R/W}")));
+ }
+
+ private CabarettiInitiate(final CabarettiInitiate card) {
+ super(card);
+ }
+
+ @Override
+ public CabarettiInitiate copy() {
+ return new CabarettiInitiate(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CadaverImp.java b/Mage.Sets/src/mage/cards/c/CadaverImp.java
index afd2a85f3c7..2d833bb8e4b 100644
--- a/Mage.Sets/src/mage/cards/c/CadaverImp.java
+++ b/Mage.Sets/src/mage/cards/c/CadaverImp.java
@@ -1,11 +1,9 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -14,8 +12,9 @@ import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class CadaverImp extends CardImpl {
@@ -31,10 +30,9 @@ public final class CadaverImp extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Cadaver Imp enters the battlefield, you may return target creature card from your graveyard to your hand.
- Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true);
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), true);
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
this.addAbility(ability);
-
}
private CadaverImp(final CadaverImp card) {
diff --git a/Mage.Sets/src/mage/cards/c/CagedSun.java b/Mage.Sets/src/mage/cards/c/CagedSun.java
index ae35a28088f..302ebe401ba 100644
--- a/Mage.Sets/src/mage/cards/c/CagedSun.java
+++ b/Mage.Sets/src/mage/cards/c/CagedSun.java
@@ -87,7 +87,7 @@ class CagedSunEffect2 extends ContinuousEffectImpl {
class CagedSunTriggeredAbility extends TriggeredManaAbility {
- private static final String staticText = "Whenever a land's ability adds one or more mana of the chosen color, add one additional mana of that color.";
+ private static final String staticText = "Whenever a land's ability causes you to add one or more mana of the chosen color, add one additional mana of that color.";
public CagedSunTriggeredAbility() {
super(Zone.BATTLEFIELD, new CagedSunEffect());
diff --git a/Mage.Sets/src/mage/cards/c/CaldaiaGuardian.java b/Mage.Sets/src/mage/cards/c/CaldaiaGuardian.java
new file mode 100644
index 00000000000..497a0b66c23
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CaldaiaGuardian.java
@@ -0,0 +1,56 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.DiesThisOrAnotherCreatureTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.keyword.BlitzAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ManaValuePredicate;
+import mage.game.permanent.token.CitizenGreenWhiteToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CaldaiaGuardian extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creature you control with mana value 4 or greater");
+
+ static {
+ filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3));
+ }
+
+ public CaldaiaGuardian(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(3);
+
+ // Whenever Caldaia Guardian or another creature you control with mana value 4 or greater dies, create two 1/1 green and white Citizen creature tokens.
+ this.addAbility(new DiesThisOrAnotherCreatureTriggeredAbility(
+ new CreateTokenEffect(new CitizenGreenWhiteToken(), 2), false, filter
+ ));
+
+ // Blitz {2}{G}
+ this.addAbility(new BlitzAbility(this, "{2}{G}"));
+ }
+
+ private CaldaiaGuardian(final CaldaiaGuardian card) {
+ super(card);
+ }
+
+ @Override
+ public CaldaiaGuardian copy() {
+ return new CaldaiaGuardian(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CaldaiaStrongarm.java b/Mage.Sets/src/mage/cards/c/CaldaiaStrongarm.java
new file mode 100644
index 00000000000..37c27101c57
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CaldaiaStrongarm.java
@@ -0,0 +1,49 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.keyword.BlitzAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CaldaiaStrongarm extends CardImpl {
+
+ public CaldaiaStrongarm(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // When Caldaia Strongarm enters the battlefield, put two +1/+1 counters on target creature.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new AddCountersTargetEffect(CounterType.P1P1.createInstance(2))
+ );
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+
+ // Blitz {3}{G}
+ this.addAbility(new BlitzAbility(this, "{3}{G}"));
+ }
+
+ private CaldaiaStrongarm(final CaldaiaStrongarm card) {
+ super(card);
+ }
+
+ @Override
+ public CaldaiaStrongarm copy() {
+ return new CaldaiaStrongarm(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CalixDestinysHand.java b/Mage.Sets/src/mage/cards/c/CalixDestinysHand.java
index 13460df08d4..15c7c64dc28 100644
--- a/Mage.Sets/src/mage/cards/c/CalixDestinysHand.java
+++ b/Mage.Sets/src/mage/cards/c/CalixDestinysHand.java
@@ -4,10 +4,10 @@ import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -55,14 +55,13 @@ public final class CalixDestinysHand extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CALIX);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
- // +1: Look at the top four cards of your library. You may reveal an enchantment card from among them and put that card into your hand. Put the rest on the bottom of your library in a random order.
+ // +1: Look at the top four cards of your library. You may reveal an enchantment card from among them and put that card into your hand.
+ // Put the rest on the bottom of your library in a random order.
this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(
- StaticValue.get(4), false, StaticValue.get(1), filter,
- Zone.LIBRARY, false, true, false,
- Zone.HAND, true, false, false
- ).setBackInRandomOrder(true).setText("Look at the top four cards of your library. "
+ 4, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM
+ ).setText("Look at the top four cards of your library. "
+ "You may reveal an enchantment card from among them and put that card into your hand. "
+ "Put the rest on the bottom of your library in a random order."), 1
));
diff --git a/Mage.Sets/src/mage/cards/c/CallForBlood.java b/Mage.Sets/src/mage/cards/c/CallForBlood.java
index bf8bf7d9c30..3f2eafcd776 100644
--- a/Mage.Sets/src/mage/cards/c/CallForBlood.java
+++ b/Mage.Sets/src/mage/cards/c/CallForBlood.java
@@ -1,23 +1,17 @@
-
package mage.cards.c;
import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.costs.Cost;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.effects.Effect;
+import mage.abilities.dynamicvalue.common.SacrificeCostCreaturesPower;
+import mage.abilities.dynamicvalue.common.SignInversionDynamicValue;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
@@ -27,14 +21,15 @@ import mage.target.common.TargetCreaturePermanent;
*/
public final class CallForBlood extends CardImpl {
+ private static final DynamicValue xValue = new SignInversionDynamicValue(SacrificeCostCreaturesPower.instance, false);
+
public CallForBlood(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}");
this.subtype.add(SubType.ARCANE);
- // As an additional cost to cast Call for Blood, sacrifice a creature.
+ // As an additional cost to cast this spell, sacrifice a creature.
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
// Target creature gets -X/-X until end of turn, where X is the sacrificed creature's power.
- DynamicValue xValue = new CallForBloodDynamicValue();
this.getSpellAbility().addEffect(new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
@@ -49,37 +44,3 @@ public final class CallForBlood extends CardImpl {
return new CallForBlood(this);
}
}
-
-class CallForBloodDynamicValue implements DynamicValue {
-
- @Override
- public int calculate(Game game, Ability sourceAbility, Effect effect) {
- Card sourceCard = game.getCard(sourceAbility.getSourceId());
- if (sourceCard != null) {
- for (Cost cost : sourceAbility.getCosts()) {
- if (cost instanceof SacrificeTargetCost) {
- Permanent p = (Permanent) game.getLastKnownInformation(((SacrificeTargetCost) cost).getPermanents().get(0).getId(), Zone.BATTLEFIELD);
- if (p != null) {
- return -1 * p.getPower().getValue();
- }
- }
- }
- }
- return 0;
- }
-
- @Override
- public CallForBloodDynamicValue copy() {
- return this;
- }
-
- @Override
- public String getMessage() {
- return ", where X is the sacrificed creature's power";
- }
-
- @Override
- public String toString() {
- return "-X";
- }
-}
diff --git a/Mage.Sets/src/mage/cards/c/CallInAProfessional.java b/Mage.Sets/src/mage/cards/c/CallInAProfessional.java
new file mode 100644
index 00000000000..ab5af6a9c77
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CallInAProfessional.java
@@ -0,0 +1,39 @@
+package mage.cards.c;
+
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.continuous.CantGainLifeAllEffect;
+import mage.abilities.effects.common.continuous.DamageCantBePreventedEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.target.common.TargetAnyTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CallInAProfessional extends CardImpl {
+
+ public CallInAProfessional(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
+
+ // Players can't gain life this turn. Damage can't be prevented this turn. Call In a Professional deals 3 damage to any target.
+ this.getSpellAbility().addEffect(new CantGainLifeAllEffect(Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new DamageCantBePreventedEffect(
+ Duration.EndOfTurn, "Damage can't be prevented this turn", true, false
+ ));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(3));
+ this.getSpellAbility().addTarget(new TargetAnyTarget());
+ }
+
+ private CallInAProfessional(final CallInAProfessional card) {
+ super(card);
+ }
+
+ @Override
+ public CallInAProfessional copy() {
+ return new CallInAProfessional(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CallOfTheDeathDweller.java b/Mage.Sets/src/mage/cards/c/CallOfTheDeathDweller.java
index 583d2ad7fa5..37d72138912 100644
--- a/Mage.Sets/src/mage/cards/c/CallOfTheDeathDweller.java
+++ b/Mage.Sets/src/mage/cards/c/CallOfTheDeathDweller.java
@@ -96,7 +96,7 @@ class CallOfTheDeathDwellerEffect extends OneShotEffect {
FilterPermanent filter = new FilterPermanent("creature to put a deathtouch counter on");
filter.add(Predicates.or(predicates));
Target target = new TargetPermanent(0, 1, filter, true);
- if (player.choose(outcome, target, source.getSourceId(), game)) {
+ if (player.choose(outcome, target, source, game)) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanent.addCounters(CounterType.DEATHTOUCH.createInstance(), source.getControllerId(), source, game);
@@ -104,7 +104,7 @@ class CallOfTheDeathDwellerEffect extends OneShotEffect {
}
filter.setMessage("creature to put a menace counter on");
target = new TargetPermanent(0, 1, filter, true);
- if (player.choose(outcome, target, source.getSourceId(), game)) {
+ if (player.choose(outcome, target, source, game)) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanent.addCounters(CounterType.MENACE.createInstance(), source.getControllerId(), source, game);
diff --git a/Mage.Sets/src/mage/cards/c/CallTheCoppercoats.java b/Mage.Sets/src/mage/cards/c/CallTheCoppercoats.java
index 76273b96462..456ab584b5c 100644
--- a/Mage.Sets/src/mage/cards/c/CallTheCoppercoats.java
+++ b/Mage.Sets/src/mage/cards/c/CallTheCoppercoats.java
@@ -53,7 +53,7 @@ class CallTheCoppercoatsEffect extends OneShotEffect {
CallTheCoppercoatsEffect() {
super(Outcome.Benefit);
- staticText = "Choose any number of target opponents. Create X 1/1 white Human soldier creature tokens, " +
+ staticText = "Choose any number of target opponents. Create X 1/1 white Human Soldier creature tokens, " +
"where X is the number of creatures those opponents control.";
}
diff --git a/Mage.Sets/src/mage/cards/c/CallToMind.java b/Mage.Sets/src/mage/cards/c/CallToMind.java
index 70f254a9447..5e3dd5fa281 100644
--- a/Mage.Sets/src/mage/cards/c/CallToMind.java
+++ b/Mage.Sets/src/mage/cards/c/CallToMind.java
@@ -1,6 +1,6 @@
package mage.cards.c;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -18,7 +18,7 @@ public final class CallToMind extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}");
// Return target instant or sorcery card from your graveyard to your hand.
- this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD));
}
diff --git a/Mage.Sets/src/mage/cards/c/CallToTheNetherworld.java b/Mage.Sets/src/mage/cards/c/CallToTheNetherworld.java
index 75e4751e4a8..c958f67ac5e 100644
--- a/Mage.Sets/src/mage/cards/c/CallToTheNetherworld.java
+++ b/Mage.Sets/src/mage/cards/c/CallToTheNetherworld.java
@@ -1,10 +1,8 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.keyword.MadnessAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -13,26 +11,27 @@ import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author nigelzor
*/
public final class CallToTheNetherworld extends CardImpl {
- private static FilterCreatureCard filter = new FilterCreatureCard("black creature card from your graveyard");
+ private static final FilterCreatureCard filter = new FilterCreatureCard("black creature card from your graveyard");
static {
filter.add(new ColorPredicate(ObjectColor.BLACK));
}
public CallToTheNetherworld(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
// Return target black creature card from your graveyard to your hand.
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter));
- this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
// Madness {0}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{0}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{0}")));
}
private CallToTheNetherworld(final CallToTheNetherworld card) {
diff --git a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
index 6a10b85f2b3..4787e7c7c98 100644
--- a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
+++ b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
@@ -138,7 +138,7 @@ class ChooseCreatureTypeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
Choice typeChoice = new ChoiceCreatureType(mageObject);
if (controller != null
&& mageObject != null
diff --git a/Mage.Sets/src/mage/cards/c/CallousOppressor.java b/Mage.Sets/src/mage/cards/c/CallousOppressor.java
index 35cdfca8e54..49d13865bd9 100644
--- a/Mage.Sets/src/mage/cards/c/CallousOppressor.java
+++ b/Mage.Sets/src/mage/cards/c/CallousOppressor.java
@@ -84,9 +84,9 @@ class CallousOppressorFilter extends FilterCreaturePermanent {
}
@Override
- public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
- if (super.match(permanent, sourceId, playerId, game)) {
- SubType subtype = (SubType) game.getState().getValue(sourceId + "_type");
+ public boolean match(Permanent permanent, UUID playerId, Ability source, Game game) {
+ if (super.match(permanent, playerId, source, game)) {
+ SubType subtype = (SubType) game.getState().getValue(source.getSourceId() + "_type");
if (subtype != null && permanent.hasSubtype(subtype, game)) {
return false;
}
@@ -113,12 +113,12 @@ class CallousOppressorChooseCreatureTypeEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
if (mageObject == null) {
- mageObject = game.getObject(source.getSourceId());
+ mageObject = game.getObject(source);
}
if (controller != null) {
TargetOpponent target = new TargetOpponent(true);
- if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
- while (!target.isChosen() && target.canChoose(source.getSourceId(), controller.getId(), game) && controller.canRespond()) {
+ if (target.canChoose(controller.getId(), source, game)) {
+ while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
controller.chooseTarget(outcome, target, source, game);
}
} else {
diff --git a/Mage.Sets/src/mage/cards/c/CalmingVerse.java b/Mage.Sets/src/mage/cards/c/CalmingVerse.java
index 04653e31979..e00451c3fb4 100644
--- a/Mage.Sets/src/mage/cards/c/CalmingVerse.java
+++ b/Mage.Sets/src/mage/cards/c/CalmingVerse.java
@@ -75,7 +75,7 @@ class CalmingVerseEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
// Destroy all other enchantments
- for (Permanent permanent : game.getBattlefield().getActivePermanents(opponentEnchantmentsFilter, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(opponentEnchantmentsFilter, source.getControllerId(), source, game)) {
permanent.destroy(source, game, false);
}
@@ -84,7 +84,7 @@ class CalmingVerseEffect extends OneShotEffect {
if (controller != null) {
if (game.getState().getBattlefield().countAll(untappedLandFilter, controller.getId(), game) > 0) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(controlledEnchantmentsFilter, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(controlledEnchantmentsFilter, source.getControllerId(), source, game)) {
permanent.destroy(source, game, false);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/Camaraderie.java b/Mage.Sets/src/mage/cards/c/Camaraderie.java
index f5a43597849..8eea5f8f722 100644
--- a/Mage.Sets/src/mage/cards/c/Camaraderie.java
+++ b/Mage.Sets/src/mage/cards/c/Camaraderie.java
@@ -64,7 +64,7 @@ class CamaraderieEffect extends OneShotEffect {
}
int xValue = game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_CREATURE,
- source.getSourceId(), source.getControllerId(), game
+ source.getControllerId(), source, game
);
player.gainLife(xValue, game, source);
player.drawCards(xValue, source, game);
diff --git a/Mage.Sets/src/mage/cards/c/Camouflage.java b/Mage.Sets/src/mage/cards/c/Camouflage.java
index 0d21c27c13b..d9728714b12 100644
--- a/Mage.Sets/src/mage/cards/c/Camouflage.java
+++ b/Mage.Sets/src/mage/cards/c/Camouflage.java
@@ -117,7 +117,7 @@ class CamouflageEffect extends ContinuousRuleModifyingEffectImpl {
}
if (defender.chooseUse(Outcome.Neutral, "Make a new blocker pile? If not, all remaining piles stay empty. (remaining piles: " + (attackerCount - masterList.size()) + ')', source, game)) {
Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true);
- if (target.canChoose(source.getSourceId(), defenderId, game)) {
+ if (target.canChoose(defenderId, source, game)) {
if (defender.chooseTarget(Outcome.Neutral, target, source, game)) {
for (UUID creatureId : target.getTargets()) {
Permanent creature = game.getPermanent(creatureId);
diff --git a/Mage.Sets/src/mage/cards/c/CandlesOfLeng.java b/Mage.Sets/src/mage/cards/c/CandlesOfLeng.java
index 45739de5709..449abacaec9 100644
--- a/Mage.Sets/src/mage/cards/c/CandlesOfLeng.java
+++ b/Mage.Sets/src/mage/cards/c/CandlesOfLeng.java
@@ -62,7 +62,7 @@ class CandlesOfLengEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if(controller == null || sourceObject == null){
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/CankerAbomination.java b/Mage.Sets/src/mage/cards/c/CankerAbomination.java
index 5129e0b0273..7b2fdce35e8 100644
--- a/Mage.Sets/src/mage/cards/c/CankerAbomination.java
+++ b/Mage.Sets/src/mage/cards/c/CankerAbomination.java
@@ -72,7 +72,7 @@ class CankerAbominationEffect extends OneShotEffect {
if (controller != null && cankerAbomination != null) {
Target target = new TargetOpponent();
target.setNotTarget(true);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
Player opponent = game.getPlayer(target.getFirstTarget());
if (opponent != null) {
game.informPlayers(cankerAbomination.getName() + ": " + controller.getLogName() + " has chosen " + opponent.getLogName());
diff --git a/Mage.Sets/src/mage/cards/c/CankerousThirst.java b/Mage.Sets/src/mage/cards/c/CankerousThirst.java
index ea3a3e04aa1..0bbf88c19bc 100644
--- a/Mage.Sets/src/mage/cards/c/CankerousThirst.java
+++ b/Mage.Sets/src/mage/cards/c/CankerousThirst.java
@@ -52,7 +52,7 @@ class CankerousThirstEffect extends OneShotEffect {
public CankerousThirstEffect() {
super(Outcome.Benefit);
- this.staticText = "If {B} was spent to cast {this}, you may have target creature get -3/-3 until end of turn. If {G} was spent to cast this spell, you may have target creature get +3/+3 until end of turn";
+ this.staticText = "If {B} was spent to cast this spell, you may have target creature get -3/-3 until end of turn. If {G} was spent to cast this spell, you may have target creature get +3/+3 until end of turn";
}
public CankerousThirstEffect(final CankerousThirstEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/Cannibalize.java b/Mage.Sets/src/mage/cards/c/Cannibalize.java
index 60c47cc4638..4d6fc737bae 100644
--- a/Mage.Sets/src/mage/cards/c/Cannibalize.java
+++ b/Mage.Sets/src/mage/cards/c/Cannibalize.java
@@ -1,8 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
-import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
@@ -11,14 +8,17 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanentSameController;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
/**
- *
* @author LevelX2
*/
public final class Cannibalize extends CardImpl {
@@ -28,7 +28,7 @@ public final class Cannibalize extends CardImpl {
// Choose two target creatures controlled by the same player. Exile one of the creatures and put two +1/+1 counters on the other.
this.getSpellAbility().addEffect(new CannibalizeEffect());
- this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(2, 2, StaticFilters.FILTER_PERMANENT_CREATURE, false));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(2));
}
private Cannibalize(final Cannibalize card) {
@@ -45,7 +45,8 @@ class CannibalizeEffect extends OneShotEffect {
public CannibalizeEffect() {
super(Outcome.Benefit);
- this.staticText = "Choose two target creatures controlled by the same player. Exile one of the creatures and put two +1/+1 counters on the other";
+ this.staticText = "Choose two target creatures controlled by the same player. " +
+ "Exile one of the creatures and put two +1/+1 counters on the other";
}
public CannibalizeEffect(final CannibalizeEffect effect) {
@@ -59,27 +60,48 @@ class CannibalizeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = source.getSourceObject(game);
- if (controller != null && sourceObject != null) {
- boolean exileDone = false;
- int count = 0;
- for (UUID targetId : getTargetPointer().getTargets(game, source)) {
- Permanent creature = game.getPermanent(targetId);
- if (creature != null) {
- if ((count == 0 && controller.chooseUse(Outcome.Exile, "Exile " + creature.getLogName() + '?', source, game))
- || (count == 1 && !exileDone)) {
- controller.moveCardToExileWithInfo(creature, null, "", source, game, Zone.BATTLEFIELD, true);
- exileDone = true;
- } else {
- creature.addCounters(CounterType.P1P1.createInstance(2), source.getControllerId(), source, game);
- game.informPlayers("Added two +1/+1 counters on " + creature.getLogName());
- }
- count++;
- }
- }
- return true;
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
}
- return false;
+ List permanents = this
+ .getTargetPointer()
+ .getTargets(game, source)
+ .stream()
+ .map(game::getPermanent)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ switch (permanents.size()) {
+ case 0:
+ return false;
+ case 1:
+ Permanent permanent = permanents.get(0);
+ if (player.chooseUse(
+ outcome, "Exile " + permanent.getIdName() +
+ " or put two +1/+1 counters on it?", null,
+ "Exile", "Add counters", source, game
+ )) {
+ player.moveCards(permanent, Zone.EXILED, source, game);
+ } else {
+ permanent.addCounters(CounterType.P1P1.createInstance(2), source, game);
+ }
+ return true;
+ }
+ Permanent permanent1 = permanents.get(0);
+ Permanent permanent2 = permanents.get(1);
+ if (player.chooseUse(
+ outcome, "Exile " + permanent1.getIdName() +
+ " or " + permanent2.getIdName() + '?',
+ "The other creature will get two +1/+1 counters",
+ "Exile " + permanent1.getIdName(),
+ "Exile " + permanent2.getIdName(), source, game
+ )) {
+ player.moveCards(permanent1, Zone.EXILED, source, game);
+ permanent2.addCounters(CounterType.P1P1.createInstance(2), source, game);
+ } else {
+ player.moveCards(permanent2, Zone.EXILED, source, game);
+ permanent1.addCounters(CounterType.P1P1.createInstance(2), source, game);
+ }
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CanyonLurkers.java b/Mage.Sets/src/mage/cards/c/CanyonLurkers.java
index 167befb3d3e..7bfeb186bac 100644
--- a/Mage.Sets/src/mage/cards/c/CanyonLurkers.java
+++ b/Mage.Sets/src/mage/cards/c/CanyonLurkers.java
@@ -25,7 +25,7 @@ public final class CanyonLurkers extends CardImpl {
this.toughness = new MageInt(2);
// Morph 3R
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{3}{R}")));
}
private CanyonLurkers(final CanyonLurkers card) {
diff --git a/Mage.Sets/src/mage/cards/c/CapennaExpress.java b/Mage.Sets/src/mage/cards/c/CapennaExpress.java
new file mode 100644
index 00000000000..10bad4bdfa1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CapennaExpress.java
@@ -0,0 +1,48 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.common.continuous.AddCardTypeSourceEffect;
+import mage.abilities.keyword.CrewAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CapennaExpress extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.TREASURE, "Treasure");
+
+ public CapennaExpress(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{G}");
+
+ this.subtype.add(SubType.VEHICLE);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // Sacrifice a Treasure: Capenna Express becomes an artifact creature until end of turn.
+ this.addAbility(new SimpleActivatedAbility(new AddCardTypeSourceEffect(
+ Duration.EndOfTurn, CardType.ARTIFACT, CardType.CREATURE
+ ), new SacrificeTargetCost(filter)));
+
+ // Crew 3
+ this.addAbility(new CrewAbility(3));
+ }
+
+ private CapennaExpress(final CapennaExpress card) {
+ super(card);
+ }
+
+ @Override
+ public CapennaExpress copy() {
+ return new CapennaExpress(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/Capricopian.java b/Mage.Sets/src/mage/cards/c/Capricopian.java
index 521a3696a6f..92c0fb04b2b 100644
--- a/Mage.Sets/src/mage/cards/c/Capricopian.java
+++ b/Mage.Sets/src/mage/cards/c/Capricopian.java
@@ -117,7 +117,7 @@ class CapricopianEffect extends OneShotEffect {
filterPlayer.add(Predicates.not(new PlayerIdPredicate(permanent.getControllerId())));
filterPlayer.add(Predicates.not(new PlayerIdPredicate(game.getCombat().getDefenderId(permanent.getId()))));
TargetPlayer targetPlayer = new TargetPlayer(0, 1, true, filterPlayer);
- player.choose(outcome, targetPlayer, source.getSourceId(), game);
+ player.choose(outcome, targetPlayer, source, game);
Player newPlayer = game.getPlayer(targetPlayer.getFirstTarget());
if (newPlayer == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/c/CaptainOfTheWatch.java b/Mage.Sets/src/mage/cards/c/CaptainOfTheWatch.java
index 1e6c89a9462..cb15f652a20 100644
--- a/Mage.Sets/src/mage/cards/c/CaptainOfTheWatch.java
+++ b/Mage.Sets/src/mage/cards/c/CaptainOfTheWatch.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -15,33 +13,43 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.permanent.token.SoldierToken;
+import java.util.UUID;
+
/**
* @author Loki
*/
public final class CaptainOfTheWatch extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Soldier creatures");
-
- static {
- filter.add(SubType.SOLDIER.getPredicate());
- }
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent(SubType.SOLDIER, "Soldier creatures");
public CaptainOfTheWatch(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
+
+ // Vigilance
this.addAbility(VigilanceAbility.getInstance());
- Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true));
- ability.addEffect(new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, filter, true));
+
+ // Other Soldier creatures you control get +1/+1 and have vigilance.
+ Ability ability = new SimpleStaticAbility(new BoostControlledEffect(
+ 1, 1, Duration.WhileOnBattlefield, filter, true
+ ));
+ ability.addEffect(new GainAbilityControlledEffect(
+ VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, filter, true
+ ).setText("and have vigilance"));
this.addAbility(ability);
- this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SoldierToken(), 3), false));
+
+ // When Captain of the Watch enters the battlefield, create three 1/1 white Soldier creature tokens.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new CreateTokenEffect(new SoldierToken(), 3), false
+ ));
}
private CaptainOfTheWatch(final CaptainOfTheWatch card) {
diff --git a/Mage.Sets/src/mage/cards/c/CarpetOfFlowers.java b/Mage.Sets/src/mage/cards/c/CarpetOfFlowers.java
index bb5dcc74be4..c66f8e7cd87 100644
--- a/Mage.Sets/src/mage/cards/c/CarpetOfFlowers.java
+++ b/Mage.Sets/src/mage/cards/c/CarpetOfFlowers.java
@@ -14,7 +14,6 @@ import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.players.Player;
import mage.target.common.TargetOpponent;
@@ -120,7 +119,7 @@ class CarpetOfFlowersEffect extends ManaEffect {
CarpetOfFlowersEffect() {
super();
- staticText = "add X mana of any one color, where X is the number of Islands target opponent controls";
+ staticText = "you may add X mana of any one color, where X is the number of Islands target opponent controls";
}
CarpetOfFlowersEffect(final CarpetOfFlowersEffect effect) {
@@ -131,7 +130,7 @@ class CarpetOfFlowersEffect extends ManaEffect {
public List getNetMana(Game game, Ability source) {
List netMana = new ArrayList<>();
if (game != null) {
- int count = game.getBattlefield().count(filter, source.getSourceId(), source.getTargets().getFirstTarget(), game);
+ int count = game.getBattlefield().count(filter, source.getTargets().getFirstTarget(), source, game);
if (count > 0) {
netMana.add(Mana.AnyMana(count));
}
@@ -148,7 +147,7 @@ class CarpetOfFlowersEffect extends ManaEffect {
Player controller = game.getPlayer(source.getControllerId());
ChoiceColor choice = new ChoiceColor();
if (controller != null && controller.choose(Outcome.Benefit, choice, game)) {
- int count = game.getBattlefield().count(filter, source.getSourceId(), source.getTargets().getFirstTarget(), game);
+ int count = game.getBattlefield().count(filter, source.getTargets().getFirstTarget(), source, game);
if (count > 0) {
switch (choice.getChoice()) {
case "Black":
diff --git a/Mage.Sets/src/mage/cards/c/CarrionThrash.java b/Mage.Sets/src/mage/cards/c/CarrionThrash.java
index 2b48d62e814..b030aabaced 100644
--- a/Mage.Sets/src/mage/cards/c/CarrionThrash.java
+++ b/Mage.Sets/src/mage/cards/c/CarrionThrash.java
@@ -1,30 +1,30 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.common.FilterCreatureCard;
-import mage.filter.predicate.mageobject.AnotherCardPredicate;
+import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class CarrionThrash extends CardImpl {
- private static final FilterCreatureCard filter = new FilterCreatureCard("another creature card from your graveyard");
+ private static final FilterCreatureCard filter = new FilterCreatureCard("another target creature card from your graveyard");
static {
- filter.add(new AnotherCardPredicate());
+ filter.add(AnotherPredicate.instance);
}
public CarrionThrash(UUID ownerId, CardSetInfo setInfo) {
@@ -36,7 +36,7 @@ public final class CarrionThrash extends CardImpl {
this.toughness = new MageInt(4);
// When Carrion Thrash dies, you may pay {2}. If you do, return another target creature card from your graveyard to your hand.
- DiesSourceTriggeredAbility ability = new DiesSourceTriggeredAbility(new DoIfCostPaid(new ReturnToHandTargetEffect(), new GenericManaCost(2)), false);
+ DiesSourceTriggeredAbility ability = new DiesSourceTriggeredAbility(new DoIfCostPaid(new ReturnFromGraveyardToHandTargetEffect(), new GenericManaCost(2)), false);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/c/CarthTheLion.java b/Mage.Sets/src/mage/cards/c/CarthTheLion.java
index aafed85ddf8..0cf232a649d 100644
--- a/Mage.Sets/src/mage/cards/c/CarthTheLion.java
+++ b/Mage.Sets/src/mage/cards/c/CarthTheLion.java
@@ -7,6 +7,7 @@ import mage.abilities.LoyaltyAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.constants.*;
import mage.cards.CardImpl;
@@ -56,9 +57,7 @@ class CarthTheLionTriggeredAbility extends TriggeredAbilityImpl {
public CarthTheLionTriggeredAbility() {
super(Zone.BATTLEFIELD, new LookLibraryAndPickControllerEffect(
- 7, 1, filter, true, false, Zone.HAND, true)
- .setBackInRandomOrder(true)
- );
+ 7, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM));
}
private CarthTheLionTriggeredAbility(final CarthTheLionTriggeredAbility ability) {
diff --git a/Mage.Sets/src/mage/cards/c/CartographersSurvey.java b/Mage.Sets/src/mage/cards/c/CartographersSurvey.java
index 3e4989f9623..47b0cfb460d 100644
--- a/Mage.Sets/src/mage/cards/c/CartographersSurvey.java
+++ b/Mage.Sets/src/mage/cards/c/CartographersSurvey.java
@@ -2,20 +2,12 @@ package mage.cards.c;
import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.dynamicvalue.common.StaticValue;
-import mage.abilities.effects.common.LookLibraryControllerEffect;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
import mage.filter.StaticFilters;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.TargetCard;
/**
*
@@ -27,7 +19,8 @@ public final class CartographersSurvey extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
// Look at the top seven cards of your library. Put up to two land cards from among them onto the battlefield tapped. Put the rest on the bottom of your library in a random order.
- this.getSpellAbility().addEffect(new CartographersSurveyEffect());
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
+ 7, 2, StaticFilters.FILTER_CARD_LANDS, PutCards.BATTLEFIELD_TAPPED, PutCards.BOTTOM_RANDOM, false));
}
private CartographersSurvey(final CartographersSurvey card) {
@@ -39,35 +32,3 @@ public final class CartographersSurvey extends CardImpl {
return new CartographersSurvey(this);
}
}
-
-class CartographersSurveyEffect extends LookLibraryControllerEffect {
-
- public CartographersSurveyEffect() {
- super(Outcome.PutLandInPlay, StaticValue.get(7), false, Zone.LIBRARY, false);
- this.setBackInRandomOrder(true);
- staticText = "Look at the top seven cards of your library. Put up to two land cards from among them onto the battlefield tapped. Put the rest on the bottom of your library in a random order";
- }
-
- private CartographersSurveyEffect(final CartographersSurveyEffect effect) {
- super(effect);
- }
-
- @Override
- public CartographersSurveyEffect copy() {
- return new CartographersSurveyEffect(this);
- }
-
- @Override
- protected void actionWithSelectedCards(Cards cards, Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- TargetCard target = new TargetCard(0, 2, Zone.LIBRARY, StaticFilters.FILTER_CARD_LANDS);
- controller.choose(outcome, cards, target, game);
- Cards pickedCards = new CardsImpl(target.getTargets());
- if (!pickedCards.isEmpty()) {
- cards.removeAll(pickedCards);
- controller.moveCards(pickedCards.getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null);
- }
- }
- }
-}
diff --git a/Mage.Sets/src/mage/cards/c/CaseTheJoint.java b/Mage.Sets/src/mage/cards/c/CaseTheJoint.java
new file mode 100644
index 00000000000..c8d8ad8d518
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CaseTheJoint.java
@@ -0,0 +1,75 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CaseTheJoint extends CardImpl {
+
+ public CaseTheJoint(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}");
+
+ // Draw two cards, then look at the top card of each player's library.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
+ this.getSpellAbility().addEffect(new CaseTheJointEffect());
+ }
+
+ private CaseTheJoint(final CaseTheJoint card) {
+ super(card);
+ }
+
+ @Override
+ public CaseTheJoint copy() {
+ return new CaseTheJoint(this);
+ }
+}
+
+class CaseTheJointEffect extends OneShotEffect {
+
+ CaseTheJointEffect() {
+ super(Outcome.Benefit);
+ staticText = ", then look at the top card of each player's library";
+ }
+
+ private CaseTheJointEffect(final CaseTheJointEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CaseTheJointEffect copy() {
+ return new CaseTheJointEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ continue;
+ }
+ Card card = player.getLibrary().getFromTop(game);
+ if (card == null) {
+ continue;
+ }
+ controller.lookAtCards(source, "Top card of " + player.getName() + "'s library", new CardsImpl(card), game);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CastleGarenbrig.java b/Mage.Sets/src/mage/cards/c/CastleGarenbrig.java
index b97b7bd31fa..e2ebf923851 100644
--- a/Mage.Sets/src/mage/cards/c/CastleGarenbrig.java
+++ b/Mage.Sets/src/mage/cards/c/CastleGarenbrig.java
@@ -90,7 +90,7 @@ enum CastleGarenbrigManaCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
if (object != null && object.isCreature(game)) {
return true;
}
diff --git a/Mage.Sets/src/mage/cards/c/Cataclysm.java b/Mage.Sets/src/mage/cards/c/Cataclysm.java
index df46dd71517..e307076e49d 100644
--- a/Mage.Sets/src/mage/cards/c/Cataclysm.java
+++ b/Mage.Sets/src/mage/cards/c/Cataclysm.java
@@ -67,8 +67,8 @@ class CataclysmEffect extends OneShotEffect {
Target target3 = new TargetControlledPermanent(1, 1, new FilterControlledEnchantmentPermanent(), true);
Target target4 = new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent(), true);
- if (target1.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target1.isChosen() && target1.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target1.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target1.isChosen() && target1.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target1, source, game);
}
Permanent artifact = game.getPermanent(target1.getFirstTarget());
@@ -78,8 +78,8 @@ class CataclysmEffect extends OneShotEffect {
target1.clearChosen();
}
- if (target2.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target2.isChosen() && target2.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target2.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target2.isChosen() && target2.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target2, source, game);
}
Permanent creature = game.getPermanent(target2.getFirstTarget());
@@ -89,8 +89,8 @@ class CataclysmEffect extends OneShotEffect {
target2.clearChosen();
}
- if (target3.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target3.isChosen() && target3.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target3.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target3.isChosen() && target3.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target3, source, game);
}
Permanent enchantment = game.getPermanent(target3.getFirstTarget());
@@ -100,8 +100,8 @@ class CataclysmEffect extends OneShotEffect {
target3.clearChosen();
}
- if (target4.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target4.isChosen() && target4.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target4.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target4.isChosen() && target4.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target4, source, game);
}
Permanent land = game.getPermanent(target4.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java b/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java
index f86a5525c8c..57e82bd582b 100644
--- a/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java
+++ b/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java
@@ -100,8 +100,8 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
Target target3 = new TargetControlledPermanent(1, 1, filterEnchantment, true);
Target target4 = new TargetControlledPermanent(1, 1, filterPlaneswalker, true);
- if (target1.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target1.isChosen() && target1.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target1.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target1.isChosen() && target1.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target1, source, game);
}
Permanent artifact = game.getPermanent(target1.getFirstTarget());
@@ -111,8 +111,8 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
target1.clearChosen();
}
- if (target2.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target2.isChosen() && target2.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target2.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target2.isChosen() && target2.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target2, source, game);
}
Permanent creature = game.getPermanent(target2.getFirstTarget());
@@ -122,8 +122,8 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
target2.clearChosen();
}
- if (target3.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target3.isChosen() && target3.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target3.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target3.isChosen() && target3.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target3, source, game);
}
Permanent enchantment = game.getPermanent(target3.getFirstTarget());
@@ -133,8 +133,8 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
target3.clearChosen();
}
- if (target4.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target4.isChosen() && target4.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target4.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target4.isChosen() && target4.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target4, source, game);
}
Permanent planeswalker = game.getPermanent(target4.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/c/Catastrophe.java b/Mage.Sets/src/mage/cards/c/Catastrophe.java
index fb8ae17279d..74ef2af9065 100644
--- a/Mage.Sets/src/mage/cards/c/Catastrophe.java
+++ b/Mage.Sets/src/mage/cards/c/Catastrophe.java
@@ -58,11 +58,11 @@ class CatastropheEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (controller.chooseUse(outcome, "Destroy all lands? (otherwise all creatures are destroyed)", source, game)) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterLandPermanent(), controller.getId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterLandPermanent(), controller.getId(), source, game)) {
permanent.destroy(source, game, permanent.isCreature(game));
}
} else {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, controller.getId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, controller.getId(), source, game)) {
permanent.destroy(source, game, true);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CatchRelease.java b/Mage.Sets/src/mage/cards/c/CatchRelease.java
index 93024ebc137..a281c668697 100644
--- a/Mage.Sets/src/mage/cards/c/CatchRelease.java
+++ b/Mage.Sets/src/mage/cards/c/CatchRelease.java
@@ -86,8 +86,8 @@ class ReleaseSacrificeEffect extends OneShotEffect {
Target target4 = new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent(), true);
Target target5 = new TargetControlledPermanent(1, 1, new FilterControlledPlaneswalkerPermanent(), true);
- if (target1.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target1.isChosen() && target1.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target1.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target1.isChosen() && target1.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target1, source, game);
}
Permanent artifact = game.getPermanent(target1.getFirstTarget());
@@ -97,8 +97,8 @@ class ReleaseSacrificeEffect extends OneShotEffect {
target1.clearChosen();
}
- if (target2.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target2.isChosen() && target2.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target2.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target2.isChosen() && target2.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target2, source, game);
}
Permanent creature = game.getPermanent(target2.getFirstTarget());
@@ -108,8 +108,8 @@ class ReleaseSacrificeEffect extends OneShotEffect {
target2.clearChosen();
}
- if (target3.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target3.isChosen() && target3.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target3.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target3.isChosen() && target3.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target3, source, game);
}
Permanent enchantment = game.getPermanent(target3.getFirstTarget());
@@ -119,8 +119,8 @@ class ReleaseSacrificeEffect extends OneShotEffect {
target3.clearChosen();
}
- if (target4.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target4.isChosen() && target4.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target4.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target4.isChosen() && target4.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target4, source, game);
}
Permanent land = game.getPermanent(target4.getFirstTarget());
@@ -130,8 +130,8 @@ class ReleaseSacrificeEffect extends OneShotEffect {
target4.clearChosen();
}
- if (target5.canChoose(source.getSourceId(), player.getId(), game)) {
- while (player.canRespond() && !target5.isChosen() && target5.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target5.canChoose(player.getId(), source, game)) {
+ while (player.canRespond() && !target5.isChosen() && target5.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.Benefit, target5, source, game);
}
Permanent planeswalker = game.getPermanent(target5.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java b/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java
index 7e976c7b309..0fbf734337d 100644
--- a/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java
+++ b/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java
@@ -1,53 +1,45 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.FilterPermanent;
-import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class CaterwaulingBoggart extends CardImpl {
- private static final FilterPermanent filterGoblin = new FilterControlledCreaturePermanent("Goblin");
- private static final FilterPermanent filterElemental = new FilterControlledCreaturePermanent("Elemental");
+ private static final FilterPermanent filter = new FilterPermanent("Goblins you control and Elementals");
static {
- filterGoblin.add(SubType.GOBLIN.getPredicate());
- filterElemental.add(SubType.ELEMENTAL.getPredicate());
+ filter.add(Predicates.or(
+ SubType.GOBLIN.getPredicate(),
+ SubType.ELEMENTAL.getPredicate()
+ ));
}
public CaterwaulingBoggart(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // Each Goblin you control has menace. (They can't be blocked except by two or more creatures.)
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(
- new MenaceAbility(),
- Duration.WhileOnBattlefield, filterGoblin,
- "Each Goblin you control has menace. (They can't be blocked except by two or more creatures.)")));
-
- // Each Elemental you control has menace. (They can't be blocked except by two or more creatures.)
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(
- new MenaceAbility(),
- Duration.WhileOnBattlefield, filterElemental,
- "Each Elemental you control has menace. (They can't be blocked except by two or more creatures.)")));
+ // Goblins you control and Elementals you control have menace.
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
+ new MenaceAbility(true), Duration.WhileOnBattlefield, filter
+ )));
}
private CaterwaulingBoggart(final CaterwaulingBoggart card) {
diff --git a/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java b/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java
index 8a5e6d559d9..cb593ab1d96 100644
--- a/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java
+++ b/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java
@@ -44,7 +44,7 @@ public final class CaughtInTheBrights extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockAttachedEffect(AttachmentType.AURA)));
// When a Vehicle you control attacks, exile enchanted creature.
- this.addAbility(new AttacksAllTriggeredAbility(new ExileAttachedEffect(), false, filter, SetTargetPointer.NONE, false));
+ this.addAbility(new AttacksAllTriggeredAbility(new ExileAttachedEffect(), false, filter, SetTargetPointer.NONE, false).setTriggerPhrase("When a Vehicle you control attacks, "));
}
private CaughtInTheBrights(final CaughtInTheBrights card) {
diff --git a/Mage.Sets/src/mage/cards/c/CauldronDance.java b/Mage.Sets/src/mage/cards/c/CauldronDance.java
index 035584db826..88c38e6fda9 100644
--- a/Mage.Sets/src/mage/cards/c/CauldronDance.java
+++ b/Mage.Sets/src/mage/cards/c/CauldronDance.java
@@ -119,7 +119,7 @@ class CauldronDancePutCreatureFromHandOntoBattlefieldEffect extends OneShotEffec
if (controller != null) {
if (controller.chooseUse(Outcome.PutCreatureInPlay, CHOICE_TEXT, source, game)) {
TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE);
- if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
+ if (controller.choose(Outcome.PutCreatureInPlay, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
diff --git a/Mage.Sets/src/mage/cards/c/CavalierOfThorns.java b/Mage.Sets/src/mage/cards/c/CavalierOfThorns.java
index f6c56822f94..7277d9269f7 100644
--- a/Mage.Sets/src/mage/cards/c/CavalierOfThorns.java
+++ b/Mage.Sets/src/mage/cards/c/CavalierOfThorns.java
@@ -5,27 +5,24 @@ import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.ExileSourceFromGraveCost;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
+import mage.abilities.effects.common.RevealLibraryPickControllerEffect;
import mage.abilities.keyword.ReachAbility;
-import mage.cards.*;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
-import mage.filter.common.FilterLandCard;
+import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.AnotherPredicate;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.TargetCard;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
- * @author TheElk801
+ * @author awjackson
*/
public final class CavalierOfThorns extends CardImpl {
@@ -46,8 +43,10 @@ public final class CavalierOfThorns extends CardImpl {
// Reach
this.addAbility(ReachAbility.getInstance());
- // When Cavalier of Thorns enters the battlefield, reveal the top five cards of your library. You may put a land card from among them onto the battlefield. Put the rest into your graveyard.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new CavalierOfThornsEffect()));
+ // When Cavalier of Thorns enters the battlefield, reveal the top five cards of your library.
+ // Put a land card from among them onto the battlefield and the rest into your graveyard.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new RevealLibraryPickControllerEffect(
+ 5, 1, StaticFilters.FILTER_CARD_LAND_A, PutCards.BATTLEFIELD, PutCards.GRAVEYARD, false)));
// When Cavalier of Thorns dies, you may exile it. If you do, put another target card from your graveyard on top of your library.
Ability ability = new DiesSourceTriggeredAbility(new DoIfCostPaid(
@@ -66,47 +65,3 @@ public final class CavalierOfThorns extends CardImpl {
return new CavalierOfThorns(this);
}
}
-
-class CavalierOfThornsEffect extends OneShotEffect {
-
- private static final FilterCard filter = new FilterLandCard("land card to put on the battlefield");
-
- CavalierOfThornsEffect() {
- super(Outcome.PutCreatureInPlay);
- this.staticText = "reveal the top five cards of your library. " +
- "Put a land card from among them onto the battlefield and the rest into your graveyard.";
- }
-
- private CavalierOfThornsEffect(final CavalierOfThornsEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller == null) {
- return false;
- }
- Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
- if (cards.isEmpty()) {
- return true;
- }
- controller.revealCards(source, cards, game);
- TargetCard target = new TargetCard(1, 1, Zone.LIBRARY, filter);
- if (cards.getCards(game).stream().anyMatch(card1 -> card1.isLand(game))
- && controller.choose(Outcome.PutCardInPlay, cards, target, game)) {
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- controller.moveCards(card, Zone.BATTLEFIELD, source, game);
- }
- }
- controller.moveCards(cards, Zone.GRAVEYARD, source, game);
- return true;
- }
-
- @Override
- public CavalierOfThornsEffect copy() {
- return new CavalierOfThornsEffect(this);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/c/CaveIn.java b/Mage.Sets/src/mage/cards/c/CaveIn.java
index 51d6cc315e9..ccccf8741c5 100644
--- a/Mage.Sets/src/mage/cards/c/CaveIn.java
+++ b/Mage.Sets/src/mage/cards/c/CaveIn.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.ExileFromHandCost;
@@ -10,27 +8,29 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterOwnedCard;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetCardInHand;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class CaveIn extends CardImpl {
- public CaveIn(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}{R}");
+ private static final FilterOwnedCard filter
+ = new FilterOwnedCard("a red card from your hand");
+ static {
+ filter.add(new ColorPredicate(ObjectColor.RED));
+ }
+
+ public CaveIn(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}");
// You may exile a red card from your hand rather than pay Cave-In's mana cost.
- FilterOwnedCard filter = new FilterOwnedCard("a red card from your hand");
- filter.add(new ColorPredicate(ObjectColor.RED));
- filter.add(Predicates.not(new CardIdPredicate(this.getId())));
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter))));
-
+
// Cave-In deals 2 damage to each creature and each player.
this.getSpellAbility().addEffect(new DamageEverythingEffect(2));
}
diff --git a/Mage.Sets/src/mage/cards/c/CavernOfSouls.java b/Mage.Sets/src/mage/cards/c/CavernOfSouls.java
index ea0ac58c26a..3acd3b26d27 100644
--- a/Mage.Sets/src/mage/cards/c/CavernOfSouls.java
+++ b/Mage.Sets/src/mage/cards/c/CavernOfSouls.java
@@ -67,7 +67,7 @@ class CavernOfSoulsManaBuilder extends ConditionalManaBuilder {
creatureType = subType;
}
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller != null && sourceObject != null && mana.getAny() == 0) {
game.informPlayers(controller.getLogName() + " produces " + mana.toString() + " with " + sourceObject.getLogName()
+ " (can only be spend to cast for creatures of type " + creatureType + " and that spell can't be countered)");
@@ -108,7 +108,7 @@ class CavernOfSoulsManaCondition extends CreatureCastManaCondition {
// check: ... to cast a creature spell
if (super.apply(game, source)) {
// check: ... of the chosen type
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
if (creatureType != null && object != null && object.hasSubtype(creatureType, game)) {
return true;
}
@@ -170,7 +170,7 @@ class CavernOfSoulsCantCounterEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject != null) {
return "This spell can't be countered because a colored mana from " + sourceObject.getName() + " was spent to cast it.";
}
diff --git a/Mage.Sets/src/mage/cards/c/CeaseFire.java b/Mage.Sets/src/mage/cards/c/CeaseFire.java
index dc559d1afe9..3683fe6f949 100644
--- a/Mage.Sets/src/mage/cards/c/CeaseFire.java
+++ b/Mage.Sets/src/mage/cards/c/CeaseFire.java
@@ -64,7 +64,7 @@ class CeaseFireEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't cast creature spells this turn (" + mageObject.getIdName() + ").";
}
diff --git a/Mage.Sets/src/mage/cards/c/CecilyHauntedMage.java b/Mage.Sets/src/mage/cards/c/CecilyHauntedMage.java
new file mode 100644
index 00000000000..d37f882a645
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CecilyHauntedMage.java
@@ -0,0 +1,87 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect;
+import mage.abilities.keyword.FriendsForeverAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CecilyHauntedMage extends CardImpl {
+
+ public CecilyHauntedMage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(5);
+
+ // Your maximum hand size is eleven.
+ this.addAbility(new SimpleStaticAbility(new MaximumHandSizeControllerEffect(
+ 11, Duration.WhileOnBattlefield, MaximumHandSizeControllerEffect.HandSizeModification.SET
+ )));
+
+ // Whenever Eleven, the Mage attacks, you draw a card and you lose 1 life. Then if you have eleven or more cards in your hand, you may cast an instant or sorcery spell from your hand without paying its mana cost.
+ this.addAbility(new AttacksTriggeredAbility(new CecilyHauntedMageEffect()));
+
+ // Friends forever
+ this.addAbility(FriendsForeverAbility.getInstance());
+ }
+
+ private CecilyHauntedMage(final CecilyHauntedMage card) {
+ super(card);
+ }
+
+ @Override
+ public CecilyHauntedMage copy() {
+ return new CecilyHauntedMage(this);
+ }
+}
+
+class CecilyHauntedMageEffect extends OneShotEffect {
+
+ CecilyHauntedMageEffect() {
+ super(Outcome.Benefit);
+ staticText = "you draw a card and you lose 1 life. Then if you have eleven or more cards in your hand, " +
+ "you may cast an instant or sorcery spell from your hand without paying its mana cost";
+ }
+
+ private CecilyHauntedMageEffect(final CecilyHauntedMageEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CecilyHauntedMageEffect copy() {
+ return new CecilyHauntedMageEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ player.drawCards(1, source, game);
+ player.loseLife(1, game, source, false);
+ return player.getHand().size() < 11
+ || CardUtil.castSpellWithAttributesForFree(
+ player, source, game, player.getHand().copy(),
+ StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY
+ );
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CelebrateTheHarvest.java b/Mage.Sets/src/mage/cards/c/CelebrateTheHarvest.java
index 47fcbcb28f7..4bf241f98c4 100644
--- a/Mage.Sets/src/mage/cards/c/CelebrateTheHarvest.java
+++ b/Mage.Sets/src/mage/cards/c/CelebrateTheHarvest.java
@@ -70,7 +70,7 @@ class CelebrateTheHarvestEffect extends OneShotEffect {
.getBattlefield()
.getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
- source.getControllerId(), source.getSourceId(), game
+ source.getControllerId(), source, game
)
.stream()
.filter(Objects::nonNull)
diff --git a/Mage.Sets/src/mage/cards/c/CelebrityFencer.java b/Mage.Sets/src/mage/cards/c/CelebrityFencer.java
new file mode 100644
index 00000000000..330e949ee84
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CelebrityFencer.java
@@ -0,0 +1,39 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.AllianceAbility;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CelebrityFencer extends CardImpl {
+
+ public CelebrityFencer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.DRUID);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Alliance — Whenever another creature enters the battlefield under your control, put a +1/+1 counter on Celebrity Fencer.
+ this.addAbility(new AllianceAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())));
+ }
+
+ private CelebrityFencer(final CelebrityFencer card) {
+ super(card);
+ }
+
+ @Override
+ public CelebrityFencer copy() {
+ return new CelebrityFencer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CelestialJudgment.java b/Mage.Sets/src/mage/cards/c/CelestialJudgment.java
index 5ac6057ad24..b62c88ea32d 100644
--- a/Mage.Sets/src/mage/cards/c/CelestialJudgment.java
+++ b/Mage.Sets/src/mage/cards/c/CelestialJudgment.java
@@ -68,7 +68,7 @@ class CelestialJudgmentEffect extends OneShotEffect {
.getBattlefield()
.getActivePermanents(
StaticFilters.FILTER_PERMANENT_CREATURE,
- source.getControllerId(), source.getSourceId(), game
+ source.getControllerId(), source, game
);
Map> powerMap = permanents
.stream()
@@ -89,7 +89,7 @@ class CelestialJudgmentEffect extends OneShotEffect {
filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, entry.getKey()));
TargetPermanent target = new TargetPermanent(filter);
target.setNotTarget(true);
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
toKeep.add(target.getFirstTarget());
}
for (Permanent permanent : permanents) {
diff --git a/Mage.Sets/src/mage/cards/c/CelestialRegulator.java b/Mage.Sets/src/mage/cards/c/CelestialRegulator.java
new file mode 100644
index 00000000000..f499ded4111
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CelestialRegulator.java
@@ -0,0 +1,91 @@
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.permanent.CounterAnyPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class CelestialRegulator extends CardImpl {
+
+ public CelestialRegulator(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
+
+ this.subtype.add(SubType.ANGEL);
+ this.subtype.add(SubType.ADVISOR);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Celestial Regulator enters the battlefield, choose target creature you don't control and tap it.
+ // If you control a creature with a counter on it, the chosen creature doesn't untap during its controller's next untap step.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new CelestialRegulatorEffect());
+ ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL));
+ this.addAbility(ability);
+ }
+
+ private CelestialRegulator(final CelestialRegulator card) {
+ super(card);
+ }
+
+ @Override
+ public CelestialRegulator copy() {
+ return new CelestialRegulator(this);
+ }
+}
+
+class CelestialRegulatorEffect extends OneShotEffect {
+
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
+
+ static {
+ filter.add(CounterAnyPredicate.instance);
+ }
+
+ public CelestialRegulatorEffect() {
+ super(Outcome.Tap);
+ this.staticText = "choose target creature you don't control and tap it. " +
+ "If you control a creature with a counter on it, the chosen creature doesn't untap during its controller's next untap step";
+ }
+
+ private CelestialRegulatorEffect(final CelestialRegulatorEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CelestialRegulatorEffect copy() {
+ return new CelestialRegulatorEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent targetCreature = game.getPermanent(source.getFirstTarget());
+ if (targetCreature == null) {
+ return false;
+ }
+ targetCreature.tap(source, game);
+ if (game.getBattlefield().count(filter, source.getControllerId(), source, game) > 0) {
+ game.addEffect(new DontUntapInControllersNextUntapStepTargetEffect(), source);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CelestusSanctifier.java b/Mage.Sets/src/mage/cards/c/CelestusSanctifier.java
index 2f14919631a..141461a4b0b 100644
--- a/Mage.Sets/src/mage/cards/c/CelestusSanctifier.java
+++ b/Mage.Sets/src/mage/cards/c/CelestusSanctifier.java
@@ -3,14 +3,12 @@ package mage.cards.c;
import mage.MageInt;
import mage.abilities.common.BecomeDayAsEntersAbility;
import mage.abilities.common.BecomesDayOrNightTriggeredAbility;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
-import mage.filter.StaticFilters;
import java.util.UUID;
@@ -31,10 +29,8 @@ public final class CelestusSanctifier extends CardImpl {
this.addAbility(new BecomeDayAsEntersAbility());
// Whenever day becomes night or night becomes day, look at the top two cards of your library. Put one of them into your graveyard.
- this.addAbility(new BecomesDayOrNightTriggeredAbility(new LookLibraryAndPickControllerEffect(
- StaticValue.get(2), false, StaticValue.get(1), StaticFilters.FILTER_CARD,
- Zone.LIBRARY, true, false, false, Zone.GRAVEYARD, false
- ).setText("look at the top two cards of your library. Put one of them into your graveyard")));
+ this.addAbility(new BecomesDayOrNightTriggeredAbility(
+ new LookLibraryAndPickControllerEffect(2, 1, PutCards.GRAVEYARD, PutCards.TOP_ANY)));
}
private CelestusSanctifier(final CelestusSanctifier card) {
diff --git a/Mage.Sets/src/mage/cards/c/CementShoes.java b/Mage.Sets/src/mage/cards/c/CementShoes.java
new file mode 100644
index 00000000000..eae1973b498
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CementShoes.java
@@ -0,0 +1,53 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author weirddan455
+ */
+public final class CementShoes extends CardImpl {
+
+ public CementShoes(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +3/+3 and has "At the beginning of your end step, tap this creature."
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(3, 3));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ new BeginningOfYourEndStepTriggeredAbility(new TapSourceEffect(), false),
+ AttachmentType.EQUIPMENT
+ ).setText("and has \"At the beginning of your end step, tap this creature.\""));
+ this.addAbility(ability);
+
+ // Equipped creature doesn't untap during its controller's untap step.
+ this.addAbility(new SimpleStaticAbility(new DontUntapInControllersUntapStepEnchantedEffect()
+ .setText("Equipped creature doesn't untap during its controller's untap step")));
+
+ // Equip {2}
+ this.addAbility(new EquipAbility(2));
+ }
+
+ private CementShoes(final CementShoes card) {
+ super(card);
+ }
+
+ @Override
+ public CementShoes copy() {
+ return new CementShoes(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CemeteryDesecrator.java b/Mage.Sets/src/mage/cards/c/CemeteryDesecrator.java
index 60b72184552..439ea276999 100644
--- a/Mage.Sets/src/mage/cards/c/CemeteryDesecrator.java
+++ b/Mage.Sets/src/mage/cards/c/CemeteryDesecrator.java
@@ -88,7 +88,7 @@ class CemeteryDesecratorEffect extends OneShotEffect {
if (controller != null) {
TargetCardInGraveyard target = new TargetCardInGraveyard(filter);
target.setNotTarget(true);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
int manaValue = card.getManaValue();
diff --git a/Mage.Sets/src/mage/cards/c/CemeteryGatekeeper.java b/Mage.Sets/src/mage/cards/c/CemeteryGatekeeper.java
index 4bdcc579128..26b3af039da 100644
--- a/Mage.Sets/src/mage/cards/c/CemeteryGatekeeper.java
+++ b/Mage.Sets/src/mage/cards/c/CemeteryGatekeeper.java
@@ -83,7 +83,7 @@ class CemeteryGatekeeperEffect extends OneShotEffect {
if (controller != null) {
TargetCardInGraveyard target = new TargetCardInGraveyard();
target.setNotTarget(true);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
diff --git a/Mage.Sets/src/mage/cards/c/CemeteryIlluminator.java b/Mage.Sets/src/mage/cards/c/CemeteryIlluminator.java
index 20d51cabb6a..160d30bba59 100644
--- a/Mage.Sets/src/mage/cards/c/CemeteryIlluminator.java
+++ b/Mage.Sets/src/mage/cards/c/CemeteryIlluminator.java
@@ -88,7 +88,7 @@ class CemeteryIlluminatorExileEffect extends OneShotEffect {
if (controller != null) {
TargetCardInGraveyard target = new TargetCardInGraveyard();
target.setNotTarget(true);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
diff --git a/Mage.Sets/src/mage/cards/c/CemeteryProtector.java b/Mage.Sets/src/mage/cards/c/CemeteryProtector.java
index 79cfa40752a..f3eed733466 100644
--- a/Mage.Sets/src/mage/cards/c/CemeteryProtector.java
+++ b/Mage.Sets/src/mage/cards/c/CemeteryProtector.java
@@ -84,7 +84,7 @@ class CemeteryProtectorEffect extends OneShotEffect {
if (controller != null) {
TargetCardInGraveyard target = new TargetCardInGraveyard();
target.setNotTarget(true);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
diff --git a/Mage.Sets/src/mage/cards/c/CemeteryProwler.java b/Mage.Sets/src/mage/cards/c/CemeteryProwler.java
index d70f7aafbe4..2c841a7d97d 100644
--- a/Mage.Sets/src/mage/cards/c/CemeteryProwler.java
+++ b/Mage.Sets/src/mage/cards/c/CemeteryProwler.java
@@ -76,7 +76,7 @@ class CemeteryProwlerExileEffect extends OneShotEffect {
if (controller != null) {
TargetCardInGraveyard target = new TargetCardInGraveyard();
target.setNotTarget(true);
- controller.choose(outcome, target, source.getSourceId(), game);
+ controller.choose(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
diff --git a/Mage.Sets/src/mage/cards/c/CemeteryPuca.java b/Mage.Sets/src/mage/cards/c/CemeteryPuca.java
index 2950b2e4c8f..cc4a08d17b5 100644
--- a/Mage.Sets/src/mage/cards/c/CemeteryPuca.java
+++ b/Mage.Sets/src/mage/cards/c/CemeteryPuca.java
@@ -57,7 +57,7 @@ class CemeteryPucaEffect extends OneShotEffect {
public CemeteryPucaEffect() {
super(Outcome.Copy);
- staticText = " {this} becomes a copy of that creature, except it has this ability";
+ staticText = "{this} becomes a copy of that creature, except it has this ability";
}
public CemeteryPucaEffect(final CemeteryPucaEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CemeteryTampering.java b/Mage.Sets/src/mage/cards/c/CemeteryTampering.java
new file mode 100644
index 00000000000..a34d2d3d826
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CemeteryTampering.java
@@ -0,0 +1,76 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.HideawayPlayEffect;
+import mage.abilities.keyword.HideawayAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CemeteryTampering extends CardImpl {
+
+ public CemeteryTampering(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
+
+ // Hideaway 5
+ this.addAbility(new HideawayAbility(5));
+
+ // At the beginning of your upkeep, you may mill three cards. Then if there are twenty or more cards in your graveyard, you may play the exiled card without paying its mana cost.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new CemeteryTamperingEffect(), TargetController.YOU, false
+ ));
+ }
+
+ private CemeteryTampering(final CemeteryTampering card) {
+ super(card);
+ }
+
+ @Override
+ public CemeteryTampering copy() {
+ return new CemeteryTampering(this);
+ }
+}
+
+class CemeteryTamperingEffect extends OneShotEffect {
+
+ CemeteryTamperingEffect() {
+ super(Outcome.Benefit);
+ staticText = "you may mill three cards. Then if there are twenty or more cards in your graveyard, " +
+ "you may play the exiled card without paying its mana cost";
+ }
+
+ private CemeteryTamperingEffect(final CemeteryTamperingEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CemeteryTamperingEffect copy() {
+ return new CemeteryTamperingEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ if (player.chooseUse(outcome, "Mill three cards?", source, game)) {
+ player.millCards(3, source, game);
+ }
+ if (player.getGraveyard().size() >= 20) {
+ new HideawayPlayEffect().apply(game, source);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CephalidFacetaker.java b/Mage.Sets/src/mage/cards/c/CephalidFacetaker.java
new file mode 100644
index 00000000000..5929e246f0f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CephalidFacetaker.java
@@ -0,0 +1,95 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfCombatTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
+import mage.abilities.keyword.CantBeBlockedSourceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.util.functions.CopyApplier;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CephalidFacetaker extends CardImpl {
+
+ public CephalidFacetaker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
+
+ this.subtype.add(SubType.CEPHALID);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(4);
+
+ // Cephalid Facetaker can't be blocked.
+ this.addAbility(new CantBeBlockedSourceAbility());
+
+ // At the beginning of combat on your turn, you may have Cephalid Facetaker become a copy of another target creature until end of turn, except its a 1/4 and has "This creature can't be blocked."
+ Ability ability = new BeginningOfCombatTriggeredAbility(
+ new CephalidFacetakerEffect(), TargetController.YOU, true
+ );
+ ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE));
+ this.addAbility(ability);
+ }
+
+ private CephalidFacetaker(final CephalidFacetaker card) {
+ super(card);
+ }
+
+ @Override
+ public CephalidFacetaker copy() {
+ return new CephalidFacetaker(this);
+ }
+}
+
+class CephalidFacetakerEffect extends OneShotEffect {
+
+ private static final CopyApplier copyApplier = new CopyApplier() {
+ @Override
+ public boolean apply(Game game, MageObject blueprint, Ability source, UUID targetObjectId) {
+ blueprint.getPower().modifyBaseValue(1);
+ blueprint.getToughness().modifyBaseValue(4);
+ blueprint.getAbilities().add(new SimpleStaticAbility(
+ new CantBeBlockedSourceEffect().setText("this creature can't be blocked")
+ ));
+ return true;
+ }
+ };
+
+ CephalidFacetakerEffect() {
+ super(Outcome.Benefit);
+ staticText = "you may have {this} become a copy of another target creature until end of turn, " +
+ "except it's 1/4 and has \"This creature can't be blocked.\"";
+ }
+
+ private CephalidFacetakerEffect(final CephalidFacetakerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CephalidFacetakerEffect copy() {
+ return new CephalidFacetakerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
+ Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (sourcePermanent == null || creature == null) {
+ return false;
+ }
+ game.copyPermanent(Duration.EndOfTurn, creature, sourcePermanent.getId(), source, copyApplier);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CephalidShrine.java b/Mage.Sets/src/mage/cards/c/CephalidShrine.java
index 32d77b5d345..66e6072566f 100644
--- a/Mage.Sets/src/mage/cards/c/CephalidShrine.java
+++ b/Mage.Sets/src/mage/cards/c/CephalidShrine.java
@@ -95,7 +95,7 @@ class CephalidShrineEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int count = 0;
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
Spell spell = (Spell) game.getState().getValue("cephalidShrine" + mageObject);
if (spell != null) {
diff --git a/Mage.Sets/src/mage/cards/c/CerebralEruption.java b/Mage.Sets/src/mage/cards/c/CerebralEruption.java
index d72297536a3..1200f337456 100644
--- a/Mage.Sets/src/mage/cards/c/CerebralEruption.java
+++ b/Mage.Sets/src/mage/cards/c/CerebralEruption.java
@@ -53,7 +53,7 @@ class CerebralEruptionEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (player != null && sourceObject != null && player.getLibrary().hasCards()) {
Card card = player.getLibrary().getFromTop(game);
Cards cards = new CardsImpl(card);
diff --git a/Mage.Sets/src/mage/cards/c/CeremonialGroundbreaker.java b/Mage.Sets/src/mage/cards/c/CeremonialGroundbreaker.java
new file mode 100644
index 00000000000..f5b5db988cd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CeremonialGroundbreaker.java
@@ -0,0 +1,56 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CeremonialGroundbreaker extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.CITIZEN, "Citizen");
+
+ public CeremonialGroundbreaker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{G}{W}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +2/+1 and has trample.
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 1));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ TrampleAbility.getInstance(), AttachmentType.EQUIPMENT
+ ).setText("and has trample"));
+ this.addAbility(ability);
+
+ // Equip Citizen {1}
+ this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(1), new TargetPermanent(filter)));
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(3));
+ }
+
+ private CeremonialGroundbreaker(final CeremonialGroundbreaker card) {
+ super(card);
+ }
+
+ @Override
+ public CeremonialGroundbreaker copy() {
+ return new CeremonialGroundbreaker(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CeruleanWisps.java b/Mage.Sets/src/mage/cards/c/CeruleanWisps.java
index 3cc5469f800..bfb26fbc714 100644
--- a/Mage.Sets/src/mage/cards/c/CeruleanWisps.java
+++ b/Mage.Sets/src/mage/cards/c/CeruleanWisps.java
@@ -28,7 +28,7 @@ public final class CeruleanWisps extends CardImpl {
this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature"));
// Draw a card.
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
"));
}
public CeruleanWisps (final CeruleanWisps card) {
diff --git a/Mage.Sets/src/mage/cards/c/Chainbreaker.java b/Mage.Sets/src/mage/cards/c/Chainbreaker.java
index b45f94e5122..ac21c9ced0b 100644
--- a/Mage.Sets/src/mage/cards/c/Chainbreaker.java
+++ b/Mage.Sets/src/mage/cards/c/Chainbreaker.java
@@ -1,51 +1,51 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class Chainbreaker extends CardImpl {
-
+
public Chainbreaker(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
this.subtype.add(SubType.SCARECROW);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Chainbreaker enters the battlefield with two -1/-1 counters on it.
- this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2), false), "with two -1/-1 counters on it"));
+ this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(
+ CounterType.M1M1.createInstance(2), false
+ ), "with two -1/-1 counters on it"));
// {3}, {tap}: Remove a -1/-1 counter from target creature.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RemoveCounterTargetEffect(CounterType.M1M1.createInstance()), new ManaCostsImpl("{3}"));
+ Ability ability = new SimpleActivatedAbility(
+ new RemoveCounterTargetEffect(CounterType.M1M1.createInstance()), new GenericManaCost(3)
+ );
ability.addCost(new TapSourceCost());
- ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("target creature")));
+ ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
-
}
-
+
private Chainbreaker(final Chainbreaker card) {
super(card);
}
-
+
@Override
public Chainbreaker copy() {
return new Chainbreaker(this);
diff --git a/Mage.Sets/src/mage/cards/c/ChandraAblaze.java b/Mage.Sets/src/mage/cards/c/ChandraAblaze.java
index 2e665564dff..9806fd544c3 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraAblaze.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraAblaze.java
@@ -3,7 +3,6 @@ package mage.cards.c;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardAllEffect;
@@ -11,23 +10,23 @@ import mage.abilities.effects.common.discard.DiscardHandAllEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
+import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
-import mage.filter.predicate.Predicates;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterInstantOrSorceryCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
-import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetDiscard;
+import mage.util.CardUtil;
-import java.util.Set;
import java.util.UUID;
-import mage.ApprovingObject;
/**
* @author North
@@ -39,7 +38,7 @@ public final class ChandraAblaze extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
LoyaltyAbility ability = new LoyaltyAbility(new ChandraAblazeEffect1(), 1);
@@ -88,7 +87,7 @@ class ChandraAblazeEffect1 extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
TargetDiscard target = new TargetDiscard(player.getId());
- player.choose(Outcome.Discard, target, source.getSourceId(), game);
+ player.choose(Outcome.Discard, target, source, game);
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
player.discard(card, false, source, game);
@@ -139,6 +138,12 @@ class ChandraAblazeEffect2 extends OneShotEffect {
class ChandraAblazeEffect5 extends OneShotEffect {
+ private static final FilterCard filter = new FilterInstantOrSorceryCard();
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.RED));
+ }
+
public ChandraAblazeEffect5() {
super(Outcome.PlayForFree);
this.staticText = "Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs";
@@ -155,33 +160,17 @@ class ChandraAblazeEffect5 extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
+ // Under this card's current oracle wording, it only casts red instant or sorcery cards
+ // This may have been a mistake which could change in the future
Player player = game.getPlayer(source.getControllerId());
- if (player != null) {
- FilterCard filter = new FilterCard("red instant or sorcery card from your graveyard to play");
- filter.add(new ColorPredicate(ObjectColor.RED));
- filter.add(Predicates.or(
- CardType.INSTANT.getPredicate(),
- CardType.SORCERY.getPredicate()));
-
- String message = "Play red instant or sorcery card from your graveyard without paying its mana cost?";
- Set cards = player.getGraveyard().getCards(filter, game);
- TargetCardInGraveyard target = new TargetCardInGraveyard(filter);
- while (!cards.isEmpty() && player.chooseUse(outcome, message, source, game)) {
- target.clearChosen();
- if (player.choose(outcome, target, source.getSourceId(), game)) {
- Card card = game.getCard(target.getFirstTarget());
- if (card != null) {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- player.cast(player.chooseAbilityForCast(card, game, true), game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
-
- cards.remove(card);
- }
- }
- }
-
- return true;
+ if (player == null) {
+ return false;
}
- return false;
+ CardUtil.castMultipleWithAttributeForFree(
+ player, source, game,
+ new CardsImpl(player.getGraveyard().getCards(filter, game)),
+ StaticFilters.FILTER_CARD
+ );
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ChandraAcolyteOfFlame.java b/Mage.Sets/src/mage/cards/c/ChandraAcolyteOfFlame.java
index acce249973c..2ceeb02b127 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraAcolyteOfFlame.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraAcolyteOfFlame.java
@@ -3,7 +3,6 @@ package mage.cards.c;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.*;
import mage.abilities.effects.common.InfoEffect;
@@ -55,7 +54,7 @@ public final class ChandraAcolyteOfFlame extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// 0: Put a loyalty counter on each red planeswalker you control.
this.addAbility(new LoyaltyAbility(new AddCountersAllEffect(CounterType.LOYALTY.createInstance(), filter), 0));
diff --git a/Mage.Sets/src/mage/cards/c/ChandraAwakenedInferno.java b/Mage.Sets/src/mage/cards/c/ChandraAwakenedInferno.java
index a9781b1009a..d188189f6f1 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraAwakenedInferno.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraAwakenedInferno.java
@@ -3,7 +3,6 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.CantBeCounteredSourceAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.GetXLoyaltyValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllEffect;
@@ -40,7 +39,7 @@ public final class ChandraAwakenedInferno extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(6));
+ this.setStartingLoyalty(6);
// This spell can't be countered.
this.addAbility(new CantBeCounteredSourceAbility());
diff --git a/Mage.Sets/src/mage/cards/c/ChandraBoldPyromancer.java b/Mage.Sets/src/mage/cards/c/ChandraBoldPyromancer.java
index 3687ef58e82..c48a05742d8 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraBoldPyromancer.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraBoldPyromancer.java
@@ -5,7 +5,6 @@ import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
@@ -30,7 +29,7 @@ public final class ChandraBoldPyromancer extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +1: Add {R}{R}. Chandra, Bold Pyromancer deals 2 damage to target player.
Ability ability = new LoyaltyAbility(new BasicManaEffect(Mana.RedMana(2)), +1);
diff --git a/Mage.Sets/src/mage/cards/c/ChandraDressedToKill.java b/Mage.Sets/src/mage/cards/c/ChandraDressedToKill.java
index ead71a7256e..be5a74be307 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraDressedToKill.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraDressedToKill.java
@@ -7,7 +7,6 @@ import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.GetEmblemEffect;
@@ -39,7 +38,7 @@ public final class ChandraDressedToKill extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: Add {R}. Chandra, Dressed to Kill deals 1 damage to up to one target player or planeswalker.
Ability ability = new LoyaltyAbility(new AddManaToManaPoolSourceControllerEffect(new Mana(ManaType.RED, 1)), 1);
diff --git a/Mage.Sets/src/mage/cards/c/ChandraFireArtisan.java b/Mage.Sets/src/mage/cards/c/ChandraFireArtisan.java
index bd3011a153a..85cb7459a98 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraFireArtisan.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraFireArtisan.java
@@ -4,7 +4,6 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.TriggeredAbilityImpl;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@@ -29,7 +28,7 @@ public final class ChandraFireArtisan extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// Whenever one or more loyalty counters are removed from Chandra, Fire Artisan, she deals that much damage to target opponent or planeswalker.
this.addAbility(new ChandraFireArtisanTriggeredAbility());
diff --git a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java
index 7a27babd504..97e7fa43803 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java
@@ -2,7 +2,6 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.GetXLoyaltyValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
@@ -30,7 +29,7 @@ public final class ChandraFlamecaller extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Create two 3/1 red Elemental creature tokens with haste. Exile them at the beginning of the next end step.
this.addAbility(new LoyaltyAbility(new ChandraElementalEffect(), 1));
diff --git a/Mage.Sets/src/mage/cards/c/ChandraFlamesCatalyst.java b/Mage.Sets/src/mage/cards/c/ChandraFlamesCatalyst.java
index 9c78e245a3e..91763674b5d 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraFlamesCatalyst.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraFlamesCatalyst.java
@@ -3,7 +3,6 @@ package mage.cards.c;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.CastCardFromGraveyardThenExileItEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamagePlayersEffect;
@@ -39,7 +38,7 @@ public final class ChandraFlamesCatalyst extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +1: Chandra, Flame's Catalyst deals 3 damage to each opponent.
this.addAbility(new LoyaltyAbility(new DamagePlayersEffect(3, TargetController.OPPONENT), 1));
diff --git a/Mage.Sets/src/mage/cards/c/ChandraFlamesFury.java b/Mage.Sets/src/mage/cards/c/ChandraFlamesFury.java
index 454b0153f82..8ed4fa1f39e 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraFlamesFury.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraFlamesFury.java
@@ -2,7 +2,6 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@@ -32,7 +31,7 @@ public final class ChandraFlamesFury extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Chandra, Flame's Fury deals 2 damage to any target.
Ability ability = new LoyaltyAbility(new DamageTargetEffect(2), 1);
diff --git a/Mage.Sets/src/mage/cards/c/ChandraGremlinWrangler.java b/Mage.Sets/src/mage/cards/c/ChandraGremlinWrangler.java
index 643baa27a87..d4cf5ff5619 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraGremlinWrangler.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraGremlinWrangler.java
@@ -2,7 +2,6 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.CreateTokenEffect;
@@ -37,7 +36,7 @@ public final class ChandraGremlinWrangler extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: Create a 2/2 red Gremlin creature token.
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new GremlinToken()), 1));
diff --git a/Mage.Sets/src/mage/cards/c/ChandraHeartOfFire.java b/Mage.Sets/src/mage/cards/c/ChandraHeartOfFire.java
index 4453a0e4263..fbf1ddfd3bb 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraHeartOfFire.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraHeartOfFire.java
@@ -4,7 +4,6 @@ import mage.Mana;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@@ -43,7 +42,7 @@ public final class ChandraHeartOfFire extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +1: Discard your hand, then exile the top three cards of your library. Until end of turn, you may play cards exiled this way.
Ability ability = new LoyaltyAbility(new DiscardHandControllerEffect(), 1);
@@ -102,16 +101,16 @@ class ChandraHeartOfFireUltimateEffect extends OneShotEffect {
// from graveyard
Target target = new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, filter, true).withChooseHint("from graveyard");
- if (target.canChoose(source.getSourceId(), controller.getId(), game)
- && target.choose(Outcome.AIDontUseIt, controller.getId(), source.getSourceId(), game)) {
+ if (target.canChoose(controller.getId(), source, game)
+ && target.choose(Outcome.AIDontUseIt, controller.getId(), source.getSourceId(), source, game)) {
Set cards = new CardsImpl(target.getTargets()).getCards(game);
exiledCards.addAll(cards);
}
// from library
target = new TargetCardInLibrary(0, Integer.MAX_VALUE, filter).withChooseHint("from library");
- if (target.canChoose(source.getSourceId(), controller.getId(), game)
- && target.choose(Outcome.AIDontUseIt, controller.getId(), source.getSourceId(), game)) {
+ if (target.canChoose(controller.getId(), source, game)
+ && target.choose(Outcome.AIDontUseIt, controller.getId(), source.getSourceId(), source, game)) {
Set cards = new CardsImpl(target.getTargets()).getCards(game);
exiledCards.addAll(cards);
}
diff --git a/Mage.Sets/src/mage/cards/c/ChandraNalaar.java b/Mage.Sets/src/mage/cards/c/ChandraNalaar.java
index 09c6b329535..f4ef053a684 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraNalaar.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraNalaar.java
@@ -2,7 +2,6 @@
package mage.cards.c;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.GetXLoyaltyValue;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
@@ -28,7 +27,7 @@ public final class ChandraNalaar extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(6));
+ this.setStartingLoyalty(6);
// +1: Chandra Nalaar deals 1 damage to target player or planeswalker.
LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1);
diff --git a/Mage.Sets/src/mage/cards/c/ChandraNovicePyromancer.java b/Mage.Sets/src/mage/cards/c/ChandraNovicePyromancer.java
index e262ee17f94..cfa960e489b 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraNovicePyromancer.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraNovicePyromancer.java
@@ -3,7 +3,6 @@ package mage.cards.c;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.mana.BasicManaEffect;
@@ -31,7 +30,7 @@ public final class ChandraNovicePyromancer extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +1: Elementals you control get +2/+0 until end of turn.
this.addAbility(new LoyaltyAbility(
diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java b/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java
index 3c4249d7b1b..37977180130 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java
@@ -3,7 +3,6 @@ package mage.cards.c;
import java.util.UUID;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
@@ -31,7 +30,7 @@ public final class ChandraPyrogenius extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+ this.setStartingLoyalty(5);
// +2: Chandra, Pyrogenius deals 2 damage to each opponent.
this.addAbility(new LoyaltyAbility(new DamagePlayersEffect(Outcome.Damage, StaticValue.get(2), TargetController.OPPONENT), 2));
diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java
index 7ab9781e7c0..e267aa4e980 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java
@@ -7,7 +7,6 @@ import mage.ApprovingObject;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
@@ -36,7 +35,7 @@ public final class ChandraPyromaster extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to
// up to one target creature that player controls. That creature can't block this turn.
@@ -127,16 +126,16 @@ class ChandraPyromasterTarget extends TargetPermanent {
}
@Override
- public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
- Set availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
+ public Set possibleTargets(UUID sourceControllerId, Ability source, Game game) {
+ Set availablePossibleTargets = super.possibleTargets(sourceControllerId, source, game);
Set possibleTargets = new HashSet<>();
- MageObject object = game.getObject(sourceId);
+ MageObject object = game.getObject(source);
for (StackObject item : game.getState().getStack()) {
- if (item.getId().equals(sourceId)) {
+ if (item.getId().equals(source.getSourceId())) {
object = item;
}
- if (item.getSourceId().equals(sourceId)) {
+ if (item.getSourceId().equals(source.getSourceId())) {
object = item;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ChandraRoaringFlame.java b/Mage.Sets/src/mage/cards/c/ChandraRoaringFlame.java
index 0308ad1de7d..ce08c704fe1 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraRoaringFlame.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraRoaringFlame.java
@@ -2,7 +2,6 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
@@ -34,7 +33,7 @@ public final class ChandraRoaringFlame extends CardImpl {
this.nightCard = true;
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Chandra, Roaring Flame deals 2 damage to target player.
LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), 1);
diff --git a/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java b/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java
index 2f18156678f..aa85c501d14 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java
@@ -4,7 +4,6 @@ package mage.cards.c;
import java.util.UUID;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CopyTargetSpellEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
@@ -32,7 +31,7 @@ public final class ChandraTheFirebrand extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
+ this.setStartingLoyalty(3);
// +1: Chandra, the Firebrand deals 1 damage to any target.
LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1);
diff --git a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java
index 0f921f1fd25..651e30a7e38 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java
@@ -6,7 +6,6 @@ import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
@@ -38,7 +37,7 @@ public final class ChandraTorchOfDefiance extends CardImpl {
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
- this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+ this.setStartingLoyalty(4);
// +1: Exile the top card of your library. You may cast that card. If you don't, Chandra, Torch of Defiance deals 2 damage to each opponent.
LoyaltyAbility ability = new LoyaltyAbility(new ChandraTorchOfDefianceEffect(), 1);
diff --git a/Mage.Sets/src/mage/cards/c/ChandrasEmbercat.java b/Mage.Sets/src/mage/cards/c/ChandrasEmbercat.java
index e5f9e25542d..cfad9feed45 100644
--- a/Mage.Sets/src/mage/cards/c/ChandrasEmbercat.java
+++ b/Mage.Sets/src/mage/cards/c/ChandrasEmbercat.java
@@ -69,7 +69,7 @@ class ChandrasEmbercatElementalManaCondition extends CreatureCastManaCondition {
if (!super.apply(game, source)) {
return false;
}
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
if (object == null) {
return false;
}
@@ -84,7 +84,7 @@ class ChandrasEmbercatPlaneswalkerManaCondition extends PlaneswalkerCastManaCond
if (!super.apply(game, source)) {
return false;
}
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
if (object == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/ChandrasIgnition.java b/Mage.Sets/src/mage/cards/c/ChandrasIgnition.java
index 28393821c59..9398409ceb1 100644
--- a/Mage.Sets/src/mage/cards/c/ChandrasIgnition.java
+++ b/Mage.Sets/src/mage/cards/c/ChandrasIgnition.java
@@ -57,7 +57,7 @@ class ChandrasIgnitionEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetCreature != null && targetCreature.getPower().getValue() > 0) {
- for (Permanent creature : game.getState().getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent creature : game.getState().getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source, game)) {
if (!creature.getId().equals(targetCreature.getId())) {
creature.damage(targetCreature.getPower().getValue(), targetCreature.getId(), source, game, false, true);
}
diff --git a/Mage.Sets/src/mage/cards/c/ChandrasTriumph.java b/Mage.Sets/src/mage/cards/c/ChandrasTriumph.java
index 356df7abe44..6fe22ed35fd 100644
--- a/Mage.Sets/src/mage/cards/c/ChandrasTriumph.java
+++ b/Mage.Sets/src/mage/cards/c/ChandrasTriumph.java
@@ -75,7 +75,7 @@ class ChandrasTriumphEffect extends OneShotEffect {
return false;
}
int damage = 3;
- if (!game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game).isEmpty()) {
+ if (!game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game).isEmpty()) {
damage = 5;
}
return permanent.damage(damage, source.getSourceId(), source, game) > 0;
diff --git a/Mage.Sets/src/mage/cards/c/ChangeOfPlans.java b/Mage.Sets/src/mage/cards/c/ChangeOfPlans.java
new file mode 100644
index 00000000000..4ec4a4f7507
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChangeOfPlans.java
@@ -0,0 +1,112 @@
+package mage.cards.c;
+
+import mage.MageItem;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.keyword.ConniveSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.PermanentIdPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.targetadjustment.TargetAdjuster;
+
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class ChangeOfPlans extends CardImpl {
+
+ public ChangeOfPlans(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{1}{U}");
+
+ // Each of X target creatures you control connive. You may have any number of them phase out.
+ this.getSpellAbility().addEffect(new ChangeOfPlansEffect());
+ this.getSpellAbility().setTargetAdjuster(ChangeOfPlansAdjuster.instance);
+ }
+
+ private ChangeOfPlans(final ChangeOfPlans card) {
+ super(card);
+ }
+
+ @Override
+ public ChangeOfPlans copy() {
+ return new ChangeOfPlans(this);
+ }
+}
+
+enum ChangeOfPlansAdjuster implements TargetAdjuster {
+ instance;
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ ability.getTargets().clear();
+ ability.addTarget(new TargetControlledCreaturePermanent(ability.getManaCostsToPay().getX()));
+ }
+}
+
+class ChangeOfPlansEffect extends OneShotEffect {
+
+ ChangeOfPlansEffect() {
+ super(Outcome.Benefit);
+ staticText = "each of X target creatures you control connive. You may have any number of them phase out";
+ }
+
+ private ChangeOfPlansEffect(final ChangeOfPlansEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ChangeOfPlansEffect copy() {
+ return new ChangeOfPlansEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Set permanents = this
+ .getTargetPointer()
+ .getTargets(game, source)
+ .stream()
+ .map(game::getPermanent)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ if (permanents.isEmpty()) {
+ return false;
+ }
+ for (Permanent permanent : permanents) {
+ ConniveSourceEffect.connive(permanent, 1, source, game);
+ }
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return true;
+ }
+ FilterPermanent filter = new FilterPermanent("creatures");
+ filter.add(Predicates.or(
+ permanents
+ .stream()
+ .map(MageItem::getId)
+ .map(PermanentIdPredicate::new)
+ .collect(Collectors.toSet())
+ ));
+ TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
+ player.choose(outcome, target.withChooseHint("to phase out"), source, game);
+ for (UUID targetId : target.getTargets()) {
+ Permanent permanent = game.getPermanent(targetId);
+ if (permanent != null) {
+ permanent.phaseOut(game);
+ }
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java b/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java
index 80845e7b462..9559c1ce355 100644
--- a/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java
+++ b/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java
@@ -30,7 +30,7 @@ public final class ChangelingBerserker extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// Champion a creature
- this.addAbility(new ChampionAbility(this, true));
+ this.addAbility(new ChampionAbility(this));
}
private ChangelingBerserker(final ChangelingBerserker card) {
diff --git a/Mage.Sets/src/mage/cards/c/ChangelingHero.java b/Mage.Sets/src/mage/cards/c/ChangelingHero.java
index a8f1c038fee..51d00ce67af 100644
--- a/Mage.Sets/src/mage/cards/c/ChangelingHero.java
+++ b/Mage.Sets/src/mage/cards/c/ChangelingHero.java
@@ -27,7 +27,7 @@ public final class ChangelingHero extends CardImpl {
this.addAbility(new ChangelingAbility());
// Champion a creature
- this.addAbility(new ChampionAbility(this, true));
+ this.addAbility(new ChampionAbility(this));
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
diff --git a/Mage.Sets/src/mage/cards/c/ChangelingTitan.java b/Mage.Sets/src/mage/cards/c/ChangelingTitan.java
index 85905b743aa..40e80e26d90 100644
--- a/Mage.Sets/src/mage/cards/c/ChangelingTitan.java
+++ b/Mage.Sets/src/mage/cards/c/ChangelingTitan.java
@@ -26,7 +26,7 @@ public final class ChangelingTitan extends CardImpl {
this.addAbility(new ChangelingAbility());
// Champion a creature
- this.addAbility(new ChampionAbility(this, true));
+ this.addAbility(new ChampionAbility(this));
}
private ChangelingTitan(final ChangelingTitan card) {
diff --git a/Mage.Sets/src/mage/cards/c/ChanneledForce.java b/Mage.Sets/src/mage/cards/c/ChanneledForce.java
index 7e933d29193..698172bc82b 100644
--- a/Mage.Sets/src/mage/cards/c/ChanneledForce.java
+++ b/Mage.Sets/src/mage/cards/c/ChanneledForce.java
@@ -25,7 +25,7 @@ public final class ChanneledForce extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{R}");
// As an additional cost to cast this spell, discard X cards.
- this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
+ this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS));
// Target player draws X cards. Channeled Force deals X damage to up to one target creature or planeswalker.
this.getSpellAbility().addEffect(new ChanneledForceEffect());
diff --git a/Mage.Sets/src/mage/cards/c/ChaosCharm.java b/Mage.Sets/src/mage/cards/c/ChaosCharm.java
index 635794fdf76..a840b36e5b8 100644
--- a/Mage.Sets/src/mage/cards/c/ChaosCharm.java
+++ b/Mage.Sets/src/mage/cards/c/ChaosCharm.java
@@ -35,13 +35,11 @@ public final class ChaosCharm extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
// or Chaos Charm deals 1 damage to target creature
- Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(1));
+ Mode mode = new Mode(new DamageTargetEffect(1));
mode.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addMode(mode);
// or target creature gains haste until end of turn.
- mode = new Mode();
- mode.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
+ mode = new Mode(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
mode.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java
index 09751d57866..9137e0b68d7 100644
--- a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java
+++ b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -11,16 +9,13 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author L_J
*/
public final class ChaosHarlequin extends CardImpl {
@@ -32,7 +27,7 @@ public final class ChaosHarlequin extends CardImpl {
this.toughness = new MageInt(4);
// {R}: Exile the top card of your library. If that card is a land card, Chaos Harlequin gets -4/-0 until end of turn. Otherwise, Chaos Harlequin gets +2/+0 until end of turn.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChaosHarlequinEffect(), new ManaCostsImpl("{R}")));
+ this.addAbility(new SimpleActivatedAbility(new ChaosHarlequinEffect(), new ManaCostsImpl<>("{R}")));
}
private ChaosHarlequin(final ChaosHarlequin card) {
@@ -49,7 +44,8 @@ class ChaosHarlequinEffect extends OneShotEffect {
public ChaosHarlequinEffect() {
super(Outcome.Benefit);
- this.staticText = "Exile the top card of your library. If that card is a land card, {this} gets -4/-0 until end of turn. Otherwise, {this} gets +2/+0 until end of turn";
+ this.staticText = "Exile the top card of your library. If that card is a land card, " +
+ "{this} gets -4/-0 until end of turn. Otherwise, {this} gets +2/+0 until end of turn";
}
public ChaosHarlequinEffect(final ChaosHarlequinEffect effect) {
@@ -64,18 +60,15 @@ class ChaosHarlequinEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
- if (player != null) {
- Card card = player.getLibrary().getFromTop(game);
- if (card != null) {
- player.moveCardToExileWithInfo(card, null, "", source, game, Zone.LIBRARY, true);
- if (card.isLand(game)) {
- game.addEffect(new BoostSourceEffect(-4, 0, Duration.EndOfTurn), source);
- } else {
- game.addEffect(new BoostSourceEffect(2, 0, Duration.EndOfTurn), source);
- }
- }
- return true;
+ if (player == null) {
+ return false;
}
- return false;
+ Card card = player.getLibrary().getFromTop(game);
+ if (card == null) {
+ return false;
+ }
+ player.moveCards(card, Zone.EXILED, source, game);
+ game.addEffect(new BoostSourceEffect(card.isLand(game) ? -4 : 2, 0, Duration.EndOfTurn), source);
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ChaosMoon.java b/Mage.Sets/src/mage/cards/c/ChaosMoon.java
index 6741496ba70..b389e080d3f 100644
--- a/Mage.Sets/src/mage/cards/c/ChaosMoon.java
+++ b/Mage.Sets/src/mage/cards/c/ChaosMoon.java
@@ -81,7 +81,7 @@ class ChaosMoonEffect extends OneShotEffect {
return false;
}
int permanentsInPlay = game.getBattlefield().count(
- StaticFilters.FILTER_PERMANENT, source.getSourceId(), source.getControllerId(), game
+ StaticFilters.FILTER_PERMANENT, source.getControllerId(), source, game
);
// Odd
if (permanentsInPlay % 2 == 1) {
diff --git a/Mage.Sets/src/mage/cards/c/ChaosWand.java b/Mage.Sets/src/mage/cards/c/ChaosWand.java
index 9fc955531ee..0f9fd6e5693 100644
--- a/Mage.Sets/src/mage/cards/c/ChaosWand.java
+++ b/Mage.Sets/src/mage/cards/c/ChaosWand.java
@@ -12,9 +12,9 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetOpponent;
+import mage.util.CardUtil;
import java.util.UUID;
-import mage.ApprovingObject;
/**
* @author TheElk801
@@ -28,10 +28,7 @@ public final class ChaosWand extends CardImpl {
// until they exile an instant or sorcery card. You may cast that card
// without paying its mana cost. Then put the exiled cards that weren't
// cast this way on the bottom of that library in a random order.
- Ability ability = new SimpleActivatedAbility(
- new ChaosWandEffect(),
- new GenericManaCost(4)
- );
+ Ability ability = new SimpleActivatedAbility(new ChaosWandEffect(), new GenericManaCost(4));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
@@ -80,25 +77,15 @@ class ChaosWandEffect extends OneShotEffect {
if (card == null) {
break;
}
+ cardsToShuffle.add(card);
opponent.moveCards(card, Zone.EXILED, source, game);
- controller.revealCards(source, new CardsImpl(card), game);
if (card.isInstantOrSorcery(game)) {
- boolean cardWasCast = false;
- if (controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName()
- + " without paying its mana cost?", source, game)) {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- }
- if (!cardWasCast) {
- cardsToShuffle.add(card);
- }
+ CardUtil.castSpellWithAttributesForFree(controller, source, game, card);
break;
- } else {
- cardsToShuffle.add(card);
}
}
+ cardsToShuffle.retainZone(Zone.EXILED, game);
+ controller.revealCards(source, cardsToShuffle, game);
return opponent.putCardsOnBottomOfLibrary(cardsToShuffle, game, source, false);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ChaosWarp.java b/Mage.Sets/src/mage/cards/c/ChaosWarp.java
index 3d24bfa2ec7..06308ce2694 100644
--- a/Mage.Sets/src/mage/cards/c/ChaosWarp.java
+++ b/Mage.Sets/src/mage/cards/c/ChaosWarp.java
@@ -98,7 +98,7 @@ class ChaosWarpRevealEffect extends OneShotEffect {
return false;
}
Player owner = game.getPlayer(permanent.getOwnerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (owner == null || sourceObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/Chaosphere.java b/Mage.Sets/src/mage/cards/c/Chaosphere.java
index 166e589e985..ae385300615 100644
--- a/Mage.Sets/src/mage/cards/c/Chaosphere.java
+++ b/Mage.Sets/src/mage/cards/c/Chaosphere.java
@@ -74,7 +74,7 @@ class ChaosphereEffect extends RestrictionEffect {
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
- return filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
+ return filter.match(permanent, source.getControllerId(), source, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/c/ChargingSlateback.java b/Mage.Sets/src/mage/cards/c/ChargingSlateback.java
index 455426b6bef..af0cfb5bb5a 100644
--- a/Mage.Sets/src/mage/cards/c/ChargingSlateback.java
+++ b/Mage.Sets/src/mage/cards/c/ChargingSlateback.java
@@ -26,7 +26,7 @@ public final class ChargingSlateback extends CardImpl {
// Charging Slateback can't block.
this.addAbility(new CantBlockAbility());
// Morph {4}{R}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{4}{R}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{4}{R}")));
}
private ChargingSlateback(final ChargingSlateback card) {
diff --git a/Mage.Sets/src/mage/cards/c/CharmedGriffin.java b/Mage.Sets/src/mage/cards/c/CharmedGriffin.java
index b751cbf3692..d5ab22e938d 100644
--- a/Mage.Sets/src/mage/cards/c/CharmedGriffin.java
+++ b/Mage.Sets/src/mage/cards/c/CharmedGriffin.java
@@ -76,9 +76,9 @@ class CharmedGriffinEffect extends OneShotEffect {
Player player = game.getPlayer(playerId);
if (player != null) {
TargetCardInHand target = new TargetCardInHand(new FilterArtifactOrEnchantmentCard());
- if (target.canChoose(source.getSourceId(), playerId, game)
+ if (target.canChoose(playerId, source, game)
&& player.chooseUse(Outcome.Neutral, "Put an artifact or enchantment card from your hand onto the battlefield?", source, game)
- && player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
+ && player.choose(Outcome.PutCardInPlay, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
toBattlefield.add(card);
diff --git a/Mage.Sets/src/mage/cards/c/CharmingPrince.java b/Mage.Sets/src/mage/cards/c/CharmingPrince.java
index da9fde85774..16623a0ebca 100644
--- a/Mage.Sets/src/mage/cards/c/CharmingPrince.java
+++ b/Mage.Sets/src/mage/cards/c/CharmingPrince.java
@@ -90,7 +90,7 @@ class CharmingPrinceEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller == null || sourceObject == null) {
return false;
}
@@ -98,9 +98,7 @@ class CharmingPrinceEffect extends OneShotEffect {
if (permanent == null) {
return false;
}
- if (!controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source, game, Zone.BATTLEFIELD, true)) {
- return false;
- }
+ controller.moveCards(permanent, Zone.EXILED, source, game);
//create delayed triggered ability
Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect();
effect.setText("Return it to the battlefield under your control at the beginning of the next end step");
diff --git a/Mage.Sets/src/mage/cards/c/ChecksAndBalances.java b/Mage.Sets/src/mage/cards/c/ChecksAndBalances.java
index f6fb669a3a3..2e44f6c2c66 100644
--- a/Mage.Sets/src/mage/cards/c/ChecksAndBalances.java
+++ b/Mage.Sets/src/mage/cards/c/ChecksAndBalances.java
@@ -11,7 +11,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SetTargetPointer;
-import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.stack.Spell;
@@ -103,7 +102,7 @@ class ChecksAndBalancesEffect extends OneShotEffect {
Player player = game.getPlayer(uuid);
if (player != null && !player.getHand().isEmpty()) {
TargetCardInHand target = new TargetCardInHand();
- if (player.choose(Outcome.Discard, target, source.getSourceId(), game)) {
+ if (player.choose(Outcome.Discard, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
player.discard(card, false, source, game);
}
diff --git a/Mage.Sets/src/mage/cards/c/ChemistersTrick.java b/Mage.Sets/src/mage/cards/c/ChemistersTrick.java
index 812b25bfdac..a8d4b4527b4 100644
--- a/Mage.Sets/src/mage/cards/c/ChemistersTrick.java
+++ b/Mage.Sets/src/mage/cards/c/ChemistersTrick.java
@@ -64,7 +64,7 @@ class ChemistersTrickEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, source.getControllerId(), source, game)) {
AttacksIfAbleTargetEffect effect = new AttacksIfAbleTargetEffect(Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(creature.getId(), game));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/c/ChillingGrasp.java b/Mage.Sets/src/mage/cards/c/ChillingGrasp.java
index 814e23d5e98..8e8c8fad06c 100644
--- a/Mage.Sets/src/mage/cards/c/ChillingGrasp.java
+++ b/Mage.Sets/src/mage/cards/c/ChillingGrasp.java
@@ -26,7 +26,7 @@ public final class ChillingGrasp extends CardImpl {
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures"));
// Madness {3}{U}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{3}{U}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl("{3}{U}")));
}
private ChillingGrasp(final ChillingGrasp card) {
diff --git a/Mage.Sets/src/mage/cards/c/ChimneyImp.java b/Mage.Sets/src/mage/cards/c/ChimneyImp.java
index 8c50b7c30f7..f817a846733 100644
--- a/Mage.Sets/src/mage/cards/c/ChimneyImp.java
+++ b/Mage.Sets/src/mage/cards/c/ChimneyImp.java
@@ -75,7 +75,7 @@ class ChimneyImpEffect extends OneShotEffect {
TargetCardInHand target = new TargetCardInHand();
target.setNotTarget(true);
target.setTargetName("a card from your hand to put on top of your library");
- targetOpponent.choose(Outcome.Detriment, target, source.getSourceId(), game);
+ targetOpponent.choose(Outcome.Detriment, target, source, game);
Card card = targetOpponent.getHand().get(target.getFirstTarget(), game);
if (card != null) {
targetOpponent.moveCardToLibraryWithInfo(card, source, game, Zone.HAND, true, false);
diff --git a/Mage.Sets/src/mage/cards/c/ChishiroTheShatteredBlade.java b/Mage.Sets/src/mage/cards/c/ChishiroTheShatteredBlade.java
index fc1d21fec3b..6f7b759adc6 100644
--- a/Mage.Sets/src/mage/cards/c/ChishiroTheShatteredBlade.java
+++ b/Mage.Sets/src/mage/cards/c/ChishiroTheShatteredBlade.java
@@ -13,7 +13,7 @@ import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
-import mage.filter.common.FilterControlledPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.ModifiedPredicate;
import mage.game.permanent.token.SpiritRedToken;
@@ -26,7 +26,7 @@ import java.util.UUID;
public final class ChishiroTheShatteredBlade extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("an Aura or Equipment");
- private static final FilterPermanent filter2 = new FilterControlledPermanent("modified creature you control");
+ private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent("modified creature you control");
static {
filter.add(Predicates.or(
diff --git a/Mage.Sets/src/mage/cards/c/ChitteringRats.java b/Mage.Sets/src/mage/cards/c/ChitteringRats.java
index 6e9a871b659..a9ff004eda8 100644
--- a/Mage.Sets/src/mage/cards/c/ChitteringRats.java
+++ b/Mage.Sets/src/mage/cards/c/ChitteringRats.java
@@ -72,7 +72,7 @@ class ChitteringRatsEffect extends OneShotEffect {
TargetCardInHand target = new TargetCardInHand();
target.setNotTarget(true);
target.setTargetName("a card from your hand to put on top of your library");
- targetOpponent.choose(Outcome.Detriment, target, source.getSourceId(), game);
+ targetOpponent.choose(Outcome.Detriment, target, source, game);
Card card = targetOpponent.getHand().get(target.getFirstTarget(), game);
if (card != null) {
targetOpponent.moveCardToLibraryWithInfo(card, source, game, Zone.HAND, true, false);
diff --git a/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java b/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java
index d4ce9c681e4..867c5d4b3a3 100644
--- a/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java
+++ b/Mage.Sets/src/mage/cards/c/ChoArrimAlchemist.java
@@ -79,7 +79,7 @@ class ChoArrimAlchemistEffect extends PreventionEffectImpl {
@Override
public void init(Ability source, Game game) {
- this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game);
+ this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/c/ChromeCat.java b/Mage.Sets/src/mage/cards/c/ChromeCat.java
new file mode 100644
index 00000000000..deaa1954c71
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChromeCat.java
@@ -0,0 +1,37 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ChromeCat extends CardImpl {
+
+ public ChromeCat(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
+
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // When Chrome Cat enters the battlefield, scry 1.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(1, false)));
+ }
+
+ private ChromeCat(final ChromeCat card) {
+ super(card);
+ }
+
+ @Override
+ public ChromeCat copy() {
+ return new ChromeCat(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChromeMox.java b/Mage.Sets/src/mage/cards/c/ChromeMox.java
index 0b7ccdc18c4..0c5f47e9c4f 100644
--- a/Mage.Sets/src/mage/cards/c/ChromeMox.java
+++ b/Mage.Sets/src/mage/cards/c/ChromeMox.java
@@ -81,7 +81,7 @@ class ChromeMoxEffect extends OneShotEffect {
target.setNotTarget(true);
Card cardToImprint = null;
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
- if (!controller.getHand().isEmpty() && controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
+ if (!controller.getHand().isEmpty() && controller.choose(Outcome.Benefit, target, source, game)) {
cardToImprint = controller.getHand().get(target.getFirstTarget(), game);
}
if (sourcePermanent != null) {
diff --git a/Mage.Sets/src/mage/cards/c/ChromeReplicator.java b/Mage.Sets/src/mage/cards/c/ChromeReplicator.java
index 3bfecae7b0c..ea8e2c44bb2 100644
--- a/Mage.Sets/src/mage/cards/c/ChromeReplicator.java
+++ b/Mage.Sets/src/mage/cards/c/ChromeReplicator.java
@@ -70,7 +70,7 @@ enum ChromeReplicatorCondition implements Condition {
return game
.getBattlefield()
.getActivePermanents(
- filter, source.getControllerId(), source.getSourceId(), game
+ filter, source.getControllerId(), source, game
).stream()
.filter(Objects::nonNull)
.map(MageObject::getName)
diff --git a/Mage.Sets/src/mage/cards/c/ChromeshellCrab.java b/Mage.Sets/src/mage/cards/c/ChromeshellCrab.java
index 9a59d61658c..2f3fc4ab1eb 100644
--- a/Mage.Sets/src/mage/cards/c/ChromeshellCrab.java
+++ b/Mage.Sets/src/mage/cards/c/ChromeshellCrab.java
@@ -34,7 +34,7 @@ public final class ChromeshellCrab extends CardImpl {
this.toughness = new MageInt(3);
// Morph {4}{U}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{4}{U}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{4}{U}")));
// When Chromeshell Crab is turned face up, you may exchange control of target creature you control and target creature an opponent controls.
Effect effect = new ExchangeControlTargetEffect(Duration.EndOfGame, rule, false, true);
diff --git a/Mage.Sets/src/mage/cards/c/ChronomanticEscape.java b/Mage.Sets/src/mage/cards/c/ChronomanticEscape.java
index a6057b39bc5..955d974369c 100644
--- a/Mage.Sets/src/mage/cards/c/ChronomanticEscape.java
+++ b/Mage.Sets/src/mage/cards/c/ChronomanticEscape.java
@@ -30,7 +30,7 @@ public final class ChronomanticEscape extends CardImpl {
getSpellAbility().addEffect(new CantAttackYouAllEffect(Duration.UntilYourNextTurn, StaticFilters.FILTER_PERMANENT_CREATURES));
getSpellAbility().addEffect(new ExileSpellEffect());
Effect effect = new AddCountersSourceEffect(CounterType.TIME.createInstance(), StaticValue.get(3), true, true);
- effect.setText("with 3 time counters on it");
+ effect.setText("with three time counters on it");
getSpellAbility().addEffect(effect);
// Suspend 3-{2}{W}
diff --git a/Mage.Sets/src/mage/cards/c/ChunLiCountlessKicks.java b/Mage.Sets/src/mage/cards/c/ChunLiCountlessKicks.java
new file mode 100644
index 00000000000..eb60a646108
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChunLiCountlessKicks.java
@@ -0,0 +1,156 @@
+package mage.cards.c;
+
+import mage.ApprovingObject;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.dynamicvalue.common.MultikickerCount;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.MultikickerAbility;
+import mage.cards.*;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.filter.FilterCard;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetCardInYourGraveyard;
+import mage.target.targetadjustment.TargetAdjuster;
+import org.apache.log4j.Logger;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ChunLiCountlessKicks extends CardImpl {
+
+ public ChunLiCountlessKicks(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Multikicker {W/U}
+ this.addAbility(new MultikickerAbility("{W/U}"));
+
+ // When Chun-Li enters the battlefield, exile up to X target instant cards from your graveyard, where X is the number of times Chun-Li was kicked. Put a kick counter on each of them.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new ChunLiCountlessKicksExileEffect())
+ .setTargetAdjuster(ChunLiCountlessKicksAdjuster.instance));
+
+ // Lightning Kick—Whenever Chun-Li attacks, copy each exiled card you own with a kick counter on it. You may cast the copies.
+ this.addAbility(new AttacksTriggeredAbility(new ChunLiCountlessKicksCastEffect()).withFlavorWord("Lightning Kick"));
+ }
+
+ private ChunLiCountlessKicks(final ChunLiCountlessKicks card) {
+ super(card);
+ }
+
+ @Override
+ public ChunLiCountlessKicks copy() {
+ return new ChunLiCountlessKicks(this);
+ }
+}
+
+enum ChunLiCountlessKicksAdjuster implements TargetAdjuster {
+ instance;
+ private static final FilterCard filter = new FilterCard("instant cards from your graveyard");
+
+ static {
+ filter.add(CardType.INSTANT.getPredicate());
+ }
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ int count = MultikickerCount.instance.calculate(game, ability, null);
+ ability.getTargets().clear();
+ ability.addTarget(new TargetCardInYourGraveyard(0, count, filter));
+ }
+}
+
+class ChunLiCountlessKicksExileEffect extends OneShotEffect {
+
+ ChunLiCountlessKicksExileEffect() {
+ super(Outcome.Benefit);
+ staticText = "exile up to X target instant cards from your graveyard, " +
+ "where X is the number of times {this} was kicked. Put a kick counter on each of them";
+ }
+
+ private ChunLiCountlessKicksExileEffect(final ChunLiCountlessKicksExileEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ChunLiCountlessKicksExileEffect copy() {
+ return new ChunLiCountlessKicksExileEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ Cards cards = new CardsImpl(getTargetPointer().getTargets(game, source));
+ if (player == null || cards.isEmpty()) {
+ return false;
+ }
+ player.moveCards(cards, Zone.EXILED, source, game);
+ cards.getCards(game).forEach(card -> card.addCounters(CounterType.KICK.createInstance(), source, game));
+ return true;
+ }
+}
+
+class ChunLiCountlessKicksCastEffect extends OneShotEffect {
+
+ ChunLiCountlessKicksCastEffect() {
+ super(Outcome.Benefit);
+ staticText = "copy each exiled card you own with a kick counter on it. You may cast the copies";
+ }
+
+ private ChunLiCountlessKicksCastEffect(final ChunLiCountlessKicksCastEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ChunLiCountlessKicksCastEffect copy() {
+ return new ChunLiCountlessKicksCastEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl(game.getExile().getAllCards(game, source.getControllerId()));
+ cards.removeIf(uuid -> !game.getCard(uuid).getCounters(game).containsKey(CounterType.KICK));
+ if (cards.isEmpty()) {
+ return false;
+ }
+ Cards copies = new CardsImpl();
+ for (Card card : cards.getCards(game)) {
+ Card copiedCard = game.copyCard(card, source, source.getControllerId());
+ game.getExile().add(source.getSourceId(), "", copiedCard);
+ game.getState().setZone(copiedCard.getId(), Zone.EXILED);
+ copies.add(copiedCard);
+ }
+ for (Card copiedCard : copies.getCards(game)) {
+ if (!player.chooseUse(outcome, "Cast the copied card?", source, game)) {
+ continue;
+ }
+ if (copiedCard.getSpellAbility() != null) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ player.cast(
+ player.chooseAbilityForCast(copiedCard, game, false),
+ game, false, new ApprovingObject(source, game)
+ );
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
+ } else {
+ Logger.getLogger(ChunLiCountlessKicksCastEffect.class).error("Chun Li, Countless Kicks: "
+ + "spell ability == null " + copiedCard.getName());
+ }
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CinderWall.java b/Mage.Sets/src/mage/cards/c/CinderWall.java
index ad72fee897c..28291f49188 100644
--- a/Mage.Sets/src/mage/cards/c/CinderWall.java
+++ b/Mage.Sets/src/mage/cards/c/CinderWall.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -29,10 +28,13 @@ public final class CinderWall extends CardImpl {
// Defender
this.addAbility(DefenderAbility.getInstance());
// When Cinder Wall blocks, destroy it at end of combat.
- this.addAbility(new BlocksSourceTriggeredAbility(
- new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new DestroySourceEffect())),
- false, false, true
- ));
+ this.addAbility(
+ new BlocksSourceTriggeredAbility(
+ new CreateDelayedTriggeredAbilityEffect(
+ new AtTheEndOfCombatDelayedTriggeredAbility(new DestroySourceEffect())
+ ).setText("destroy it at end of combat")
+ ).setTriggerPhrase("When {this} blocks, ")
+ );
}
private CinderWall(final CinderWall card) {
diff --git a/Mage.Sets/src/mage/cards/c/CinderheartGiant.java b/Mage.Sets/src/mage/cards/c/CinderheartGiant.java
index 4dc474cf9fe..41edce72e3b 100644
--- a/Mage.Sets/src/mage/cards/c/CinderheartGiant.java
+++ b/Mage.Sets/src/mage/cards/c/CinderheartGiant.java
@@ -70,7 +70,7 @@ class CinderheartGiantEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player == null || game.getBattlefield().count(
StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE,
- source.getSourceId(), source.getControllerId(), game
+ source.getControllerId(), source, game
) < 1) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java
index aa1ed0ccb71..4439aa712fd 100644
--- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java
+++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionArtifacts.java
@@ -30,7 +30,7 @@ public final class CircleOfProtectionArtifacts extends CardImpl {
// {2}: The next time an artifact source of your choice would deal damage to you this turn, prevent that damage.
Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("2")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{2}")));
}
private CircleOfProtectionArtifacts(final CircleOfProtectionArtifacts card) {
diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java
index 3f2f5a3ed25..04ae99ce2c9 100644
--- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java
+++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlack.java
@@ -33,7 +33,7 @@ public final class CircleOfProtectionBlack extends CardImpl {
// {1}: The next time a black source of your choice would deal damage to you this turn, prevent that damage.
Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("1")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}")));
}
private CircleOfProtectionBlack(final CircleOfProtectionBlack card) {
diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java
index 9ffe0cc9ac5..f8427073049 100644
--- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java
+++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionBlue.java
@@ -33,7 +33,7 @@ public final class CircleOfProtectionBlue extends CardImpl {
// {1}: The next time a blue source of your choice would deal damage to you this turn, prevent that damage.
Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("1")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}")));
}
private CircleOfProtectionBlue(final CircleOfProtectionBlue card) {
diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java
index dc7be67826e..642c7a50783 100644
--- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java
+++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionGreen.java
@@ -33,7 +33,7 @@ public final class CircleOfProtectionGreen extends CardImpl {
// {1}: The next time a green source of your choice would deal damage to you this turn, prevent that damage.
Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("1")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}")));
}
private CircleOfProtectionGreen(final CircleOfProtectionGreen card) {
diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java
index 6d9e177df40..97f0bece75a 100644
--- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java
+++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionRed.java
@@ -33,7 +33,7 @@ public final class CircleOfProtectionRed extends CardImpl {
// {1}: The next time a red source of your choice would deal damage to you this turn, prevent that damage.
Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("1")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}")));
}
private CircleOfProtectionRed(final CircleOfProtectionRed card) {
diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java
index 62aa70f0756..a3a8f069dfa 100644
--- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java
+++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionShadow.java
@@ -33,7 +33,7 @@ public final class CircleOfProtectionShadow extends CardImpl {
// {1}: The next time a creature of your choice with shadow would deal damage to you this turn, prevent that damage.
Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
effect.setText("The next time a creature of your choice with shadow would deal damage to you this turn, prevent that damage");
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("1")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}")));
}
private CircleOfProtectionShadow(final CircleOfProtectionShadow card) {
diff --git a/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java b/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java
index dae973e3811..b94573a3df2 100644
--- a/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java
+++ b/Mage.Sets/src/mage/cards/c/CircleOfProtectionWhite.java
@@ -33,7 +33,7 @@ public final class CircleOfProtectionWhite extends CardImpl {
// {1}: The next time a white source of your choice would deal damage to you this turn, prevent that damage.
Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("1")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}")));
}
private CircleOfProtectionWhite(final CircleOfProtectionWhite card) {
diff --git a/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java b/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java
index b1940d5e158..c10debb4e46 100644
--- a/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java
+++ b/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java
@@ -8,7 +8,6 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@@ -17,8 +16,6 @@ import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
-import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.util.CardUtil;
@@ -58,7 +55,7 @@ public final class CircuDimirLobotomist extends CardImpl {
this.addAbility(ability);
// Your opponents can't cast nonland cards with the same name as a card exiled with Circu, Dimir Lobotomist.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CircuDimirLobotomistRuleModifyingEffect()));
+ this.addAbility(new SimpleStaticAbility(new CircuDimirLobotomistRuleModifyingEffect()));
}
private CircuDimirLobotomist(final CircuDimirLobotomist card) {
@@ -91,14 +88,14 @@ class CircuDimirLobotomistEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player playerTargetLibrary = game.getPlayer(getTargetPointer().getFirst(game, source));
- Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (controller != null && playerTargetLibrary != null && sourcePermanent != null) {
- UUID exileId = CardUtil.getCardExileZoneId(game, source);
- controller.moveCardToExileWithInfo(playerTargetLibrary.getLibrary().getFromTop(game), exileId,
- sourcePermanent.getIdName() + " (" + sourcePermanent.getZoneChangeCounter(game) + ')', source, game, Zone.BATTLEFIELD, true);
- return true;
+ if (controller == null || playerTargetLibrary == null) {
+ return false;
}
- return false;
+ controller.moveCardsToExile(
+ playerTargetLibrary.getLibrary().getFromTop(game), source, game, true,
+ CardUtil.getCardExileZoneId(game, source), CardUtil.getSourceName(game, source)
+ );
+ return true;
}
}
@@ -120,28 +117,23 @@ class CircuDimirLobotomistRuleModifyingEffect extends ContinuousRuleModifyingEff
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
- if (mageObject != null) {
- return "You can't cast this spell because a card with the same name is exiled by " + mageObject.getLogName() + '.';
- }
- return null;
+ return "You can't cast this spell because a card with the same name is exiled by " + CardUtil.getSourceName(game, source) + '.';
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (event.getType() == GameEvent.EventType.CAST_SPELL && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
- MageObject object = game.getObject(event.getSourceId());
- if (object != null) {
- ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
- if ((exileZone != null)) {
- for (Card card : exileZone.getCards(game)) {
- if (CardUtil.haveSameNames(card, object)) {
- return true;
- }
- }
- }
- }
+ if (event.getType() != GameEvent.EventType.CAST_SPELL
+ || !game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
+ return false;
}
- return false;
+ MageObject object = game.getObject(event.getSourceId());
+ ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
+ return object != null
+ && exileZone != null
+ && !exileZone.isEmpty()
+ && exileZone
+ .getCards(game)
+ .stream()
+ .anyMatch(card -> CardUtil.haveSameNames(card, object));
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CircularLogic.java b/Mage.Sets/src/mage/cards/c/CircularLogic.java
index 99a28b12469..2ded66eb0c9 100644
--- a/Mage.Sets/src/mage/cards/c/CircularLogic.java
+++ b/Mage.Sets/src/mage/cards/c/CircularLogic.java
@@ -28,7 +28,7 @@ public final class CircularLogic extends CardImpl {
this.getSpellAbility().addTarget(new TargetSpell());
// Madness {U}
- this.addAbility(new MadnessAbility(this, new ManaCostsImpl<>("{U}")));
+ this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{U}")));
}
private CircularLogic(final CircularLogic card) {
diff --git a/Mage.Sets/src/mage/cards/c/CitizensCrowbar.java b/Mage.Sets/src/mage/cards/c/CitizensCrowbar.java
new file mode 100644
index 00000000000..40c9431b094
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CitizensCrowbar.java
@@ -0,0 +1,60 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.SacrificeAttachmentCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenAttachSourceEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.game.permanent.token.CitizenGreenWhiteToken;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CitizensCrowbar extends CardImpl {
+
+ public CitizensCrowbar(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // When Citizen's Crowbar enters the battlefield, create a 1/1 green and white Citizen creature token, then attach Citizen's Crowbar to it.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new CreateTokenAttachSourceEffect(new CitizenGreenWhiteToken())
+ ));
+
+ // Equipped creature gets +1/+1 and has "{W}, {T}, Sacrifice Citizen's Crowbar: Destroy target artifact or enchantment."
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 1));
+ ability.addEffect(new GainAbilityWithAttachmentEffect(
+ "and has \"{W}, {T}, Sacrifice {this}: Destroy target artifact or enchantment.\"",
+ new DestroyTargetEffect(), new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT),
+ new SacrificeAttachmentCost(), new ManaCostsImpl<>("{W}"), new TapSourceCost()
+ ));
+ this.addAbility(ability);
+
+ // Equip {2}
+ this.addAbility(new EquipAbility(2));
+ }
+
+ private CitizensCrowbar(final CitizensCrowbar card) {
+ super(card);
+ }
+
+ @Override
+ public CitizensCrowbar copy() {
+ return new CitizensCrowbar(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CityInABottle.java b/Mage.Sets/src/mage/cards/c/CityInABottle.java
index 30d668281d3..2177c78905e 100644
--- a/Mage.Sets/src/mage/cards/c/CityInABottle.java
+++ b/Mage.Sets/src/mage/cards/c/CityInABottle.java
@@ -158,7 +158,7 @@ class CityInABottleStateTriggeredAbility extends StateTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- return game.getBattlefield().contains(filter, this.getSourceId(), this.getControllerId(), game, 1);
+ return game.getBattlefield().contains(filter, this.getSourceId(), this.getControllerId(), this, game, 1);
}
@Override
@@ -192,7 +192,7 @@ class CityInABottleSacrificeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
permanent.sacrifice(source, game);
}
return true;
@@ -239,6 +239,6 @@ class CityInABottleCantPlayEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Card card = game.getCard(event.getSourceId());
- return filter.match(card, source.getSourceId(), source.getControllerId(), game);
+ return filter.match(card, source.getControllerId(), source, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CityOfSolitude.java b/Mage.Sets/src/mage/cards/c/CityOfSolitude.java
index fdb24401c75..409048a05e4 100644
--- a/Mage.Sets/src/mage/cards/c/CityOfSolitude.java
+++ b/Mage.Sets/src/mage/cards/c/CityOfSolitude.java
@@ -57,7 +57,7 @@ class CityOfSolitudeEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
MageObject eventObject = game.getObject(event.getSourceId());
if (sourceObject != null && eventObject != null) {
return "You can cast or activate anability of " + eventObject.getIdName() + " only during your own turns (" + sourceObject.getIdName() + "). ";
diff --git a/Mage.Sets/src/mage/cards/c/CitystalkerConnoisseur.java b/Mage.Sets/src/mage/cards/c/CitystalkerConnoisseur.java
new file mode 100644
index 00000000000..746a87e1ac8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CitystalkerConnoisseur.java
@@ -0,0 +1,101 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.game.permanent.token.BloodToken;
+import mage.players.Player;
+import mage.target.common.TargetCardInHand;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CitystalkerConnoisseur extends CardImpl {
+
+ public CitystalkerConnoisseur(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+
+ this.subtype.add(SubType.VAMPIRE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Deathtouch
+ this.addAbility(DeathtouchAbility.getInstance());
+
+ // When Citystalker Connoisseur enters the battlefield, target opponent discards a card with the greatest mana value among cards in their hand. Create a Blood token.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new CitystalkerConnoisseurEffect());
+ ability.addEffect(new CreateTokenEffect(new BloodToken()));
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+ }
+
+ private CitystalkerConnoisseur(final CitystalkerConnoisseur card) {
+ super(card);
+ }
+
+ @Override
+ public CitystalkerConnoisseur copy() {
+ return new CitystalkerConnoisseur(this);
+ }
+}
+
+class CitystalkerConnoisseurEffect extends OneShotEffect {
+
+ CitystalkerConnoisseurEffect() {
+ super(Outcome.Discard);
+ staticText = "target opponent discards a card with the greatest mana value among cards in their hand";
+ }
+
+ private CitystalkerConnoisseurEffect(final CitystalkerConnoisseurEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CitystalkerConnoisseurEffect copy() {
+ return new CitystalkerConnoisseurEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getFirstTarget());
+ if (player == null || player.getHand().isEmpty()) {
+ return false;
+ }
+ if (player.getHand().size() == 1) {
+ player.discard(player.getHand(), false, source, game);
+ return true;
+ }
+ int maxValue = player
+ .getHand()
+ .getCards(game)
+ .stream()
+ .mapToInt(MageObject::getManaValue)
+ .max()
+ .orElse(0);
+ Cards cards = new CardsImpl(player.getHand());
+ cards.removeIf(uuid -> game.getCard(uuid).getManaValue() < maxValue);
+ if (cards.size() == 1) {
+ player.discard(cards, false, source, game);
+ return true;
+ }
+ TargetCardInHand target = new TargetCardInHand();
+ player.choose(outcome, cards, target, game);
+ player.discard(cards.get(target.getFirstTarget(), game), false, source, game);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CivicGardener.java b/Mage.Sets/src/mage/cards/c/CivicGardener.java
new file mode 100644
index 00000000000..61dac145b2b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CivicGardener.java
@@ -0,0 +1,50 @@
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.effects.common.UntapTargetEffect;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.Predicates;
+import mage.target.TargetPermanent;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class CivicGardener extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterPermanent("creature or land");
+
+ static {
+ filter.add(Predicates.or(CardType.CREATURE.getPredicate(), CardType.LAND.getPredicate()));
+ }
+
+ public CivicGardener(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.CITIZEN);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever Civic Gardener attacks, untap target creature or land.
+ Ability ability = new AttacksTriggeredAbility(new UntapTargetEffect());
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private CivicGardener(final CivicGardener card) {
+ super(card);
+ }
+
+ @Override
+ public CivicGardener copy() {
+ return new CivicGardener(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CivilServant.java b/Mage.Sets/src/mage/cards/c/CivilServant.java
new file mode 100644
index 00000000000..52d80ba5126
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CivilServant.java
@@ -0,0 +1,60 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.costs.common.TapTargetCost;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.mageobject.AnotherPredicate;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CivilServant extends CardImpl {
+
+ private static final FilterControlledPermanent filter
+ = new FilterControlledPermanent(SubType.CITIZEN, "another untapped Citizen you control");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(TappedPredicate.UNTAPPED);
+ }
+
+ public CivilServant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}");
+
+ this.subtype.add(SubType.CAT);
+ this.subtype.add(SubType.CITIZEN);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Whenever Civil Servant attacks, you may tap another untapped Citizen you control. If you do, Civil Servant gets +1/+0 and gains lifelink until end of turn.
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
+ new BoostSourceEffect(1, 0, Duration.EndOfTurn).setText("{this} gets +1/+0"),
+ new TapTargetCost(new TargetControlledPermanent(filter))
+ ).addEffect(new GainAbilitySourceEffect(
+ LifelinkAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains lifelink until end of turn"))));
+ }
+
+ private CivilServant(final CivilServant card) {
+ super(card);
+ }
+
+ @Override
+ public CivilServant copy() {
+ return new CivilServant(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java b/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java
index 0388d41c922..12609ef38c0 100644
--- a/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java
+++ b/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java
@@ -94,9 +94,9 @@ class ClackbridgeTrollEffect extends OneShotEffect {
}
TargetControlledPermanent target = new TargetControlledPermanent(filter);
target.setNotTarget(true);
- if (!target.canChoose(source.getSourceId(), opponent.getId(), game)
+ if (!target.canChoose(opponent.getId(), source, game)
|| !opponent.chooseUse(Outcome.AIDontUseIt, "Sacrifice a creature?", source, game)
- || !opponent.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) {
+ || !opponent.choose(Outcome.Sacrifice, target, source, game)) {
continue;
}
Permanent permanent = game.getPermanent(target.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/c/Clambassadors.java b/Mage.Sets/src/mage/cards/c/Clambassadors.java
index f1a37fd465b..ddf3f37cc3e 100644
--- a/Mage.Sets/src/mage/cards/c/Clambassadors.java
+++ b/Mage.Sets/src/mage/cards/c/Clambassadors.java
@@ -81,8 +81,8 @@ class ClambassadorsEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Target target = new TargetControlledPermanent(1, 1, filter, true);
- if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
- while (!target.isChosen() && target.canChoose(source.getSourceId(), controller.getId(), game) && controller.canRespond()) {
+ if (target.canChoose(controller.getId(), source, game)) {
+ while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
controller.chooseTarget(outcome, target, source, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ClanDefiance.java b/Mage.Sets/src/mage/cards/c/ClanDefiance.java
index 4ae9cb1daa6..a1a622f778d 100644
--- a/Mage.Sets/src/mage/cards/c/ClanDefiance.java
+++ b/Mage.Sets/src/mage/cards/c/ClanDefiance.java
@@ -38,13 +38,11 @@ public final class ClanDefiance extends CardImpl {
this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.REGULAR));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filterFlying).withChooseHint("deals X damage, with flying"));
// Clan Defiance deals X damage to target creature without flying;
- Mode mode1 = new Mode();
- mode1.addEffect(new DamageTargetEffect(ManacostVariableValue.REGULAR));
+ Mode mode1 = new Mode(new DamageTargetEffect(ManacostVariableValue.REGULAR));
mode1.addTarget(new TargetCreaturePermanent(filterWithoutFlying).withChooseHint("deals X damage, without flying"));
this.getSpellAbility().addMode(mode1);
// and/or Clan Defiance deals X damage to target player.
- Mode mode2 = new Mode();
- mode2.addEffect(new DamageTargetEffect(ManacostVariableValue.REGULAR));
+ Mode mode2 = new Mode(new DamageTargetEffect(ManacostVariableValue.REGULAR));
mode2.addTarget(new TargetPlayerOrPlaneswalker().withChooseHint("deals X damage"));
this.getSpellAbility().addMode(mode2);
diff --git a/Mage.Sets/src/mage/cards/c/ClarionUltimatum.java b/Mage.Sets/src/mage/cards/c/ClarionUltimatum.java
index 53c5deacce1..2835ac886e3 100644
--- a/Mage.Sets/src/mage/cards/c/ClarionUltimatum.java
+++ b/Mage.Sets/src/mage/cards/c/ClarionUltimatum.java
@@ -69,11 +69,11 @@ class ClarionUltimatumEffect extends OneShotEffect {
}
int permCount = game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_PERMANENT,
- source.getSourceId(), source.getControllerId(), game
+ source.getControllerId(), source, game
);
TargetPermanent targetPermanent = new TargetControlledPermanent(Math.max(permCount, 5));
targetPermanent.setNotTarget(true);
- player.choose(outcome, targetPermanent, source.getSourceId(), game);
+ player.choose(outcome, targetPermanent, source, game);
Set names = targetPermanent
.getTargets()
.stream()
diff --git a/Mage.Sets/src/mage/cards/c/ClawsOfValakut.java b/Mage.Sets/src/mage/cards/c/ClawsOfValakut.java
index 0684f8d3680..ab25ad766ce 100644
--- a/Mage.Sets/src/mage/cards/c/ClawsOfValakut.java
+++ b/Mage.Sets/src/mage/cards/c/ClawsOfValakut.java
@@ -42,7 +42,7 @@ public final class ClawsOfValakut extends CardImpl {
SimpleStaticAbility ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(new PermanentsOnBattlefieldCount(filter, 1),
new PermanentsOnBattlefieldCount(filter, 0),
Duration.WhileOnBattlefield));
- ability.addEffect(new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA));
+ ability.addEffect(new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA).setText("and has first strike"));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/c/CleansingMeditation.java b/Mage.Sets/src/mage/cards/c/CleansingMeditation.java
index 1c7a6a19ea6..b3716a38538 100644
--- a/Mage.Sets/src/mage/cards/c/CleansingMeditation.java
+++ b/Mage.Sets/src/mage/cards/c/CleansingMeditation.java
@@ -9,6 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.AbilityWord;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
@@ -46,7 +47,7 @@ class CleansingMeditationEffect extends OneShotEffect {
public CleansingMeditationEffect() {
super(Outcome.DestroyPermanent);
- this.staticText = "Destroy all enchantments.
Threshold - If seven or more cards are in your graveyard, instead destroy all enchantments, then return all cards in your graveyard destroyed this way to the battlefield.";
+ this.staticText = "Destroy all enchantments.
" + AbilityWord.THRESHOLD.formatWord() + "If seven or more cards are in your graveyard, instead destroy all enchantments, then return all cards in your graveyard destroyed this way to the battlefield.";
}
public CleansingMeditationEffect(final CleansingMeditationEffect effect) {
@@ -72,7 +73,7 @@ class CleansingMeditationEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
- for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_ENCHANTMENT, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_ENCHANTMENT, source.getControllerId(), source, game)) {
if (permanent != null && permanent.destroy(source, game, false)) {
if (threshold && controller != null && permanent.isOwnedBy(controller.getId())) {
cardsToBattlefield.add(permanent);
diff --git a/Mage.Sets/src/mage/cards/c/CleansingNova.java b/Mage.Sets/src/mage/cards/c/CleansingNova.java
index ce6652ee4c1..f4ac94234f4 100644
--- a/Mage.Sets/src/mage/cards/c/CleansingNova.java
+++ b/Mage.Sets/src/mage/cards/c/CleansingNova.java
@@ -26,8 +26,7 @@ public final class CleansingNova extends CardImpl {
this.getSpellAbility().addEffect(new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES));
// • Destroy all artifacts and enchantments.
- Mode mode = new Mode();
- mode.addEffect(new DestroyAllEffect(filter));
+ Mode mode = new Mode(new DestroyAllEffect(filter));
this.getSpellAbility().getModes().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/CleansingRay.java b/Mage.Sets/src/mage/cards/c/CleansingRay.java
index d1bed44724a..4a3db217e91 100644
--- a/Mage.Sets/src/mage/cards/c/CleansingRay.java
+++ b/Mage.Sets/src/mage/cards/c/CleansingRay.java
@@ -29,8 +29,7 @@ public final class CleansingRay extends CardImpl {
getSpellAbility().addTarget(new TargetPermanent(filter));
// - Destroy target enchantment.
- Mode mode = new Mode();
- mode.addEffect(new DestroyTargetEffect());
+ Mode mode = new Mode(new DestroyTargetEffect());
mode.addTarget(new TargetEnchantmentPermanent());
this.getSpellAbility().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/c/CleanupCrew.java b/Mage.Sets/src/mage/cards/c/CleanupCrew.java
new file mode 100644
index 00000000000..d743613bd76
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CleanupCrew.java
@@ -0,0 +1,57 @@
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetArtifactPermanent;
+import mage.target.common.TargetCardInGraveyard;
+import mage.target.common.TargetEnchantmentPermanent;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class CleanupCrew extends CardImpl {
+
+ public CleanupCrew(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.CITIZEN);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // When Cleanup Crew enters the battlefield, choose one —
+ // • Destroy target artifact.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect());
+ ability.addTarget(new TargetArtifactPermanent());
+
+ // • Destroy target enchantment.
+ ability.addMode(new Mode(new DestroyTargetEffect()).addTarget(new TargetEnchantmentPermanent()));
+
+ // • Exile target card from a graveyard.
+ ability.addMode(new Mode(new ExileTargetEffect()).addTarget(new TargetCardInGraveyard()));
+
+ // • You gain 4 life.
+ ability.addMode(new Mode(new GainLifeEffect(4)));
+ this.addAbility(ability);
+ }
+
+ private CleanupCrew(final CleanupCrew card) {
+ super(card);
+ }
+
+ @Override
+ public CleanupCrew copy() {
+ return new CleanupCrew(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CleavingSliver.java b/Mage.Sets/src/mage/cards/c/CleavingSliver.java
index b3da1f12439..276865cf0c5 100644
--- a/Mage.Sets/src/mage/cards/c/CleavingSliver.java
+++ b/Mage.Sets/src/mage/cards/c/CleavingSliver.java
@@ -27,7 +27,7 @@ public final class CleavingSliver extends CardImpl {
// Sliver creatures you control get +2/+0.
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
2, 0, Duration.WhileOnBattlefield,
- StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS
+ StaticFilters.FILTER_PERMANENT_SLIVERS
)));
}
diff --git a/Mage.Sets/src/mage/cards/c/ClericOfChillDepths.java b/Mage.Sets/src/mage/cards/c/ClericOfChillDepths.java
index 8e02967bcf0..f74a5a12d9a 100644
--- a/Mage.Sets/src/mage/cards/c/ClericOfChillDepths.java
+++ b/Mage.Sets/src/mage/cards/c/ClericOfChillDepths.java
@@ -1,7 +1,7 @@
package mage.cards.c;
import mage.MageInt;
-import mage.abilities.common.BlocksSourceTriggeredAbility;
+import mage.abilities.common.BlocksCreatureTriggeredAbility;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -24,8 +24,8 @@ public final class ClericOfChillDepths extends CardImpl {
this.toughness = new MageInt(3);
// Whenever Cleric of Chill Depths blocks a creature, that creature doesn't untap during its controller's next untap step.
- this.addAbility(new BlocksSourceTriggeredAbility(
- new DontUntapInControllersNextUntapStepTargetEffect("that creature"), false, true
+ this.addAbility(new BlocksCreatureTriggeredAbility(
+ new DontUntapInControllersNextUntapStepTargetEffect("that creature")
));
}
diff --git a/Mage.Sets/src/mage/cards/c/ClingingMists.java b/Mage.Sets/src/mage/cards/c/ClingingMists.java
index 7506823282f..bed1c919805 100644
--- a/Mage.Sets/src/mage/cards/c/ClingingMists.java
+++ b/Mage.Sets/src/mage/cards/c/ClingingMists.java
@@ -63,7 +63,7 @@ class ClingingMistsEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
List doNotUntapNextUntapStep = new ArrayList<>();
- for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_ATTACKING_CREATURES, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_ATTACKING_CREATURES, source.getControllerId(), source, game)) {
creature.tap(source, game);
doNotUntapNextUntapStep.add(creature);
}
diff --git a/Mage.Sets/src/mage/cards/c/CloakAndDagger.java b/Mage.Sets/src/mage/cards/c/CloakAndDagger.java
index 914d65b2248..68ebe8cc4cb 100644
--- a/Mage.Sets/src/mage/cards/c/CloakAndDagger.java
+++ b/Mage.Sets/src/mage/cards/c/CloakAndDagger.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -23,11 +22,7 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class CloakAndDagger extends CardImpl {
- private static final FilterPermanent filter = new FilterCreaturePermanent("a Rogue creature");
-
- static {
- filter.add(SubType.ROGUE.getPredicate());
- }
+ private static final FilterPermanent filter = new FilterCreaturePermanent(SubType.ROGUE, "a Rogue creature");
public CloakAndDagger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.ARTIFACT}, "{2}");
diff --git a/Mage.Sets/src/mage/cards/c/ClotSliver.java b/Mage.Sets/src/mage/cards/c/ClotSliver.java
index be39f61fb12..d0c769b9383 100644
--- a/Mage.Sets/src/mage/cards/c/ClotSliver.java
+++ b/Mage.Sets/src/mage/cards/c/ClotSliver.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import mage.MageInt;
@@ -12,7 +11,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.FilterPermanent;
import java.util.UUID;
@@ -22,19 +20,19 @@ import java.util.UUID;
*/
public final class ClotSliver extends CardImpl {
- private static final FilterPermanent filter = new FilterPermanent("Slivers");
-
- static {
- filter.add(SubType.SLIVER.getPredicate());
- }
+ private static final FilterPermanent filter = new FilterPermanent(SubType.SLIVER, "all Slivers");
public ClotSliver(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.SLIVER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect("this permanent"), new GenericManaCost(2)), Duration.WhileOnBattlefield, filter, false)));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect(
+ new SimpleActivatedAbility(
+ new RegenerateSourceEffect("this permanent"), new GenericManaCost(2)
+ ), Duration.WhileOnBattlefield, filter, false
+ )));
}
private ClotSliver(final ClotSliver card) {
diff --git a/Mage.Sets/src/mage/cards/c/CloudshredderSliver.java b/Mage.Sets/src/mage/cards/c/CloudshredderSliver.java
index 15a194d3a3a..203142ec60e 100644
--- a/Mage.Sets/src/mage/cards/c/CloudshredderSliver.java
+++ b/Mage.Sets/src/mage/cards/c/CloudshredderSliver.java
@@ -30,11 +30,11 @@ public final class CloudshredderSliver extends CardImpl {
// Sliver creatures you control have flying and haste.
Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect(
FlyingAbility.getInstance(), Duration.WhileOnBattlefield,
- StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS
+ StaticFilters.FILTER_PERMANENT_ALL_SLIVERS
).setText("Sliver creatures you control have flying"));
ability.addEffect(new GainAbilityControlledEffect(
HasteAbility.getInstance(), Duration.WhileOnBattlefield,
- StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS
+ StaticFilters.FILTER_PERMANENT_ALL_SLIVERS
).setText("and haste"));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/c/CloudstoneCurio.java b/Mage.Sets/src/mage/cards/c/CloudstoneCurio.java
index 1f092551139..0c60bfbff9b 100644
--- a/Mage.Sets/src/mage/cards/c/CloudstoneCurio.java
+++ b/Mage.Sets/src/mage/cards/c/CloudstoneCurio.java
@@ -82,7 +82,7 @@ class CloudstoneCurioEffect extends OneShotEffect {
));
TargetPermanent target = new TargetPermanent(1, 1, filter, true);
- if (target.canChoose(source.getSourceId(), controller.getId(), game) && controller.chooseTarget(outcome, target, source, game)) {
+ if (target.canChoose(controller.getId(), source, game) && controller.chooseTarget(outcome, target, source, game)) {
Permanent returningCreature = game.getPermanent(target.getFirstTarget());
if (returningCreature != null) {
controller.moveCards(returningCreature, Zone.HAND, source, game);
diff --git a/Mage.Sets/src/mage/cards/c/Cloudthresher.java b/Mage.Sets/src/mage/cards/c/Cloudthresher.java
index 0139ffd66e9..7b16baa23f2 100644
--- a/Mage.Sets/src/mage/cards/c/Cloudthresher.java
+++ b/Mage.Sets/src/mage/cards/c/Cloudthresher.java
@@ -42,7 +42,7 @@ public final class Cloudthresher extends CardImpl {
this.addAbility(ReachAbility.getInstance());
// When Cloudthresher enters the battlefield, it deals 2 damage to each creature with flying and each player.
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageAllEffect(2, "it", filter));
- ability.addEffect(new DamagePlayersEffect(2));
+ ability.addEffect(new DamagePlayersEffect(2).setText("and each player"));
this.addAbility(ability);
// Evoke {2}{G}{G}
this.addAbility(new EvokeAbility("{2}{G}{G}"));
diff --git a/Mage.Sets/src/mage/cards/c/CoalhaulerSwine.java b/Mage.Sets/src/mage/cards/c/CoalhaulerSwine.java
index 87acbeb4bf3..fb9fbb57ffe 100644
--- a/Mage.Sets/src/mage/cards/c/CoalhaulerSwine.java
+++ b/Mage.Sets/src/mage/cards/c/CoalhaulerSwine.java
@@ -28,8 +28,7 @@ public final class CoalhaulerSwine extends CardImpl {
// Whenever Coalhauler Swine is dealt damage, it deals that much damage to each player.
this.addAbility(new DealtDamageToSourceTriggeredAbility(new DamagePlayersEffect(
- Outcome.Neutral, SavedDamageValue.instance, TargetController.ANY, "it"
- ), false, false));
+ Outcome.Damage, SavedDamageValue.MUCH, TargetController.ANY, "it"), false));
}
private CoalhaulerSwine(final CoalhaulerSwine card) {
diff --git a/Mage.Sets/src/mage/cards/c/CoalitionVictory.java b/Mage.Sets/src/mage/cards/c/CoalitionVictory.java
index a39235a3e78..ff12aa73d88 100644
--- a/Mage.Sets/src/mage/cards/c/CoalitionVictory.java
+++ b/Mage.Sets/src/mage/cards/c/CoalitionVictory.java
@@ -68,33 +68,33 @@ class CoalitionVictoryCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- if (game.getBattlefield().count(CoalitionVictory.filterPlains, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterPlains, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterIsland, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterIsland, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterSwamp, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterSwamp, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterMountain, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterMountain, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterForest, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterForest, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterWhite, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterWhite, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterBlue, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterBlue, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterBlack, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterBlack, source.getControllerId(), source, game) < 1) {
return false;
}
- if (game.getBattlefield().count(CoalitionVictory.filterRed, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(CoalitionVictory.filterRed, source.getControllerId(), source, game) < 1) {
return false;
}
- return game.getBattlefield().count(CoalitionVictory.filterGreen, source.getSourceId(), source.getControllerId(), game) >= 1;
+ return game.getBattlefield().count(CoalitionVictory.filterGreen, source.getControllerId(), source, game) >= 1;
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/CodexShredder.java b/Mage.Sets/src/mage/cards/c/CodexShredder.java
index 3f5d319a4d5..4b6743cd198 100644
--- a/Mage.Sets/src/mage/cards/c/CodexShredder.java
+++ b/Mage.Sets/src/mage/cards/c/CodexShredder.java
@@ -1,40 +1,41 @@
-
package mage.cards.c;
-import java.util.UUID;
+import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
* @author LevelX2
*/
public final class CodexShredder extends CardImpl {
public CodexShredder(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {T}: Target player puts the top card of their library into their graveyard.
- SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLibraryIntoGraveTargetEffect(1), new TapSourceCost());
+ Ability ability = new SimpleActivatedAbility(
+ new PutLibraryIntoGraveTargetEffect(1), new TapSourceCost()
+ );
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
-
+
// {5}, {T}, Sacrifice Codex Shredder: Return target card from your graveyard to your hand.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{5}"));
+ ability = new SimpleActivatedAbility(new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl<>("{5}"));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCardInYourGraveyard());
this.addAbility(ability);
-
}
private CodexShredder(final CodexShredder card) {
diff --git a/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java b/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java
index 02a67433c38..58428ba40e0 100644
--- a/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java
+++ b/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java
@@ -1,19 +1,15 @@
-
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.dynamicvalue.common.SavedDamageValue;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.IslandwalkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Outcome;
-import mage.game.Game;
-import mage.players.Player;
/**
*
@@ -31,9 +27,11 @@ public final class ColdEyedSelkie extends CardImpl {
// Islandwalk
this.addAbility(new IslandwalkAbility());
- // Whenever Cold-Eyed Selkie deals combat damage to a player, you may draw that many cards.
- this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new ColdEyeSelkieEffect(), true, true));
+ // Whenever Cold-Eyed Selkie deals combat damage to a player, you may draw that many cards.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
+ new DrawCardSourceControllerEffect(SavedDamageValue.MANY),
+ true, true));
}
private ColdEyedSelkie(final ColdEyedSelkie card) {
@@ -45,33 +43,3 @@ public final class ColdEyedSelkie extends CardImpl {
return new ColdEyedSelkie(this);
}
}
-
-class ColdEyeSelkieEffect extends OneShotEffect {
-
- public ColdEyeSelkieEffect() {
- super(Outcome.DrawCard);
- this.staticText = "draw that many cards";
- }
-
- public ColdEyeSelkieEffect(final ColdEyeSelkieEffect effect) {
- super(effect);
- }
-
- @Override
- public ColdEyeSelkieEffect copy() {
- return new ColdEyeSelkieEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- int amount = (Integer) getValue("damage");
- if (amount > 0) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- controller.drawCards(amount, source, game);
- return true;
- }
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/c/ColdStorage.java b/Mage.Sets/src/mage/cards/c/ColdStorage.java
index db7f195974c..c2e91ed5c0c 100644
--- a/Mage.Sets/src/mage/cards/c/ColdStorage.java
+++ b/Mage.Sets/src/mage/cards/c/ColdStorage.java
@@ -1,36 +1,39 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
-import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.common.ExileTargetEffect;
-import mage.abilities.effects.common.ReturnCreaturesFromExileEffect;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.Outcome;
import mage.constants.Zone;
+import mage.game.ExileZone;
+import mage.game.Game;
+import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
/**
- *
* @author Plopman
*/
public final class ColdStorage extends CardImpl {
public ColdStorage(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// {3}: Exile target creature you control.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(this.getId(), this.getIdName()), new ManaCostsImpl("{3}"));
+ Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new GenericManaCost(3));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
+
// Sacrifice Cold Storage: Return each creature card exiled with Cold Storage to the battlefield under your control.
- ReturnCreaturesFromExileEffect returnFromExileEffect = new ReturnCreaturesFromExileEffect(this.getId(), false, "Return each creature card exiled with {this} to the battlefield under your control");
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, returnFromExileEffect, new SacrificeSourceCost());
- this.addAbility(ability);
+ this.addAbility(new SimpleActivatedAbility(new ColdStorageEffect(), new SacrificeSourceCost()));
}
private ColdStorage(final ColdStorage card) {
@@ -42,3 +45,30 @@ public final class ColdStorage extends CardImpl {
return new ColdStorage(this);
}
}
+
+class ColdStorageEffect extends OneShotEffect {
+
+ ColdStorageEffect() {
+ super(Outcome.Benefit);
+ staticText = "return each creature card exiled with {this} to the battlefield under your control";
+ }
+
+ private ColdStorageEffect(final ColdStorageEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ColdStorageEffect copy() {
+ return new ColdStorageEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
+ return player != null
+ && exileZone != null
+ && !exileZone.isEmpty()
+ && player.moveCards(exileZone, Zone.BATTLEFIELD, source, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java b/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java
index ec9e1197732..8c461e68ae1 100644
--- a/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java
+++ b/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java
@@ -150,7 +150,7 @@ class ColfenorsPlansLookAtCardEffect extends AsThoughEffectImpl {
if (affectedControllerId.equals(source.getControllerId())) {
Card card = game.getCard(objectId);
if (card != null) {
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (sourceObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/ColfenorsUrn.java b/Mage.Sets/src/mage/cards/c/ColfenorsUrn.java
index 5ffe45ee082..da26d1ad12f 100644
--- a/Mage.Sets/src/mage/cards/c/ColfenorsUrn.java
+++ b/Mage.Sets/src/mage/cards/c/ColfenorsUrn.java
@@ -44,7 +44,7 @@ public final class ColfenorsUrn extends CardImpl {
new ExileTargetForSourceEffect().setText("exile it"), true, filter, true, true));
// At the beginning of the end step, if three or more cards have been exiled with Colfenor's Urn, sacrifice it. If you do, return those cards to the battlefield under their owner's control.
- this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new ColfenorsUrnEffect(), TargetController.ANY, new ColfenorsUrnCondition(), false));
+ this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new ColfenorsUrnEffect(), TargetController.NEXT, new ColfenorsUrnCondition(), false));
}
private ColfenorsUrn(final ColfenorsUrn card) {
@@ -95,7 +95,7 @@ class ColfenorsUrnCondition implements Condition {
@Override
public final boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller != null && sourceObject != null) {
UUID exileId = CardUtil.getCardExileZoneId(game, source);
ExileZone exile = game.getExile().getExileZone(exileId);
diff --git a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java
index 9a066fe61a3..934e031adc2 100644
--- a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java
+++ b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.DomainValue;
@@ -15,10 +13,10 @@ import mage.constants.AbilityWord;
import mage.constants.CardType;
import mage.constants.TargetController;
+import java.util.UUID;
+
/**
- *
* @author LoneFox
- *
*/
public final class CollapsingBorders extends CardImpl {
@@ -26,7 +24,7 @@ public final class CollapsingBorders extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// Domain - At the beginning of each player's upkeep, that player gains 1 life for each basic land type among lands they control. Then Collapsing Borders deals 3 damage to that player.
- Effect effect = new GainLifeTargetEffect(new DomainValue(true));
+ Effect effect = new GainLifeTargetEffect(DomainValue.TARGET);
effect.setText("that player gains 1 life for each basic land type among lands they control");
Ability ability = new BeginningOfUpkeepTriggeredAbility(effect, TargetController.ANY, false);
effect = new DamageTargetEffect(3);
diff --git a/Mage.Sets/src/mage/cards/c/CollectedCompany.java b/Mage.Sets/src/mage/cards/c/CollectedCompany.java
index 8035c40fd81..a41f1b164e0 100644
--- a/Mage.Sets/src/mage/cards/c/CollectedCompany.java
+++ b/Mage.Sets/src/mage/cards/c/CollectedCompany.java
@@ -1,14 +1,14 @@
-
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
+import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
/**
@@ -17,20 +17,18 @@ import mage.filter.predicate.mageobject.ManaValuePredicate;
*/
public final class CollectedCompany extends CardImpl {
- private static final FilterCard filter = new FilterCard("up to two creature cards with mana value 3 or less");
+ private static final FilterCard filter = new FilterCreatureCard("creature cards with mana value 3 or less");
static {
- filter.add(CardType.CREATURE.getPredicate());
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4));
}
public CollectedCompany(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{G}");
- // Look at the top six cards of your library. Put up to two creature cards with converted mana cost 3 or less from among them onto the battlefield.
+ // Look at the top six cards of your library. Put up to two creature cards with mana value 3 or less from among them onto the battlefield.
// Put the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(6, 2, filter, false, true, Zone.BATTLEFIELD, false));
-
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(6, 2, filter, PutCards.BATTLEFIELD, PutCards.BOTTOM_ANY, false));
}
private CollectedCompany(final CollectedCompany card) {
diff --git a/Mage.Sets/src/mage/cards/c/CollectedConjuring.java b/Mage.Sets/src/mage/cards/c/CollectedConjuring.java
index f46fe78b9d4..b838db5ce86 100644
--- a/Mage.Sets/src/mage/cards/c/CollectedConjuring.java
+++ b/Mage.Sets/src/mage/cards/c/CollectedConjuring.java
@@ -1,10 +1,11 @@
package mage.cards.c;
-import mage.ApprovingObject;
-import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.*;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
@@ -13,7 +14,7 @@ import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
+import mage.util.CardUtil;
import java.util.UUID;
@@ -51,12 +52,6 @@ class CollectedConjuringEffect extends OneShotEffect {
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4));
}
- private static final FilterCard filter2 = filter.copy();
-
- static {
- filter2.setMessage("sorcery card with mana value 3 or less");
- }
-
CollectedConjuringEffect() {
super(Outcome.PlayForFree);
this.staticText = "exile the top six cards of your library. You may cast up to two sorcery spells " +
@@ -76,42 +71,12 @@ class CollectedConjuringEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = source.getSourceObject(game);
- if (controller == null
- || sourceObject == null) {
+ if (controller == null) {
return false;
}
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 6));
- Cards cardsToChoose = new CardsImpl(cards);
controller.moveCards(cards, Zone.EXILED, source, game);
- int cardsCast = 0;
- while (!cardsToChoose.getCards(filter, source.getSourceId(), source.getControllerId(), game).isEmpty()
- && cardsCast < 2) {
- if (!controller.chooseUse(Outcome.PlayForFree, "Cast a card exiled with "
- + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
- break;
- }
- TargetCard targetCard = new TargetCard(1, Zone.EXILED, filter2);
- if (!controller.choose(Outcome.PlayForFree, cardsToChoose, targetCard, game)) {
- continue;
- }
- Card card = game.getCard(targetCard.getFirstTarget());
- if (card == null) {
- continue;
- }
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- cardsToChoose.remove(card); // remove on non cast too (infinite freeze fix)
- if (cardWasCast) {
- cards.remove(card);
- cardsCast++;
- } else {
- game.informPlayer(controller, "You're not able to cast "
- + card.getIdName() + " or you canceled the casting.");
- }
- }
+ CardUtil.castMultipleWithAttributeForFree(controller, source, game, cards, filter, 2);
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/c/CollectiveBrutality.java b/Mage.Sets/src/mage/cards/c/CollectiveBrutality.java
index c5367301280..a5242bb7fa0 100644
--- a/Mage.Sets/src/mage/cards/c/CollectiveBrutality.java
+++ b/Mage.Sets/src/mage/cards/c/CollectiveBrutality.java
@@ -49,14 +49,12 @@ public final class CollectiveBrutality extends CardImpl {
this.getSpellAbility().addTarget(new TargetOpponent().withChooseHint("reveals hand, you choose to discard"));
// Target creature gets -2/-2 until end of turn.
- Mode mode = new Mode();
- mode.addEffect(new BoostTargetEffect(-2, -2, Duration.EndOfTurn));
+ Mode mode = new Mode(new BoostTargetEffect(-2, -2, Duration.EndOfTurn));
mode.addTarget(new TargetCreaturePermanent().withChooseHint("gets -2/-2 until end of turn"));
this.getSpellAbility().addMode(mode);
// Target opponent loses 2 life and you gain 2 life.
- mode = new Mode();
- mode.addEffect(new LoseLifeTargetEffect(2));
+ mode = new Mode(new LoseLifeTargetEffect(2));
mode.addEffect(new GainLifeEffect(2).concatBy("and"));
mode.addTarget(new TargetOpponent().withChooseHint("loses 2 life"));
this.getSpellAbility().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java b/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java
index 0cb729fa358..2fe28da5bef 100644
--- a/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java
+++ b/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java
@@ -44,18 +44,16 @@ public final class CollectiveDefiance extends CardImpl {
this.getSpellAbility().addTarget(new TargetPlayer(1, 1, false, filterDiscard).withChooseHint("discards all cards and draws"));
// Collective Defiance deals 4 damage to target creature.;
- Mode mode = new Mode();
Effect effect = new DamageTargetEffect(4);
effect.setText("{this} deals 4 damage to target creature");
- mode.addEffect(effect);
+ Mode mode = new Mode(effect);
mode.addTarget(new TargetCreaturePermanent(filterCreature).withChooseHint("deals 4 damage to"));
this.getSpellAbility().addMode(mode);
// Collective Defiance deals 3 damage to target opponent or planeswalker.
- mode = new Mode();
effect = new DamageTargetEffect(3);
effect.setText("{this} deals 3 damage to target opponent or planeswalker");
- mode.addEffect(effect);
+ mode = new Mode(effect);
mode.addTarget(new TargetOpponentOrPlaneswalker().withChooseHint("deals 3 damage to"));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/CollectiveEffort.java b/Mage.Sets/src/mage/cards/c/CollectiveEffort.java
index c5462be3fde..9dda7f30c1a 100644
--- a/Mage.Sets/src/mage/cards/c/CollectiveEffort.java
+++ b/Mage.Sets/src/mage/cards/c/CollectiveEffort.java
@@ -63,18 +63,16 @@ public final class CollectiveEffort extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filterDestroyCreature).withChooseHint("destroy"));
// Destroy target enchantment.;
- Mode mode = new Mode();
Effect effect = new DestroyTargetEffect();
effect.setText("Destroy target enchantment");
- mode.addEffect(effect);
+ Mode mode = new Mode(effect);
mode.addTarget(new TargetEnchantmentPermanent(filterDestroyEnchantment).withChooseHint("destroy"));
this.getSpellAbility().addMode(mode);
// Put a +1/+1 counter on each creature target player controls.
- mode = new Mode();
effect = new CollectiveEffortEffect();
effect.setText("Put a +1/+1 counter on each creature target player controls");
- mode.addEffect(effect);
+ mode = new Mode(effect);
mode.addTarget(new TargetPlayer(1, 1, false, filterPlayer).withChooseHint("put +1/+1 counter on each creature"));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java
index fc36ceb624d..df7d2435c88 100644
--- a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java
+++ b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java
@@ -56,7 +56,7 @@ class CollectiveRestraintPayManaToAttackAllEffect extends CantAttackYouUnlessPay
@Override
public ManaCosts getManaCostToPay(GameEvent event, Ability source, Game game) {
- int domainValue = new DomainValue().calculate(game, source, this);
+ int domainValue = DomainValue.REGULAR.calculate(game, source, this);
if (domainValue > 0) {
return new ManaCostsImpl<>("{" + domainValue + '}');
}
diff --git a/Mage.Sets/src/mage/cards/c/CollisionOfRealms.java b/Mage.Sets/src/mage/cards/c/CollisionOfRealms.java
new file mode 100644
index 00000000000..0c85fa53d2b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CollisionOfRealms.java
@@ -0,0 +1,103 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.PermanentToken;
+import mage.players.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CollisionOfRealms extends CardImpl {
+
+ public CollisionOfRealms(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{R}");
+
+ // Each player shuffles all creatures they own into their library. Each player who shuffled a nontoken creature into their library this way reveals cards from the top of their library until they reveal a creature card, then puts that card onto the battlefield and the rest on the bottom of their library in a random order.
+ this.getSpellAbility().addEffect(new CollisionOfRealmsEffect());
+ }
+
+ private CollisionOfRealms(final CollisionOfRealms card) {
+ super(card);
+ }
+
+ @Override
+ public CollisionOfRealms copy() {
+ return new CollisionOfRealms(this);
+ }
+}
+
+class CollisionOfRealmsEffect extends OneShotEffect {
+
+ CollisionOfRealmsEffect() {
+ super(Outcome.Benefit);
+ staticText = "each player shuffles all creatures they own into their library. " +
+ "Each player who shuffled a nontoken creature into their library this way reveals cards " +
+ "from the top of their library until they reveal a creature card, then puts that card " +
+ "onto the battlefield and the rest on the bottom of their library in a random order";
+ }
+
+ private CollisionOfRealmsEffect(final CollisionOfRealmsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CollisionOfRealmsEffect copy() {
+ return new CollisionOfRealmsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ List players = new ArrayList<>();
+ for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
+ Player player = game.getPlayer(playerId);
+ if (player == null) {
+ continue;
+ }
+ List permanents = game.getBattlefield().getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_CREATURE, playerId, game
+ );
+ boolean hasNonToken = permanents
+ .stream()
+ .filter(permanent -> !(permanent instanceof PermanentToken))
+ .anyMatch(permanent -> permanent.isCreature(game));
+ player.putCardsOnBottomOfLibrary(new CardsImpl(permanents), game, source, false);
+ player.shuffleLibrary(source, game);
+ if (hasNonToken) {
+ players.add(player);
+ }
+ }
+ for (Player player : players) {
+ Cards cards = new CardsImpl();
+ Card creature = revealUntilCreature(cards, player, game);
+ player.revealCards(source, cards, game);
+ if (creature != null) {
+ player.moveCards(creature, Zone.BATTLEFIELD, source, game);
+ }
+ cards.retainZone(Zone.LIBRARY, game);
+ player.putCardsOnBottomOfLibrary(cards, game, source, false);
+ }
+ return true;
+ }
+
+ private static Card revealUntilCreature(Cards cards, Player player, Game game) {
+ for (Card card : player.getLibrary().getCards(game)) {
+ cards.add(card);
+ if (card.isCreature(game)) {
+ return card;
+ }
+ }
+ return null;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ColossalMight.java b/Mage.Sets/src/mage/cards/c/ColossalMight.java
index 014cf982f2f..f569d4fee4e 100644
--- a/Mage.Sets/src/mage/cards/c/ColossalMight.java
+++ b/Mage.Sets/src/mage/cards/c/ColossalMight.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.c;
-import java.util.UUID;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.TrampleAbility;
@@ -12,22 +9,26 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class ColossalMight extends CardImpl {
- public ColossalMight (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}{G}");
-
+ public ColossalMight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{G}");
+ this.getSpellAbility().addEffect(new BoostTargetEffect(
+ 4, 2, Duration.EndOfTurn
+ ).setText("target creature gets +4/+2"));
+ this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains trample until end of turn"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new BoostTargetEffect(4, 2, Duration.EndOfTurn));
- this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn));
}
- public ColossalMight (final ColossalMight card) {
+ public ColossalMight(final ColossalMight card) {
super(card);
}
@@ -35,5 +36,4 @@ public final class ColossalMight extends CardImpl {
public ColossalMight copy() {
return new ColossalMight(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java b/Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java
index c4609faa067..e9ec1c7786a 100644
--- a/Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java
+++ b/Mage.Sets/src/mage/cards/c/CommuneWithDinosaurs.java
@@ -1,9 +1,8 @@
-
package mage.cards.c;
import java.util.UUID;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -30,7 +29,7 @@ public final class CommuneWithDinosaurs extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}");
//Look at the top five cards of your library. You may reveal a Dinosaur or land card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(StaticValue.get(5), false, StaticValue.get(1), filter, false));
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(5, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY));
}
private CommuneWithDinosaurs(final CommuneWithDinosaurs card) {
diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithNature.java b/Mage.Sets/src/mage/cards/c/CommuneWithNature.java
index 69a5a27fd96..9b216d38738 100644
--- a/Mage.Sets/src/mage/cards/c/CommuneWithNature.java
+++ b/Mage.Sets/src/mage/cards/c/CommuneWithNature.java
@@ -1,13 +1,12 @@
-
package mage.cards.c;
import java.util.UUID;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -18,12 +17,10 @@ public final class CommuneWithNature extends CardImpl {
public CommuneWithNature(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}");
- // Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(
- new LookLibraryAndPickControllerEffect(
- StaticValue.get(5), false, StaticValue.get(1), new FilterCreatureCard("a creature card"), false
- )
- );
+ // Look at the top five cards of your library. You may reveal a creature card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in any order.
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
+ 5, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_ANY));
}
private CommuneWithNature(final CommuneWithNature card) {
@@ -34,5 +31,4 @@ public final class CommuneWithNature extends CardImpl {
public CommuneWithNature copy() {
return new CommuneWithNature(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithSpirits.java b/Mage.Sets/src/mage/cards/c/CommuneWithSpirits.java
index 1614cb95261..f51fc750c52 100644
--- a/Mage.Sets/src/mage/cards/c/CommuneWithSpirits.java
+++ b/Mage.Sets/src/mage/cards/c/CommuneWithSpirits.java
@@ -1,11 +1,10 @@
package mage.cards.c;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@@ -28,13 +27,9 @@ public final class CommuneWithSpirits extends CardImpl {
public CommuneWithSpirits(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}");
- // Look at the top four cards of your library. You may reveal an enchantment or land card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(4), false, StaticValue.get(1), filter, Zone.LIBRARY, false,
- true, false, Zone.HAND, true, false, false
- ).setBackInRandomOrder(true).setText("look at the top four cards of your library. " +
- "You may reveal an enchantment or land card from among them and put it into your hand. " +
- "Put the rest on the bottom of your library in a random order"));
+ // Look at the top four cards of your library. You may reveal an enchantment or land card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in a random order.
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(4, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM));
}
private CommuneWithSpirits(final CommuneWithSpirits card) {
diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java b/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java
index f9f80f6b0ed..eb688a01ec6 100644
--- a/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java
+++ b/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java
@@ -1,31 +1,35 @@
-
package mage.cards.c;
import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
-import mage.cards.*;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
+import mage.abilities.effects.common.RevealLibraryPickControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.TargetCard;
/**
*
- * @author LevelX2
+ * @author awjackson
*/
public final class CommuneWithTheGods extends CardImpl {
+ private static final FilterCard filter = new FilterCard("a creature or enchantment card");
+
+ static {
+ filter.add(Predicates.or(
+ CardType.CREATURE.getPredicate(),
+ CardType.ENCHANTMENT.getPredicate()
+ ));
+ }
+
public CommuneWithTheGods(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
- // Reveal the top five cards of your library. You may put a creature or enchantment card from among them into your hand. Put the rest into your graveyard.
- this.getSpellAbility().addEffect(new CommuneWithTheGodsEffect());
-
+ // Reveal the top five cards of your library. You may put a creature or enchantment card from among them into your hand.
+ // Put the rest into your graveyard.
+ this.getSpellAbility().addEffect(new RevealLibraryPickControllerEffect(5, 1, filter, PutCards.HAND, PutCards.GRAVEYARD));
}
private CommuneWithTheGods(final CommuneWithTheGods card) {
@@ -37,47 +41,3 @@ public final class CommuneWithTheGods extends CardImpl {
return new CommuneWithTheGods(this);
}
}
-
-class CommuneWithTheGodsEffect extends OneShotEffect {
-
- public CommuneWithTheGodsEffect() {
- super(Outcome.DrawCard);
- this.staticText = "Reveal the top five cards of your library. You may put a creature or enchantment card from among them into your hand. Put the rest into your graveyard";
- }
-
- public CommuneWithTheGodsEffect(final CommuneWithTheGodsEffect effect) {
- super(effect);
- }
-
- @Override
- public CommuneWithTheGodsEffect copy() {
- return new CommuneWithTheGodsEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
- if (!cards.isEmpty()) {
- FilterCard filterPutInHand = new FilterCard("creature or enchantment card to put in hand");
- filterPutInHand.add(Predicates.or(CardType.CREATURE.getPredicate(), CardType.ENCHANTMENT.getPredicate()));
- controller.revealCards(source, cards, game);
- if (cards.count(filterPutInHand, source.getSourceId(), source.getControllerId(), game) > 0) {
- TargetCard target = new TargetCard(0, 1, Zone.LIBRARY, filterPutInHand);
- if (controller.choose(Outcome.DrawCard, cards, target, game)) {
- Card card = game.getCard(target.getFirstTarget());
- if (card != null) {
- cards.remove(card);
- controller.moveCards(card, Zone.HAND, source, game);
- }
-
- }
- }
- controller.moveCards(cards, Zone.GRAVEYARD, source, game);
- }
- return true;
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java b/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java
index 840f57400ec..e7eaa81f986 100644
--- a/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java
+++ b/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java
@@ -67,7 +67,7 @@ class CompulsiveResearchDiscardEffect extends OneShotEffect {
return !targetPlayer.discard(2, false, false, source, game).isEmpty();
}
TargetDiscard target = new TargetDiscard(StaticFilters.FILTER_CARD_LAND_A, targetPlayer.getId());
- targetPlayer.choose(Outcome.Discard, target, source.getSourceId(), game);
+ targetPlayer.choose(Outcome.Discard, target, source, game);
Card card = targetPlayer.getHand().get(target.getFirstTarget(), game);
if (card != null && targetPlayer.discard(card, false, source, game)) {
return true;
diff --git a/Mage.Sets/src/mage/cards/c/ConchHorn.java b/Mage.Sets/src/mage/cards/c/ConchHorn.java
index 1fd78493047..a73e76cc1a7 100644
--- a/Mage.Sets/src/mage/cards/c/ConchHorn.java
+++ b/Mage.Sets/src/mage/cards/c/ConchHorn.java
@@ -73,7 +73,7 @@ class ConchHornEffect extends OneShotEffect {
private boolean putOnLibrary(Player player, Ability source, Game game) {
TargetCardInHand target = new TargetCardInHand();
- if (target.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (target.canChoose(player.getId(), source, game)) {
player.chooseTarget(Outcome.ReturnToHand, target, source, game);
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/c/ConcordWithTheKami.java b/Mage.Sets/src/mage/cards/c/ConcordWithTheKami.java
new file mode 100644
index 00000000000..841148ba064
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ConcordWithTheKami.java
@@ -0,0 +1,91 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.hint.ConditionHint;
+import mage.abilities.hint.Hint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.CounterAnyPredicate;
+import mage.filter.predicate.permanent.EnchantedPredicate;
+import mage.filter.predicate.permanent.EquippedPredicate;
+import mage.game.permanent.token.SpiritToken;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ConcordWithTheKami extends CardImpl {
+
+ private static final FilterPermanent counterFilter
+ = new FilterCreaturePermanent("creature with a counter on it");
+ private static final FilterPermanent enchantedFilter
+ = new FilterControlledCreaturePermanent();
+ private static final FilterPermanent equippedFilter
+ = new FilterControlledCreaturePermanent();
+
+ static {
+ counterFilter.add(CounterAnyPredicate.instance);
+ enchantedFilter.add(EnchantedPredicate.instance);
+ equippedFilter.add(EquippedPredicate.instance);
+ }
+
+ private static final Condition enchantedCondition
+ = new PermanentsOnTheBattlefieldCondition(enchantedFilter);
+ private static final Condition equippedCondition
+ = new PermanentsOnTheBattlefieldCondition(equippedFilter);
+ private static final Hint enchantedHint
+ = new ConditionHint(enchantedCondition, "You control an enchanted creature");
+ private static final Hint equippedHint
+ = new ConditionHint(equippedCondition, "You control an equipped creature");
+
+ public ConcordWithTheKami(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
+
+ // At the beginning of your end step, choose one or more —
+ // • Put a +1/+1 counter on target creature with a counter on it.
+ Ability ability = new BeginningOfEndStepTriggeredAbility(
+ new AddCountersTargetEffect(CounterType.P1P1.createInstance()), TargetController.YOU, false
+ );
+ ability.addTarget(new TargetPermanent(counterFilter));
+ ability.getModes().setMinModes(1);
+ ability.getModes().setMaxModes(3);
+
+ // • Draw a card if you control an enchanted creature.
+ ability.addMode(new Mode(new ConditionalOneShotEffect(
+ new DrawCardSourceControllerEffect(1), enchantedCondition,
+ "draw a card if you control an enchanted creature"
+ )));
+
+ // • Create a 1/1 colorless Spirit creature token if you control an equipped creature.
+ ability.addMode(new Mode(new ConditionalOneShotEffect(
+ new CreateTokenEffect(new SpiritToken()), equippedCondition,
+ "create a 1/1 colorless Spirit creature token if you control an equipped creature"
+ )));
+ this.addAbility(ability.addHint(enchantedHint).addHint(equippedHint));
+ }
+
+ private ConcordWithTheKami(final ConcordWithTheKami card) {
+ super(card);
+ }
+
+ @Override
+ public ConcordWithTheKami copy() {
+ return new ConcordWithTheKami(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/Condemn.java b/Mage.Sets/src/mage/cards/c/Condemn.java
index 57eb1a51afd..2871de61def 100644
--- a/Mage.Sets/src/mage/cards/c/Condemn.java
+++ b/Mage.Sets/src/mage/cards/c/Condemn.java
@@ -1,5 +1,3 @@
-
-
package mage.cards.c;
import java.util.UUID;
@@ -23,7 +21,7 @@ import mage.target.common.TargetAttackingCreature;
public final class Condemn extends CardImpl {
public Condemn(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
// Put target attacking creature on the bottom of its owner's library.
this.getSpellAbility().addTarget(new TargetAttackingCreature());
@@ -46,7 +44,7 @@ public final class Condemn extends CardImpl {
class CondemnEffect extends OneShotEffect {
public CondemnEffect() {
- super(Outcome.GainLife);
+ super(Outcome.Detriment);
staticText = "Its controller gains life equal to its toughness";
}
@@ -61,7 +59,7 @@ class CondemnEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Permanent permanent = (Permanent)game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD);
+ Permanent permanent = (Permanent) game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD);
if (permanent != null) {
Player player = game.getPlayer(permanent.getControllerId());
if (player != null) {
diff --git a/Mage.Sets/src/mage/cards/c/ConfoundingConundrum.java b/Mage.Sets/src/mage/cards/c/ConfoundingConundrum.java
index f393c1e6cd6..e8ceb3d5a4a 100644
--- a/Mage.Sets/src/mage/cards/c/ConfoundingConundrum.java
+++ b/Mage.Sets/src/mage/cards/c/ConfoundingConundrum.java
@@ -106,10 +106,10 @@ class ConfoundingConundrumEffect extends OneShotEffect {
}
TargetPermanent target = new TargetPermanent(1, StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND);
target.setNotTarget(true);
- if (!target.canChoose(source.getSourceId(), player.getId(), game)) {
+ if (!target.canChoose(player.getId(), source, game)) {
return false;
}
- player.choose(outcome, target, source.getSourceId(), game);
+ player.choose(outcome, target, source, game);
return player.moveCards(game.getCard(target.getFirstTarget()), Zone.HAND, source, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ConfrontThePast.java b/Mage.Sets/src/mage/cards/c/ConfrontThePast.java
index 8cafe8f05d2..310ae0c0e8e 100644
--- a/Mage.Sets/src/mage/cards/c/ConfrontThePast.java
+++ b/Mage.Sets/src/mage/cards/c/ConfrontThePast.java
@@ -43,8 +43,7 @@ public final class ConfrontThePast extends CardImpl {
this.getSpellAbility().setTargetAdjuster(ConfrontThePastAdjuster.instance);
// • Remove twice X loyalty counters from target planeswalker an opponent controls.
- Mode mode = new Mode();
- mode.addEffect(new ConfrontThePastLoyaltyEffect());
+ Mode mode = new Mode(new ConfrontThePastLoyaltyEffect());
mode.addTarget(new TargetPlaneswalkerPermanent(filter));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/CongregationAtDawn.java b/Mage.Sets/src/mage/cards/c/CongregationAtDawn.java
index 3c106d17b35..d1d604e46f5 100644
--- a/Mage.Sets/src/mage/cards/c/CongregationAtDawn.java
+++ b/Mage.Sets/src/mage/cards/c/CongregationAtDawn.java
@@ -61,14 +61,14 @@ class CongregationAtDawnEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller != null && sourceObject != null) {
TargetCardInLibrary target = new TargetCardInLibrary(0, 3, new FilterCreatureCard("creature cards"));
if (controller.searchLibrary(target, source, game)) {
if (!target.getTargets().isEmpty()) {
Cards revealed = new CardsImpl();
for (UUID cardId : target.getTargets()) {
- Card card = controller.getLibrary().remove(cardId, game);
+ Card card = controller.getLibrary().getCard(cardId, game);
revealed.add(card);
}
controller.revealCards(sourceObject.getName(), revealed, game);
diff --git a/Mage.Sets/src/mage/cards/c/ConniveConcoct.java b/Mage.Sets/src/mage/cards/c/ConniveConcoct.java
index d6144105e87..5cd00455179 100644
--- a/Mage.Sets/src/mage/cards/c/ConniveConcoct.java
+++ b/Mage.Sets/src/mage/cards/c/ConniveConcoct.java
@@ -93,7 +93,7 @@ class ConcoctEffect extends OneShotEffect {
player.surveil(3, source, game);
Target target = new TargetCardInYourGraveyard(filter);
target.setNotTarget(true);
- if (player.choose(outcome, target, source.getSourceId(), game)) {
+ if (player.choose(outcome, target, source, game)) {
Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect();
effect.setTargetPointer(new FixedTarget(target.getFirstTarget(), game));
effect.apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java b/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java
index 4a746bf8609..4d352e5fdaf 100644
--- a/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java
+++ b/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java
@@ -39,7 +39,7 @@ public final class ConstrictingSliver extends CardImpl {
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityControlledEffect(ability,
- Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS)
+ Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS)
.setText("Sliver creatures you control have \"When this creature enters the battlefield, "
+ "you may exile target creature an opponent controls until this creature leaves the battlefield.\"")));
diff --git a/Mage.Sets/src/mage/cards/c/ConsultTheNecrosages.java b/Mage.Sets/src/mage/cards/c/ConsultTheNecrosages.java
index de4b36fde6b..8808843a003 100644
--- a/Mage.Sets/src/mage/cards/c/ConsultTheNecrosages.java
+++ b/Mage.Sets/src/mage/cards/c/ConsultTheNecrosages.java
@@ -23,9 +23,8 @@ public final class ConsultTheNecrosages extends CardImpl {
// Choose one - Target player draws two cards; or target player discards two cards.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DrawCardTargetEffect(2));
- Mode mode = new Mode();
+ Mode mode = new Mode(new DiscardTargetEffect(2));
mode.addTarget(new TargetPlayer());
- mode.addEffect(new DiscardTargetEffect(2));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/ConsumingBonfire.java b/Mage.Sets/src/mage/cards/c/ConsumingBonfire.java
index b2dee98163a..30ce0c08c92 100644
--- a/Mage.Sets/src/mage/cards/c/ConsumingBonfire.java
+++ b/Mage.Sets/src/mage/cards/c/ConsumingBonfire.java
@@ -38,8 +38,7 @@ public final class ConsumingBonfire extends CardImpl {
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
//or Consuming Bonfire deals 7 damage to target Treefolk creature.
- Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(7));
+ Mode mode = new Mode(new DamageTargetEffect(7));
mode.addTarget(new TargetPermanent(filter2));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/ConsumingSinkhole.java b/Mage.Sets/src/mage/cards/c/ConsumingSinkhole.java
index 4a93844061b..5b1c94faafc 100644
--- a/Mage.Sets/src/mage/cards/c/ConsumingSinkhole.java
+++ b/Mage.Sets/src/mage/cards/c/ConsumingSinkhole.java
@@ -39,8 +39,7 @@ public final class ConsumingSinkhole extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
// Consuming Sinkhole deals 4 damage to target player.
- Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(4));
+ Mode mode = new Mode(new DamageTargetEffect(4));
mode.addTarget(new TargetPlayerOrPlaneswalker());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/ConsumingTide.java b/Mage.Sets/src/mage/cards/c/ConsumingTide.java
index 3e71ee8ec1c..01834bd2d68 100644
--- a/Mage.Sets/src/mage/cards/c/ConsumingTide.java
+++ b/Mage.Sets/src/mage/cards/c/ConsumingTide.java
@@ -70,7 +70,7 @@ class ConsumingTideEffect extends OneShotEffect {
if (player != null) {
TargetNonlandPermanent target = new TargetNonlandPermanent();
target.setNotTarget(true);
- player.choose(Outcome.Benefit, target, source.getSourceId(), game);
+ player.choose(Outcome.Benefit, target, source, game);
UUID permId = target.getFirstTarget();
if (permId != null) {
chosenPermanents.add(permId);
@@ -78,7 +78,7 @@ class ConsumingTideEffect extends OneShotEffect {
}
}
HashSet permanentsToHand = new HashSet<>();
- for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_NON_LAND, controller.getId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_NON_LAND, controller.getId(), source, game)) {
if (!chosenPermanents.contains(permanent.getId())) {
permanentsToHand.add(permanent);
}
diff --git a/Mage.Sets/src/mage/cards/c/ConsumingVapors.java b/Mage.Sets/src/mage/cards/c/ConsumingVapors.java
index f78dfbe7333..487f6ebb6c5 100644
--- a/Mage.Sets/src/mage/cards/c/ConsumingVapors.java
+++ b/Mage.Sets/src/mage/cards/c/ConsumingVapors.java
@@ -64,8 +64,8 @@ class ConsumingVaporsEffect extends OneShotEffect {
filter.add(TargetController.YOU.getControllerPredicate());
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
- if (player != null && target.canChoose(source.getSourceId(), player.getId(), game)) {
- player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
+ if (player != null && target.canChoose(player.getId(), source, game)) {
+ player.choose(Outcome.Sacrifice, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
diff --git a/Mage.Sets/src/mage/cards/c/Contagion.java b/Mage.Sets/src/mage/cards/c/Contagion.java
index 4a951ba2189..c1e223c9079 100644
--- a/Mage.Sets/src/mage/cards/c/Contagion.java
+++ b/Mage.Sets/src/mage/cards/c/Contagion.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.ExileFromHandCost;
@@ -12,24 +10,26 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.common.FilterOwnedCard;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreaturePermanentAmount;
+import java.util.UUID;
+
/**
- *
* @author Plopman
*/
public final class Contagion extends CardImpl {
- public Contagion(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{B}{B}");
+ private static final FilterOwnedCard filter
+ = new FilterOwnedCard("a black card from your hand");
- FilterOwnedCard filter = new FilterOwnedCard("black card from your hand");
+ static {
filter.add(new ColorPredicate(ObjectColor.BLACK));
- filter.add(Predicates.not(new CardIdPredicate(this.getId()))); // the exile cost can never be paid with the card itself
+ }
+
+ public Contagion(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B}{B}");
// You may pay 1 life and exile a black card from your hand rather than pay Contagion's mana cost.
AlternativeCostSourceAbility ability = new AlternativeCostSourceAbility(new PayLifeCost(1));
@@ -38,7 +38,10 @@ public final class Contagion extends CardImpl {
// Distribute two -2/-1 counters among one or two target creatures.
this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(2));
- this.getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.M2M1, 2, false, "one or two target creatures"));
+ this.getSpellAbility().addEffect(new DistributeCountersEffect(
+ CounterType.M2M1, 2, false,
+ "one or two target creatures"
+ ));
}
private Contagion(final Contagion card) {
diff --git a/Mage.Sets/src/mage/cards/c/ContainmentConstruct.java b/Mage.Sets/src/mage/cards/c/ContainmentConstruct.java
new file mode 100644
index 00000000000..47de50387c3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ContainmentConstruct.java
@@ -0,0 +1,121 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
+import mage.cards.Card;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+import mage.util.CardUtil;
+
+/**
+ * @author jeffwadsworth
+ */
+public final class ContainmentConstruct extends CardImpl {
+
+ public ContainmentConstruct(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
+
+ this.subtype.add(SubType.CONSTRUCT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Whenever you discard a card, you may exile that card from your graveyard. If you do, you may play that card this turn.
+ this.addAbility(new ContainmentConstructTriggeredAbility());
+
+ }
+
+ private ContainmentConstruct(final ContainmentConstruct card) {
+ super(card);
+ }
+
+ @Override
+ public ContainmentConstruct copy() {
+ return new ContainmentConstruct(this);
+ }
+}
+
+class ContainmentConstructTriggeredAbility extends TriggeredAbilityImpl {
+
+ public ContainmentConstructTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new ContainmentConstructEffect(), false);
+ }
+
+ public ContainmentConstructTriggeredAbility(final ContainmentConstructTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public ContainmentConstructTriggeredAbility copy() {
+ return new ContainmentConstructTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DISCARDED_CARD;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getPlayerId() == this.getControllerId()
+ && game.getState().getZone(event.getTargetId()) == Zone.GRAVEYARD) {
+ this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId()));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getTriggerPhrase() {
+ return "Whenever you discard a card, ";
+ }
+}
+
+class ContainmentConstructEffect extends OneShotEffect {
+
+ public ContainmentConstructEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "you may exile that card from your graveyard. If you do, you may play that card this turn";
+ }
+
+ public ContainmentConstructEffect(final ContainmentConstructEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ContainmentConstructEffect copy() {
+ return new ContainmentConstructEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Card discardedCard = game.getCard(targetPointer.getFirst(game, source));
+ Card containmentConstruct = game.getCard(source.getSourceId());
+ if (discardedCard != null
+ && containmentConstruct != null) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller.chooseUse(Outcome.Benefit, "Do you want to exile the discarded card? You may play it this turn from exile.", source, game)) {
+ UUID exileId = CardUtil.getExileZoneId(game, source);
+ controller.moveCardsToExile(discardedCard, source, game, true, exileId, "Exiled by " + containmentConstruct.getIdName());
+ PlayFromNotOwnHandZoneTargetEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(discardedCard.getId(), game));
+ game.addEffect(effect, source);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ContingencyPlan.java b/Mage.Sets/src/mage/cards/c/ContingencyPlan.java
index 18cf5006f1e..e3aefc29b9e 100644
--- a/Mage.Sets/src/mage/cards/c/ContingencyPlan.java
+++ b/Mage.Sets/src/mage/cards/c/ContingencyPlan.java
@@ -1,14 +1,11 @@
-
package mage.cards.c;
import java.util.UUID;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
/**
*
@@ -20,9 +17,7 @@ public final class ContingencyPlan extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}");
// Look at the top five cards of your library. Put any number of them into your graveyard and the rest back on top of your library in any order.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(StaticValue.get(5), false, StaticValue.get(5),
- new FilterCard("cards"), Zone.LIBRARY, true, false, true, Zone.GRAVEYARD, false));
-
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(5, Integer.MAX_VALUE, PutCards.GRAVEYARD, PutCards.TOP_ANY));
}
private ContingencyPlan(final ContingencyPlan card) {
diff --git a/Mage.Sets/src/mage/cards/c/ContrabandKingpin.java b/Mage.Sets/src/mage/cards/c/ContrabandKingpin.java
index b32c69e4b55..696bd8569bb 100644
--- a/Mage.Sets/src/mage/cards/c/ContrabandKingpin.java
+++ b/Mage.Sets/src/mage/cards/c/ContrabandKingpin.java
@@ -1,26 +1,25 @@
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
-import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
-import mage.filter.common.FilterControlledArtifactPermanent;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
/**
- *
* @author fireshoes
*/
public final class ContrabandKingpin extends CardImpl {
public ContrabandKingpin(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}");
this.subtype.add(SubType.AETHERBORN);
this.subtype.add(SubType.ROGUE);
this.power = new MageInt(1);
@@ -30,7 +29,10 @@ public final class ContrabandKingpin extends CardImpl {
this.addAbility(LifelinkAbility.getInstance());
// Whenever an artifact enters the battlefield under your control, scry 1.
- this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new ScryEffect(1, false), new FilterControlledArtifactPermanent(), false, null, true));
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
+ new ScryEffect(1, false),
+ StaticFilters.FILTER_PERMANENT_ARTIFACT_AN
+ ));
}
private ContrabandKingpin(final ContrabandKingpin card) {
diff --git a/Mage.Sets/src/mage/cards/c/Conviction.java b/Mage.Sets/src/mage/cards/c/Conviction.java
index 46151f22199..f3339222029 100644
--- a/Mage.Sets/src/mage/cards/c/Conviction.java
+++ b/Mage.Sets/src/mage/cards/c/Conviction.java
@@ -41,7 +41,7 @@ public final class Conviction extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 3, Duration.WhileOnBattlefield)));
// {W}: Return Conviction to its owner's hand.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("W")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl<>("{W}")));
}
private Conviction(final Conviction card) {
diff --git a/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java b/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java
index 91cdb882c24..592ff34873f 100644
--- a/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java
+++ b/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java
@@ -60,12 +60,12 @@ class CoordinatedBarrageEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Choice choice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
+ Choice choice = new ChoiceCreatureType(game.getObject(source));
if (controller.choose(Outcome.Damage, choice, game)) {
String chosenType = choice.getChoice();
FilterControlledPermanent filter = new FilterControlledPermanent();
filter.add(SubType.byDescription(chosenType).getPredicate());
- int damageDealt = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ int damageDealt = game.getBattlefield().count(filter, source.getControllerId(), source, game);
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) {
permanent.damage(damageDealt, source.getSourceId(), source, game, false, true);
diff --git a/Mage.Sets/src/mage/cards/c/CopperhornScout.java b/Mage.Sets/src/mage/cards/c/CopperhornScout.java
index 7be18f955d6..2887e93527c 100644
--- a/Mage.Sets/src/mage/cards/c/CopperhornScout.java
+++ b/Mage.Sets/src/mage/cards/c/CopperhornScout.java
@@ -16,7 +16,6 @@ import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
/**
@@ -91,7 +90,7 @@ class CopperhornScoutUntapEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
- List creatures = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
+ List creatures = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game);
for ( Permanent creature : creatures ) {
if ( !creature.getId().equals(source.getSourceId()) ) {
diff --git a/Mage.Sets/src/mage/cards/c/CoralTrickster.java b/Mage.Sets/src/mage/cards/c/CoralTrickster.java
index 7db134ee8b0..d329e648b35 100644
--- a/Mage.Sets/src/mage/cards/c/CoralTrickster.java
+++ b/Mage.Sets/src/mage/cards/c/CoralTrickster.java
@@ -28,7 +28,7 @@ public final class CoralTrickster extends CardImpl {
this.toughness = new MageInt(1);
// Morph {U}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{U}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{U}")));
// When Coral Trickster is turned face up, you may tap or untap target permanent.
Ability ability = new TurnedFaceUpSourceTriggeredAbility(new MayTapOrUntapTargetEffect());
ability.addTarget(new TargetPermanent());
diff --git a/Mage.Sets/src/mage/cards/c/CoralhelmChronicler.java b/Mage.Sets/src/mage/cards/c/CoralhelmChronicler.java
index e13ee671217..13a9d9baaf0 100644
--- a/Mage.Sets/src/mage/cards/c/CoralhelmChronicler.java
+++ b/Mage.Sets/src/mage/cards/c/CoralhelmChronicler.java
@@ -3,15 +3,14 @@ package mage.cards.c;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.keyword.KickerAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.AbilityPredicate;
@@ -45,11 +44,7 @@ public final class CoralhelmChronicler extends CardImpl {
// When Coralhelm Chronicler enters the battlefield, look at the top five cards of your library. You may reveal a card with a kicker ability from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
- StaticValue.get(5), false, StaticValue.get(1), filter, Zone.LIBRARY, false,
- true, false, Zone.HAND, true, false, false
- ).setBackInRandomOrder(true).setText("look at the top five cards of your library. " +
- "You may reveal a card with a kicker ability from among them and put it into your hand. " +
- "Put the rest on the bottom of your library in a random order")));
+ 5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM)));
}
private CoralhelmChronicler(final CoralhelmChronicler card) {
diff --git a/Mage.Sets/src/mage/cards/c/CormelaGlamourThief.java b/Mage.Sets/src/mage/cards/c/CormelaGlamourThief.java
new file mode 100644
index 00000000000..8c387bc0165
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CormelaGlamourThief.java
@@ -0,0 +1,65 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesSourceTriggeredAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.mana.ConditionalColoredManaAbility;
+import mage.abilities.mana.builder.common.InstantOrSorcerySpellManaBuilder;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CormelaGlamourThief extends CardImpl {
+
+ public CormelaGlamourThief(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // {1}, {T}: Add {U}{B}{R}. Spend this mana only to cast instant and/or sorcery spells.
+ Ability ability = new ConditionalColoredManaAbility(
+ new GenericManaCost(1),
+ new Mana(0, 1, 1, 1, 0, 0, 0, 0),
+ new InstantOrSorcerySpellManaBuilder()
+ );
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+
+ // When Cormela, Glamour Thief dies, return up to one target instant or sorcery card from your graveyard to your hand.
+ ability = new DiesSourceTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false);
+ ability.addTarget(new TargetCardInYourGraveyard(
+ 0, 1, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD
+ ));
+ this.addAbility(ability);
+ }
+
+ private CormelaGlamourThief(final CormelaGlamourThief card) {
+ super(card);
+ }
+
+ @Override
+ public CormelaGlamourThief copy() {
+ return new CormelaGlamourThief(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CorpseAppraiser.java b/Mage.Sets/src/mage/cards/c/CorpseAppraiser.java
new file mode 100644
index 00000000000..356eab6dd42
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CorpseAppraiser.java
@@ -0,0 +1,92 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetCard;
+import mage.target.common.TargetCardInGraveyard;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CorpseAppraiser extends CardImpl {
+
+ public CorpseAppraiser(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}{R}");
+
+ this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // When Corpse Appraiser enters the battlefield, exile up to one target creature card from a graveyard. If a card is put into exile this way, look at the top three cards of your library, then put one of those cards into your hand and the rest into your graveyard.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new CorpseAppraiserEffect());
+ ability.addTarget(new TargetCardInGraveyard(
+ 0, 1, StaticFilters.FILTER_CARD_CREATURE
+ ));
+ this.addAbility(ability);
+ }
+
+ private CorpseAppraiser(final CorpseAppraiser card) {
+ super(card);
+ }
+
+ @Override
+ public CorpseAppraiser copy() {
+ return new CorpseAppraiser(this);
+ }
+}
+
+class CorpseAppraiserEffect extends OneShotEffect {
+
+ CorpseAppraiserEffect() {
+ super(Outcome.Benefit);
+ staticText = "exile up to one target creature card from a graveyard. " +
+ "If a card is put into exile this way, look at the top three cards of your library, " +
+ "then put one of those cards into your hand and the rest into your graveyard";
+ }
+
+ private CorpseAppraiserEffect(final CorpseAppraiserEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CorpseAppraiserEffect copy() {
+ return new CorpseAppraiserEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ Card card = game.getCard(getTargetPointer().getFirst(game, source));
+ if (player == null || card == null) {
+ return false;
+ }
+ player.moveCards(card, Zone.EXILED, source, game);
+ if (!Zone.EXILED.match(game.getState().getZone(card.getId()))) {
+ return true;
+ }
+ Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 3));
+ if (cards.isEmpty()) {
+ return true;
+ }
+ TargetCard target = new TargetCardInLibrary();
+ player.choose(outcome, cards, target, game);
+ player.moveCards(cards.get(target.getFirstTarget(), game), Zone.HAND, source, game);
+ cards.retainZone(Zone.LIBRARY, game);
+ player.moveCards(cards, Zone.GRAVEYARD, source, game);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CorpseChurn.java b/Mage.Sets/src/mage/cards/c/CorpseChurn.java
index e27a3ade3a0..dd337e59ea5 100644
--- a/Mage.Sets/src/mage/cards/c/CorpseChurn.java
+++ b/Mage.Sets/src/mage/cards/c/CorpseChurn.java
@@ -64,9 +64,9 @@ class CorpseChurnEffect extends OneShotEffect {
}
TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD);
target.setNotTarget(true);
- if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
+ if (target.canChoose(source.getControllerId(), source, game)
&& controller.chooseUse(outcome, "Return a creature card from your graveyard to hand?", source, game)
- && controller.choose(Outcome.ReturnToHand, target, source.getSourceId(), game)) {
+ && controller.choose(Outcome.ReturnToHand, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.moveCards(card, Zone.HAND, source, game);
diff --git a/Mage.Sets/src/mage/cards/c/CorpseCur.java b/Mage.Sets/src/mage/cards/c/CorpseCur.java
index b41f588765f..f7c59480b54 100644
--- a/Mage.Sets/src/mage/cards/c/CorpseCur.java
+++ b/Mage.Sets/src/mage/cards/c/CorpseCur.java
@@ -1,46 +1,45 @@
-
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.keyword.InfectAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterCard;
+import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class CorpseCur extends CardImpl {
- private static final FilterCard filter = new FilterCard("creature card with infect from your graveyard");
+ private static final FilterCard filter = new FilterCreatureCard("creature card with infect from your graveyard");
static {
filter.add(new AbilityPredicate(InfectAbility.class));
}
- public CorpseCur (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}");
+ public CorpseCur(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.DOG);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.addAbility(InfectAbility.getInstance());
- Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect());
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
}
- public CorpseCur (final CorpseCur card) {
+ public CorpseCur(final CorpseCur card) {
super(card);
}
@@ -48,5 +47,4 @@ public final class CorpseCur extends CardImpl {
public CorpseCur copy() {
return new CorpseCur(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/c/CorpseExplosion.java b/Mage.Sets/src/mage/cards/c/CorpseExplosion.java
new file mode 100644
index 00000000000..d96a94f6f03
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CorpseExplosion.java
@@ -0,0 +1,82 @@
+package mage.cards.c;
+
+import java.util.List;
+import java.util.UUID;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.common.ExileFromGraveCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCardInYourGraveyard;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class CorpseExplosion extends CardImpl {
+
+ public CorpseExplosion(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{R}");
+
+ // As an additional cost to cast this spell, exile a creature card from your graveyard.
+ this.getSpellAbility().addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)));
+
+ // Corpse Explosion deals damage equal to the exiled card's power to each creature and each planeswalker.
+ this.getSpellAbility().addEffect(new CorpseExplosionEffect());
+ }
+
+ private CorpseExplosion(final CorpseExplosion card) {
+ super(card);
+ }
+
+ @Override
+ public CorpseExplosion copy() {
+ return new CorpseExplosion(this);
+ }
+}
+
+class CorpseExplosionEffect extends OneShotEffect {
+
+ public CorpseExplosionEffect() {
+ super(Outcome.Damage);
+ this.staticText = "{this} deals damage equal to the exiled card's power to each creature and each planeswalker";
+ }
+
+ private CorpseExplosionEffect(final CorpseExplosionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CorpseExplosionEffect copy() {
+ return new CorpseExplosionEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ int power = 0;
+ for (Cost cost : source.getCosts()) {
+ if (cost instanceof ExileFromGraveCost) {
+ List exiledCards = ((ExileFromGraveCost) cost).getExiledCards();
+ if (!exiledCards.isEmpty()) {
+ power = exiledCards.get(0).getPower().getValue();
+ break;
+ }
+ }
+ }
+ if (power < 1) {
+ return false;
+ }
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER, source.getControllerId(), source, game)) {
+ permanent.damage(power, source, game);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CorpseHauler.java b/Mage.Sets/src/mage/cards/c/CorpseHauler.java
index 443a0974058..7f98451e9ed 100644
--- a/Mage.Sets/src/mage/cards/c/CorpseHauler.java
+++ b/Mage.Sets/src/mage/cards/c/CorpseHauler.java
@@ -14,7 +14,7 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
-import mage.filter.predicate.mageobject.AnotherCardPredicate;
+import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetCardInYourGraveyard;
/**
@@ -26,7 +26,7 @@ public final class CorpseHauler extends CardImpl {
private static final FilterCard filter = new FilterCard("another target creature card from your graveyard");
static {
filter.add(CardType.CREATURE.getPredicate());
- filter.add(new AnotherCardPredicate());
+ filter.add(AnotherPredicate.instance);
}
public CorpseHauler(UUID ownerId, CardSetInfo setInfo) {
diff --git a/Mage.Sets/src/mage/cards/c/Corrosion.java b/Mage.Sets/src/mage/cards/c/Corrosion.java
index 309a29fadd2..665c49792f5 100644
--- a/Mage.Sets/src/mage/cards/c/Corrosion.java
+++ b/Mage.Sets/src/mage/cards/c/Corrosion.java
@@ -82,7 +82,7 @@ class CorrosionUpkeepEffect extends OneShotEffect {
}
}
// destroy each artifact with converted mana cost less than or equal to the number of rust counters on it
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
if (permanent.getManaValue() <= permanent.getCounters(game).getCount(CounterType.RUST)) {
permanent.destroy(source, game, true);
}
diff --git a/Mage.Sets/src/mage/cards/c/Corrupt.java b/Mage.Sets/src/mage/cards/c/Corrupt.java
index 6931d7489f4..09efcf60797 100644
--- a/Mage.Sets/src/mage/cards/c/Corrupt.java
+++ b/Mage.Sets/src/mage/cards/c/Corrupt.java
@@ -60,7 +60,7 @@ class CorruptEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- int amount = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ int amount = game.getBattlefield().count(filter, source.getControllerId(), source, game);
if (amount > 0) {
int damageDealt = amount;
Permanent permanent = game.getPermanent(source.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/c/CorruptedCrossroads.java b/Mage.Sets/src/mage/cards/c/CorruptedCrossroads.java
index b8d17d2578c..e915c4aeeb1 100644
--- a/Mage.Sets/src/mage/cards/c/CorruptedCrossroads.java
+++ b/Mage.Sets/src/mage/cards/c/CorruptedCrossroads.java
@@ -69,7 +69,7 @@ class BlightedCrossroadsConditionalMana extends ConditionalMana {
class BlightedCrossroadsManaCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
if (object != null) {
for (Ability ability: object.getAbilities()) {
if (ability instanceof DevoidAbility) {
diff --git a/Mage.Sets/src/mage/cards/c/CosisRavager.java b/Mage.Sets/src/mage/cards/c/CosisRavager.java
index 91e9555d6de..e968d862939 100644
--- a/Mage.Sets/src/mage/cards/c/CosisRavager.java
+++ b/Mage.Sets/src/mage/cards/c/CosisRavager.java
@@ -24,7 +24,7 @@ public final class CosisRavager extends CardImpl {
this.color.setRed(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- Ability ability = new LandfallAbility(new DamageTargetEffect(1), false);
+ Ability ability = new LandfallAbility(new DamageTargetEffect(1), true);
ability.addTarget(new TargetPlayerOrPlaneswalker());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/c/CouncilGuardian.java b/Mage.Sets/src/mage/cards/c/CouncilGuardian.java
index 21e9fcf94b2..967ace3d593 100644
--- a/Mage.Sets/src/mage/cards/c/CouncilGuardian.java
+++ b/Mage.Sets/src/mage/cards/c/CouncilGuardian.java
@@ -10,10 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.choices.VoteHandler;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.SubType;
+import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
@@ -38,7 +35,7 @@ public final class CouncilGuardian extends CardImpl {
// Will of the council - When Council Guardian enters the battlefield, starting with you, each player votes for blue, black, red, or green. Council Guardian gains protection from each color with the most votes or tied for most votes.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new CouncilsGuardianEffect(), false)
- .withFlavorWord("Will of the council")
+ .setAbilityWord(AbilityWord.WILL_OF_THE_COUNCIL)
);
}
diff --git a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java
index 54da84be391..69990b3afc8 100644
--- a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java
+++ b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java
@@ -76,7 +76,7 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifyingEffec
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
- MageObject mageObject = game.getObject(source.getSourceId());
+ MageObject mageObject = game.getObject(source);
if (mageObject != null) {
return "You can't cast a spell with that name (" + mageObject.getName() + " in play).";
}
diff --git a/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java b/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java
index 1c722445761..bc6f5f584e0 100644
--- a/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java
+++ b/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java
@@ -17,7 +17,6 @@ import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
-import mage.target.Target;
import mage.target.TargetPermanent;
import java.util.LinkedHashSet;
@@ -95,13 +94,13 @@ class CouncilsJudgmentVote extends VoteHandler {
@Override
public Permanent playerChoose(String voteInfo, Player player, Player decidingPlayer, Ability source, Game game) {
- if (game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) < 1) {
+ if (game.getBattlefield().count(filter, source.getControllerId(), source, game) < 1) {
return null;
}
TargetPermanent target = new TargetPermanent(1, filter);
target.withChooseHint(voteInfo + " (to exile)");
target.setNotTarget(true);
- decidingPlayer.choose(Outcome.Exile, target, source.getSourceId(), game);
+ decidingPlayer.choose(Outcome.Exile, target, source, game);
return game.getPermanent(target.getFirstTarget());
}
diff --git a/Mage.Sets/src/mage/cards/c/Counterbore.java b/Mage.Sets/src/mage/cards/c/Counterbore.java
index 23c6b437561..e32a041c13a 100644
--- a/Mage.Sets/src/mage/cards/c/Counterbore.java
+++ b/Mage.Sets/src/mage/cards/c/Counterbore.java
@@ -21,7 +21,7 @@ public final class Counterbore extends CardImpl {
// Counter target spell.
// Search its controller's graveyard, hand, and library for all cards with the same name as that spell and exile them. Then that player shuffles their library.
this.getSpellAbility().addTarget(new TargetSpell());
- this.getSpellAbility().addEffect(new CounterTargetAndSearchGraveyardHandLibraryEffect());
+ this.getSpellAbility().addEffect(new CounterTargetAndSearchGraveyardHandLibraryEffect().concatBy("."));
}
private Counterbore(final Counterbore card) {
diff --git a/Mage.Sets/src/mage/cards/c/Counterlash.java b/Mage.Sets/src/mage/cards/c/Counterlash.java
index 2e7eda53d13..458d03b8b14 100644
--- a/Mage.Sets/src/mage/cards/c/Counterlash.java
+++ b/Mage.Sets/src/mage/cards/c/Counterlash.java
@@ -1,15 +1,11 @@
package mage.cards.c;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import mage.ApprovingObject;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
+import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.FilterCard;
@@ -19,10 +15,13 @@ import mage.game.Game;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.TargetSpell;
-import mage.target.common.TargetCardInHand;
+import mage.util.CardUtil;
+
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
/**
- *
* @author BetaSteward
*/
public final class Counterlash extends CardImpl {
@@ -50,9 +49,9 @@ class CounterlashEffect extends OneShotEffect {
public CounterlashEffect() {
super(Outcome.Detriment);
- this.staticText = "Counter target spell. You may cast a nonland "
- + "card in your hand that shares a card type with that "
- + "spell without paying its mana cost";
+ this.staticText = "Counter target spell. You may cast a spell "
+ + "that shares a card type with it from your hand "
+ + "without paying its mana cost";
}
public CounterlashEffect(final CounterlashEffect effect) {
@@ -68,32 +67,21 @@ class CounterlashEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
- if (stackObject != null
- && controller != null) {
- game.getStack().counter(source.getFirstTarget(), source, game);
- if (controller.chooseUse(Outcome.PlayForFree, "Cast a nonland card in your hand that "
- + "shares a card type with that spell without paying its mana cost?", source, game)) {
- FilterCard filter = new FilterCard();
- List> types = new ArrayList<>();
- for (CardType type : stackObject.getCardType(game)) {
- if (type != CardType.LAND) {
- types.add(type.getPredicate());
- }
- }
- filter.add(Predicates.or(types));
- TargetCardInHand target = new TargetCardInHand(filter);
- if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
- Card card = controller.getHand().get(target.getFirstTarget(), game);
- if (card != null) {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- controller.cast(controller.chooseAbilityForCast(card, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- }
- }
- }
+ if (stackObject == null || controller == null) {
+ return false;
+ }
+ Set> predicates = stackObject
+ .getCardType(game)
+ .stream()
+ .map(CardType::getPredicate)
+ .collect(Collectors.toSet());
+ game.getStack().counter(source.getFirstTarget(), source, game);
+ if (predicates.isEmpty()) {
return true;
}
- return false;
+ FilterCard filter = new FilterCard();
+ filter.add(Predicates.or(predicates));
+ CardUtil.castSpellWithAttributesForFree(controller, source, game, new CardsImpl(controller.getHand()), filter);
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CountlessGearsRenegade.java b/Mage.Sets/src/mage/cards/c/CountlessGearsRenegade.java
index 374e9212c7a..96974b33217 100644
--- a/Mage.Sets/src/mage/cards/c/CountlessGearsRenegade.java
+++ b/Mage.Sets/src/mage/cards/c/CountlessGearsRenegade.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -16,6 +14,8 @@ import mage.constants.SubType;
import mage.game.permanent.token.ServoToken;
import mage.watchers.common.RevoltWatcher;
+import java.util.UUID;
+
/**
* @author JRHerlehy
*/
@@ -31,13 +31,13 @@ public final class CountlessGearsRenegade extends CardImpl {
// Revolt — When Countless Gears Renegade enters the battlefield, if a permanent you controlled
// left the battlefield this turn, create a 1/1 colorless Servo artifact creature token.
- Ability ability = new ConditionalInterveningIfTriggeredAbility(new EntersBattlefieldTriggeredAbility(
- new CreateTokenEffect(new ServoToken(), 1), false), RevoltCondition.instance,
- "Revolt — When {this} enters the battlefield, if a permanent you controlled left"
- + " the battlefield this turn, create a 1/1 colorless Servo artifact creature token.");
+ Ability ability = new ConditionalInterveningIfTriggeredAbility(
+ new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ServoToken()), false),
+ RevoltCondition.instance, "When {this} enters the battlefield, if a permanent you controlled " +
+ "left the battlefield this turn, create a 1/1 colorless Servo artifact creature token."
+ );
ability.setAbilityWord(AbilityWord.REVOLT);
- ability.addWatcher(new RevoltWatcher());
- this.addAbility(ability);
+ this.addAbility(ability, new RevoltWatcher());
}
private CountlessGearsRenegade(final CountlessGearsRenegade card) {
diff --git a/Mage.Sets/src/mage/cards/c/CourageousOutrider.java b/Mage.Sets/src/mage/cards/c/CourageousOutrider.java
index 68d726c52ee..5ef2464947f 100644
--- a/Mage.Sets/src/mage/cards/c/CourageousOutrider.java
+++ b/Mage.Sets/src/mage/cards/c/CourageousOutrider.java
@@ -1,11 +1,10 @@
-
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -33,7 +32,8 @@ public final class CourageousOutrider extends CardImpl {
// When Courageous Outrider enters the battlefield, look at the top four cards of your library. You may reveal a Human card from among them
// and put it into your hand. Put the rest on the bottom of your library in any order.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(StaticValue.get(4), false, StaticValue.get(1), filter, false) , false));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
+ 4, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY)));
}
private CourageousOutrider(final CourageousOutrider card) {
diff --git a/Mage.Sets/src/mage/cards/c/CouriersBriefcase.java b/Mage.Sets/src/mage/cards/c/CouriersBriefcase.java
new file mode 100644
index 00000000000..5297235f442
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CouriersBriefcase.java
@@ -0,0 +1,55 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.mana.AnyColorManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.permanent.token.CitizenGreenWhiteToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CouriersBriefcase extends CardImpl {
+
+ public CouriersBriefcase(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{G}");
+
+ this.subtype.add(SubType.TREASURE);
+
+ // When Courier's Briefcase enters the battlefield, create a 1/1 green and white Citizen creature token.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new CitizenGreenWhiteToken())));
+
+ // {T}, Sacrifice Courier's Briefcase: Add one mana of any color.
+ Ability ability = new AnyColorManaAbility();
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+
+ // {W}{U}{B}{R}{G}, {T}, Sacrifice Courier's Briefcase: Draw three cards.
+ ability = new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(3), new ManaCostsImpl<>("{W}{U}{B}{R}{G}")
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ private CouriersBriefcase(final CouriersBriefcase card) {
+ super(card);
+ }
+
+ @Override
+ public CouriersBriefcase copy() {
+ return new CouriersBriefcase(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CourtHomunculus.java b/Mage.Sets/src/mage/cards/c/CourtHomunculus.java
index f1c52d18e70..6d02aa9b1e3 100644
--- a/Mage.Sets/src/mage/cards/c/CourtHomunculus.java
+++ b/Mage.Sets/src/mage/cards/c/CourtHomunculus.java
@@ -54,7 +54,7 @@ class ControlsAnotherArtifactCondition implements Condition {
public boolean apply(Game game, Ability source) {
List controlledArtifacts = game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), source.getControllerId(), game);
for (Permanent permanent : controlledArtifacts) {
- if (!permanent.getId().equals(game.getObject(source.getSourceId()).getId())) {
+ if (!permanent.getId().equals(game.getObject(source).getId())) {
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CourtHussar.java b/Mage.Sets/src/mage/cards/c/CourtHussar.java
index 4808edfac53..af4d720f610 100644
--- a/Mage.Sets/src/mage/cards/c/CourtHussar.java
+++ b/Mage.Sets/src/mage/cards/c/CourtHussar.java
@@ -1,12 +1,11 @@
-
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.ManaWasSpentCondition;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.abilities.effects.common.SacrificeSourceUnlessConditionEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
@@ -14,8 +13,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ColoredManaSymbol;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
/**
*
@@ -34,9 +31,7 @@ public final class CourtHussar extends CardImpl {
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// When Court Hussar enters the battlefield, look at the top three cards of your library, then put one of them into your hand and the rest on the bottom of your library in any order.
- this.addAbility(new EntersBattlefieldTriggeredAbility(
- new LookLibraryAndPickControllerEffect(StaticValue.get(3), false, StaticValue.get(1), new FilterCard(), Zone.LIBRARY, false, false),
- false));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(3, 1, PutCards.HAND, PutCards.BOTTOM_ANY)));
// When Court Hussar enters the battlefield, sacrifice it unless {W} was spent to cast it.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessConditionEffect(new ManaWasSpentCondition(ColoredManaSymbol.W)), false));
}
@@ -50,4 +45,3 @@ public final class CourtHussar extends CardImpl {
return new CourtHussar(this);
}
}
-
diff --git a/Mage.Sets/src/mage/cards/c/CourtOfAmbition.java b/Mage.Sets/src/mage/cards/c/CourtOfAmbition.java
index 453c0f88b8f..9cf70bf1ce5 100644
--- a/Mage.Sets/src/mage/cards/c/CourtOfAmbition.java
+++ b/Mage.Sets/src/mage/cards/c/CourtOfAmbition.java
@@ -82,7 +82,7 @@ class CourtOfAmbitionEffect extends OneShotEffect {
continue;
}
TargetDiscard target = new TargetDiscard(discardCount, StaticFilters.FILTER_CARD, playerId);
- player.choose(Outcome.Discard, target, source.getSourceId(), game);
+ player.choose(Outcome.Discard, target, source, game);
discardMap.put(playerId, new CardsImpl(target.getTargets()));
}
for (Map.Entry entry : discardMap.entrySet()) {
diff --git a/Mage.Sets/src/mage/cards/c/CourtOfBounty.java b/Mage.Sets/src/mage/cards/c/CourtOfBounty.java
index 3e6828b6f9f..392ba066553 100644
--- a/Mage.Sets/src/mage/cards/c/CourtOfBounty.java
+++ b/Mage.Sets/src/mage/cards/c/CourtOfBounty.java
@@ -10,9 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
-import mage.filter.FilterCard;
import mage.filter.StaticFilters;
-import mage.filter.predicate.Predicates;
import java.util.UUID;
@@ -21,15 +19,6 @@ import java.util.UUID;
*/
public final class CourtOfBounty extends CardImpl {
- private static final FilterCard filter = new FilterCard("a creature or land card");
-
- static {
- filter.add(Predicates.or(
- CardType.CREATURE.getPredicate(),
- CardType.LAND.getPredicate()
- ));
- }
-
public CourtOfBounty(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");
@@ -38,7 +27,7 @@ public final class CourtOfBounty extends CardImpl {
// At the beginning of your upkeep, you may put a land card from your hand onto the battlefield. If you're the monarch, instead you may put a creature or land card from your hand onto the battlefield.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ConditionalOneShotEffect(
- new PutCardFromHandOntoBattlefieldEffect(filter),
+ new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_OR_LAND),
new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A),
MonarchIsSourceControllerCondition.instance, "you may put a land card " +
"from your hand onto the battlefield. If you're the monarch, " +
diff --git a/Mage.Sets/src/mage/cards/c/CoverOfDarkness.java b/Mage.Sets/src/mage/cards/c/CoverOfDarkness.java
index c3b97c757dc..e525d953b48 100644
--- a/Mage.Sets/src/mage/cards/c/CoverOfDarkness.java
+++ b/Mage.Sets/src/mage/cards/c/CoverOfDarkness.java
@@ -1,7 +1,7 @@
package mage.cards.c;
-import java.util.UUID;
+import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
@@ -14,8 +14,9 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class CoverOfDarkness extends CardImpl {
@@ -58,10 +59,10 @@ class FilterCoverOfDarkness extends FilterCreaturePermanent {
}
@Override
- public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
- if (super.match(permanent, sourceId, playerId, game)) {
+ public boolean match(Permanent permanent, UUID playerId, Ability source, Game game) {
+ if (super.match(permanent, playerId, source, game)) {
if (subType == null) {
- subType = ChooseCreatureTypeEffect.getChosenCreatureType(sourceId, game);
+ subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
if (subType == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/CovetedPrize.java b/Mage.Sets/src/mage/cards/c/CovetedPrize.java
index 5fd841994c9..95a0aee9705 100644
--- a/Mage.Sets/src/mage/cards/c/CovetedPrize.java
+++ b/Mage.Sets/src/mage/cards/c/CovetedPrize.java
@@ -4,14 +4,17 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.FullPartyCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.dynamicvalue.common.PartyCount;
-import mage.abilities.effects.common.cost.CastWithoutPayingManaCostEffect;
+import mage.abilities.effects.common.cost.CastFromHandForFreeEffect;
import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.abilities.hint.common.PartyCountHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.ComparisonType;
import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
@@ -21,6 +24,12 @@ import java.util.UUID;
*/
public final class CovetedPrize extends CardImpl {
+ private static final FilterCard filter = new FilterCard("a spell with mana value 4 or less");
+
+ static {
+ filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 5));
+ }
+
public CovetedPrize(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
@@ -32,7 +41,7 @@ public final class CovetedPrize extends CardImpl {
// Search your library for a card, put it into your hand, then shuffle your library. If you have a full party, you may cast a spell with converted mana cost 4 or less from your hand without paying its mana cost.
this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary()));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new CastWithoutPayingManaCostEffect(4),
+ new CastFromHandForFreeEffect(filter),
FullPartyCondition.instance, "If you have a full party, " +
"you may cast a spell with mana value 4 or less from your hand without paying its mana cost."
));
diff --git a/Mage.Sets/src/mage/cards/c/CowerInFear.java b/Mage.Sets/src/mage/cards/c/CowerInFear.java
index 3a29280e2a5..7e089889e77 100644
--- a/Mage.Sets/src/mage/cards/c/CowerInFear.java
+++ b/Mage.Sets/src/mage/cards/c/CowerInFear.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -7,8 +6,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.TargetController;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.StaticFilters;
/**
*
@@ -16,18 +14,11 @@ import mage.filter.common.FilterCreaturePermanent;
*/
public final class CowerInFear extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
-
- static {
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public CowerInFear(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{B}{B}");
-
// Creatures your opponents control get -1/-1 until end of turn.
- this.getSpellAbility().addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false));
+ this.getSpellAbility().addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES, false));
}
private CowerInFear(final CowerInFear card) {
diff --git a/Mage.Sets/src/mage/cards/c/Crackleburr.java b/Mage.Sets/src/mage/cards/c/Crackleburr.java
index 7b19db74d84..f3a6900fbd1 100644
--- a/Mage.Sets/src/mage/cards/c/Crackleburr.java
+++ b/Mage.Sets/src/mage/cards/c/Crackleburr.java
@@ -32,8 +32,8 @@ import mage.target.common.TargetCreaturePermanent;
*/
public final class Crackleburr extends CardImpl {
- private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("two untapped red creatures you control");
- private static final FilterControlledCreaturePermanent filter2 = new FilterControlledCreaturePermanent("two tapped blue creatures you control");
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped red creatures you control");
+ private static final FilterControlledCreaturePermanent filter2 = new FilterControlledCreaturePermanent("tapped blue creature you control");
static {
filter.add(new ColorPredicate(ObjectColor.RED));
diff --git a/Mage.Sets/src/mage/cards/c/CracklingDoom.java b/Mage.Sets/src/mage/cards/c/CracklingDoom.java
index e7a57c37b0f..e3d85a853be 100644
--- a/Mage.Sets/src/mage/cards/c/CracklingDoom.java
+++ b/Mage.Sets/src/mage/cards/c/CracklingDoom.java
@@ -93,7 +93,7 @@ class CracklingDoomEffect extends OneShotEffect {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature to sacrifice with power equal to " + greatestPower);
filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, greatestPower));
Target target = new TargetControlledCreaturePermanent(filter);
- if (opponent.choose(outcome, target, playerId, game)) {
+ if (opponent.choose(outcome, target, source, game)) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
toSacrifice.add(permanent);
diff --git a/Mage.Sets/src/mage/cards/c/CracklingEmergence.java b/Mage.Sets/src/mage/cards/c/CracklingEmergence.java
new file mode 100644
index 00000000000..b4756ff1419
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CracklingEmergence.java
@@ -0,0 +1,113 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BecomesCreatureAttachedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.custom.CreatureToken;
+import mage.target.TargetPermanent;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CracklingEmergence extends CardImpl {
+
+ public CracklingEmergence(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant land you control
+ TargetPermanent auraTarget = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND);
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
+
+ // Enchanted land is a 3/3 red Spirit creature with haste. It's still a land.
+ this.addAbility(new SimpleStaticAbility(new BecomesCreatureAttachedEffect(
+ new CreatureToken(3, 3)
+ .withColor("R")
+ .withSubType(SubType.SPIRIT)
+ .withAbility(HasteAbility.getInstance()),
+ "enchanted land is a 3/3 red Spirit creature with haste. It's still a land",
+ Duration.WhileOnBattlefield, BecomesCreatureAttachedEffect.LoseType.COLOR
+ )));
+
+ // If enchanted land would be destroyed, instead sacrifice Crackling Emergence and that land gains indestructible until end of turn.
+ this.addAbility(new SimpleStaticAbility(new CracklingEmergenceEffect()));
+ }
+
+ private CracklingEmergence(final CracklingEmergence card) {
+ super(card);
+ }
+
+ @Override
+ public CracklingEmergence copy() {
+ return new CracklingEmergence(this);
+ }
+}
+
+class CracklingEmergenceEffect extends ReplacementEffectImpl {
+
+ CracklingEmergenceEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Benefit);
+ staticText = "if enchanted land would be destroyed, instead sacrifice " +
+ "{this} and that land gains indestructible until end of turn";
+ }
+
+ private CracklingEmergenceEffect(final CracklingEmergenceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
+ Permanent enchantedPermanent = game.getPermanent(event.getTargetId());
+ if (sourcePermanent == null || enchantedPermanent == null) {
+ return false;
+ }
+ sourcePermanent.sacrifice(source, game);
+ game.addEffect(new GainAbilityTargetEffect(IndestructibleAbility.getInstance())
+ .setTargetPointer(new FixedTarget(enchantedPermanent, game)), source);
+ return true;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DESTROY_PERMANENT;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
+ return sourcePermanent != null && event.getTargetId().equals(sourcePermanent.getAttachedTo());
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public CracklingEmergenceEffect copy() {
+ return new CracklingEmergenceEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CragganwickCremator.java b/Mage.Sets/src/mage/cards/c/CragganwickCremator.java
index 2106008dfeb..e8eddeca762 100644
--- a/Mage.Sets/src/mage/cards/c/CragganwickCremator.java
+++ b/Mage.Sets/src/mage/cards/c/CragganwickCremator.java
@@ -52,7 +52,7 @@ class CragganwickCrematorEffect extends OneShotEffect {
public CragganwickCrematorEffect() {
super(Outcome.Neutral);
- this.staticText = "discard a card at random. If you discard a creature card this way, {this} deals damage equal to that card's power to target player";
+ this.staticText = "discard a card at random. If you discard a creature card this way, {this} deals damage equal to that card's power to target player or planeswalker";
}
public CragganwickCrematorEffect(final CragganwickCrematorEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CrashTheParty.java b/Mage.Sets/src/mage/cards/c/CrashTheParty.java
new file mode 100644
index 00000000000..33ea58a6374
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CrashTheParty.java
@@ -0,0 +1,51 @@
+package mage.cards.c;
+
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.permanent.token.RhinoWarriorToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CrashTheParty extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledCreaturePermanent("tapped creature you control");
+
+ static {
+ filter.add(TappedPredicate.TAPPED);
+ }
+
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter, 1);
+ private static final Hint hint = new ValueHint("Tapped creatures you control", xValue);
+
+ public CrashTheParty(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{G}");
+
+ // Create a tapped 4/4 green Rhino Warrior creature token for each tapped creature you control.
+ this.getSpellAbility().addEffect(new CreateTokenEffect(
+ new RhinoWarriorToken(), xValue, true, false
+ ));
+ this.getSpellAbility().addHint(hint);
+ }
+
+ private CrashTheParty(final CrashTheParty card) {
+ super(card);
+ }
+
+ @Override
+ public CrashTheParty copy() {
+ return new CrashTheParty(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CrashingBoars.java b/Mage.Sets/src/mage/cards/c/CrashingBoars.java
index b9e66a2c13f..d2c5a1e4c71 100644
--- a/Mage.Sets/src/mage/cards/c/CrashingBoars.java
+++ b/Mage.Sets/src/mage/cards/c/CrashingBoars.java
@@ -74,7 +74,7 @@ class CrashingBoarsEffect extends OneShotEffect {
Player defendingPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (defendingPlayer != null) {
Target target = new TargetControlledCreaturePermanent(1, 1, filter, true);
- if (target.choose(Outcome.Neutral, defendingPlayer.getId(), source.getSourceId(), game)) {
+ if (target.choose(Outcome.Neutral, defendingPlayer.getId(), source.getSourceId(), source, game)) {
RequirementEffect effect = new MustBeBlockedByTargetSourceEffect();
effect.setTargetPointer(new FixedTarget(target.getFirstTarget(), game));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java b/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java
index 0a66219f2cb..112a06f0fe3 100644
--- a/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java
+++ b/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java
@@ -36,7 +36,7 @@ public final class CreamOfTheCrop extends CardImpl {
+ "you may look at the top X cards of your library, where X "
+ "is that creature's power. If you do, put one of those cards "
+ "on top of your library and the rest on the bottom of "
- + "your library in any order"));
+ + "your library in any order."));
}
private CreamOfTheCrop(final CreamOfTheCrop card) {
diff --git a/Mage.Sets/src/mage/cards/c/CreativeOutburst.java b/Mage.Sets/src/mage/cards/c/CreativeOutburst.java
index 2c39e9e4dfc..9dbe0bb2675 100644
--- a/Mage.Sets/src/mage/cards/c/CreativeOutburst.java
+++ b/Mage.Sets/src/mage/cards/c/CreativeOutburst.java
@@ -4,15 +4,14 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.effects.common.LookLibraryControllerEffect.PutCards;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
-import mage.filter.StaticFilters;
import mage.game.permanent.token.TreasureToken;
import mage.target.common.TargetAnyTarget;
@@ -28,11 +27,7 @@ public final class CreativeOutburst extends CardImpl {
// Creative Outburst deals 5 damage to any target. Look at the top five cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order.
this.getSpellAbility().addEffect(new DamageTargetEffect(5));
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(5), false, StaticValue.get(1),
- StaticFilters.FILTER_CARD, Zone.LIBRARY, false, false
- ).setBackInRandomOrder(true).setText("Look at the top five cards of your library. " +
- "Put one of them into your hand and the rest on the bottom of your library in a random order"));
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(5, 1, PutCards.HAND, PutCards.BOTTOM_RANDOM));
this.getSpellAbility().addTarget(new TargetAnyTarget());
// {U/R}{U/R}, Discard Creative Outburst: Create a Treasure token.
diff --git a/Mage.Sets/src/mage/cards/c/CreativeTechnique.java b/Mage.Sets/src/mage/cards/c/CreativeTechnique.java
index 8ad5c336c5a..a243785617b 100644
--- a/Mage.Sets/src/mage/cards/c/CreativeTechnique.java
+++ b/Mage.Sets/src/mage/cards/c/CreativeTechnique.java
@@ -1,6 +1,5 @@
package mage.cards.c;
-import mage.ApprovingObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.DemonstrateAbility;
@@ -10,6 +9,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
+import mage.util.CardUtil;
import java.util.UUID;
@@ -78,18 +78,7 @@ class CreativeTechniqueEffect extends OneShotEffect {
player.moveCards(toCast, Zone.EXILED, source, game);
}
player.putCardsOnBottomOfLibrary(cards, game, source, false);
- if (toCast == null || !player.chooseUse(
- Outcome.PlayForFree, "Cast " + toCast.getIdName()
- + " without paying its mana cost?", source, game
- )) {
- return true;
- }
- game.getState().setValue("PlayFromNotOwnHandZone" + toCast.getId(), Boolean.TRUE);
- player.cast(
- player.chooseAbilityForCast(toCast, game, true),
- game, true, new ApprovingObject(source, game)
- );
- game.getState().setValue("PlayFromNotOwnHandZone" + toCast.getId(), null);
+ CardUtil.castSpellWithAttributesForFree(player, source, game, toCast);
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CreatureBond.java b/Mage.Sets/src/mage/cards/c/CreatureBond.java
index 9e19b52bdbb..eb28133c1a1 100644
--- a/Mage.Sets/src/mage/cards/c/CreatureBond.java
+++ b/Mage.Sets/src/mage/cards/c/CreatureBond.java
@@ -1,10 +1,10 @@
-
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.DiesAttachedTriggeredAbility;
-import mage.abilities.dynamicvalue.common.AttachedPermanentToughnessValue;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DamageAttachedControllerEffect;
import mage.abilities.keyword.EnchantAbility;
@@ -13,6 +13,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
@@ -24,18 +27,19 @@ public final class CreatureBond extends CardImpl {
public CreatureBond(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
-
+
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
- this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// When enchanted creature dies, Creature Bond deals damage equal to that creature's toughness to the creature's controller.
- this.addAbility( new DiesAttachedTriggeredAbility(new DamageAttachedControllerEffect(AttachedPermanentToughnessValue.instance), "enchanted creature"));
+ Effect effect = new DamageAttachedControllerEffect(CreatureBondValue.instance);
+ effect.setText("{this} deals damage equal to that creature's toughness to the creature's controller");
+ this.addAbility(new DiesAttachedTriggeredAbility(effect, "enchanted creature"));
}
private CreatureBond(final CreatureBond card) {
@@ -47,3 +51,32 @@ public final class CreatureBond extends CardImpl {
return new CreatureBond(this);
}
}
+
+enum CreatureBondValue implements DynamicValue {
+ instance;
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ // In the case that the enchantment is blinked
+ Permanent enchantment = (Permanent) game.getLastKnownInformation(sourceAbility.getSourceId(), Zone.BATTLEFIELD);
+ if (enchantment == null) {
+ // It was not blinked, use the standard method
+ enchantment = game.getPermanentOrLKIBattlefield(sourceAbility.getSourceId());
+ }
+ if (enchantment == null) {
+ return 0;
+ }
+ Permanent enchanted = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo());
+ return enchanted.getToughness().getValue();
+ }
+
+ @Override
+ public CreatureBondValue copy() {
+ return instance;
+ }
+
+ @Override
+ public String getMessage() {
+ return "that creature's toughness";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CreditVoucher.java b/Mage.Sets/src/mage/cards/c/CreditVoucher.java
index 2fdc5e4bc6a..5b7a871fa5e 100644
--- a/Mage.Sets/src/mage/cards/c/CreditVoucher.java
+++ b/Mage.Sets/src/mage/cards/c/CreditVoucher.java
@@ -65,13 +65,13 @@ class CreditVoucherEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- MageObject sourceObject = game.getObject(source.getSourceId());
+ MageObject sourceObject = game.getObject(source);
if (controller != null && sourceObject != null) {
FilterCard filter = new FilterCard("card in your hand to shuffle away");
TargetCardInHand target = new TargetCardInHand(0, controller.getHand().size(), filter);
target.setRequired(false);
int amountShuffled = 0;
- if (target.canChoose(source.getSourceId(), source.getControllerId(), game) && target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) {
+ if (target.canChoose(source.getControllerId(), source, game) && target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), source, game)) {
if (!target.getTargets().isEmpty()) {
amountShuffled = target.getTargets().size();
controller.moveCards(new CardsImpl(target.getTargets()), Zone.LIBRARY, source, game);
diff --git a/Mage.Sets/src/mage/cards/c/CreepingInn.java b/Mage.Sets/src/mage/cards/c/CreepingInn.java
index 5ba7b0aa98c..81125611374 100644
--- a/Mage.Sets/src/mage/cards/c/CreepingInn.java
+++ b/Mage.Sets/src/mage/cards/c/CreepingInn.java
@@ -84,8 +84,8 @@ class CreepingInnEffect extends OneShotEffect {
UUID exileId = CardUtil.getExileZoneId(game, source);
TargetCardInGraveyard target = new TargetCardInGraveyard(0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD);
target.setNotTarget(true);
- if (target.canChoose(source.getSourceId(), player.getId(), game)) {
- if (player.choose(Outcome.Exile, target, source.getId(), game)) {
+ if (target.canChoose(player.getId(), source, game)) {
+ if (player.choose(Outcome.Exile, target, source, game)) {
Card cardChosen = game.getCard(target.getFirstTarget());
if (cardChosen != null) {
int lifeAmount = 0;
diff --git a/Mage.Sets/src/mage/cards/c/CreepingRenaissance.java b/Mage.Sets/src/mage/cards/c/CreepingRenaissance.java
index 10f09e1f1d3..23cbf17c3ae 100644
--- a/Mage.Sets/src/mage/cards/c/CreepingRenaissance.java
+++ b/Mage.Sets/src/mage/cards/c/CreepingRenaissance.java
@@ -10,7 +10,6 @@ import mage.choices.Choice;
import mage.choices.ChoiceCardType;
import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
@@ -76,7 +75,7 @@ class CreepingRenaissanceEffect extends OneShotEffect {
}
FilterCard filter = new FilterCard(chosenType.toString().toLowerCase(Locale.ENGLISH) + " card");
filter.add(chosenType.getPredicate());
- return controller.moveCards(controller.getGraveyard().getCards(filter, source.getSourceId(), controller.getId(), game), Zone.HAND, source, game);
+ return controller.moveCards(controller.getGraveyard().getCards(filter, controller.getId(), source, game), Zone.HAND, source, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/c/CrewCaptain.java b/Mage.Sets/src/mage/cards/c/CrewCaptain.java
new file mode 100644
index 00000000000..fa70c900e80
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CrewCaptain.java
@@ -0,0 +1,65 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CrewCaptain extends CardImpl {
+
+ public CrewCaptain(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Crew Captain has indestructible as long as it entered the battlefield this turn.
+ this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new GainAbilitySourceEffect(IndestructibleAbility.getInstance()), CrewCaptainCondition.instance,
+ "{this} has indestructible as long as it entered the battlefield this turn"
+ )));
+ }
+
+ private CrewCaptain(final CrewCaptain card) {
+ super(card);
+ }
+
+ @Override
+ public CrewCaptain copy() {
+ return new CrewCaptain(this);
+ }
+}
+
+enum CrewCaptainCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return Optional.of(source.getSourcePermanentIfItStillExists(game))
+ .filter(Objects::nonNull)
+ .map(Permanent::getTurnsOnBattlefield)
+ .orElseGet(() -> -1) == 0;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/CrimsonRoc.java b/Mage.Sets/src/mage/cards/c/CrimsonRoc.java
index 72d8899a991..f6094a32d18 100644
--- a/Mage.Sets/src/mage/cards/c/CrimsonRoc.java
+++ b/Mage.Sets/src/mage/cards/c/CrimsonRoc.java
@@ -1,7 +1,10 @@
package mage.cards.c;
import mage.MageInt;
+import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.BlocksCreatureTriggeredAbility;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.FirstStrikeAbility;
@@ -12,6 +15,9 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@@ -23,6 +29,12 @@ import java.util.UUID;
*/
public final class CrimsonRoc extends CardImpl {
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature without flying");
+
+ static {
+ filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
+ }
+
public CrimsonRoc(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
@@ -34,7 +46,13 @@ public final class CrimsonRoc extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever Crimson Roc blocks a creature without flying, Crimson Roc gets +1/+0 and gains first strike until end of turn.
- this.addAbility(new CrimsonRocTriggeredAbility());
+ Ability ability = new BlocksCreatureTriggeredAbility(new BoostSourceEffect(
+ 1, 0, Duration.EndOfTurn
+ ).setText("{this} gets +1/+0"), filter, false);
+ ability.addEffect(new GainAbilitySourceEffect(
+ FirstStrikeAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains first strike until end of turn"));
+ this.addAbility(ability);
}
private CrimsonRoc(final CrimsonRoc card) {
@@ -45,43 +63,4 @@ public final class CrimsonRoc extends CardImpl {
public CrimsonRoc copy() {
return new CrimsonRoc(this);
}
-}
-
-class CrimsonRocTriggeredAbility extends TriggeredAbilityImpl {
-
- CrimsonRocTriggeredAbility() {
- super(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), false);
- this.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn));
- }
-
- private CrimsonRocTriggeredAbility(final CrimsonRocTriggeredAbility ability) {
- super(ability);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.BLOCKER_DECLARED;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- if (!event.getSourceId().equals(this.getSourceId())) {
- return false;
- }
- Permanent permanent = game.getPermanent(event.getTargetId());
- return permanent != null
- && permanent.isCreature(game)
- && !permanent.hasAbility(FlyingAbility.getInstance(), game);
- }
-
- @Override
- public String getRule() {
- return "Whenever {this} blocks a creature without flying, " +
- "{this} gets +1/+0 and gains first strike until end of turn.";
- }
-
- @Override
- public CrimsonRocTriggeredAbility copy() {
- return new CrimsonRocTriggeredAbility(this);
- }
-}
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/CrimsonWisps.java b/Mage.Sets/src/mage/cards/c/CrimsonWisps.java
index 1d45f2931bb..7d0bcb5d883 100644
--- a/Mage.Sets/src/mage/cards/c/CrimsonWisps.java
+++ b/Mage.Sets/src/mage/cards/c/CrimsonWisps.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.c;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BecomesColorTargetEffect;
@@ -14,25 +11,30 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX
*/
public final class CrimsonWisps extends CardImpl {
- public CrimsonWisps (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");
+ public CrimsonWisps(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
// Target creature becomes red and gains haste until end of turn.
+ this.getSpellAbility().addEffect(new BecomesColorTargetEffect(
+ ObjectColor.RED, Duration.EndOfTurn
+ ).setText("target creature becomes red"));
+ this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains haste until end of turn"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new BecomesColorTargetEffect(ObjectColor.RED, Duration.EndOfTurn));
- this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
// Draw a card.
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
"));
}
- public CrimsonWisps (final CrimsonWisps card) {
+ public CrimsonWisps(final CrimsonWisps card) {
super(card);
}
@@ -40,6 +42,4 @@ public final class CrimsonWisps extends CardImpl {
public CrimsonWisps copy() {
return new CrimsonWisps(this);
}
-
}
-
diff --git a/Mage.Sets/src/mage/cards/c/Cromat.java b/Mage.Sets/src/mage/cards/c/Cromat.java
index ce52d89df43..dc49bb0e3e4 100644
--- a/Mage.Sets/src/mage/cards/c/Cromat.java
+++ b/Mage.Sets/src/mage/cards/c/Cromat.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -15,24 +13,30 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.SuperType;
-import mage.constants.Zone;
+import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.permanent.BlockedByIdPredicate;
-import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
-import mage.target.common.TargetCreaturePermanent;
+import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class Cromat extends CardImpl {
-
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creature blocking or blocked by {this}");
+
+ static {
+ filter.add(BlockingOrBlockedBySourcePredicate.EITHER);
+ }
+
public Cromat(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}{B}{R}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}{R}{G}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ILLUSION);
@@ -40,20 +44,31 @@ public final class Cromat extends CardImpl {
this.toughness = new MageInt(5);
// {W}{B}: Destroy target creature blocking or blocked by Cromat.
- FilterCreaturePermanent filter = new FilterCreaturePermanent("creature blocking or blocked by Cromat");
- filter.add(Predicates.or(new BlockedByIdPredicate(this.getId()),
- new BlockingAttackerIdPredicate(this.getId())));
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{W}{B}"));
- ability.addTarget(new TargetCreaturePermanent(filter));
+ Ability ability = new SimpleActivatedAbility(
+ new DestroyTargetEffect(), new ManaCostsImpl<>("{W}{B}")
+ );
+ ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
+
// {U}{R}: Cromat gains flying until end of turn.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{U}{R}")));
+ this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect(
+ FlyingAbility.getInstance(), Duration.EndOfTurn
+ ), new ManaCostsImpl<>("{U}{R}")));
+
// {B}{G}: Regenerate Cromat.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}{G}")));
+ this.addAbility(new SimpleActivatedAbility(
+ new RegenerateSourceEffect(), new ManaCostsImpl<>("{B}{G}")
+ ));
+
// {R}{W}: Cromat gets +1/+1 until end of turn.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1,1, Duration.EndOfTurn), new ManaCostsImpl("{R}{W}")));
+ this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(
+ 1, 1, Duration.EndOfTurn
+ ), new ManaCostsImpl<>("{R}{W}")));
+
// {G}{U}: Put Cromat on top of its owner's library.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibrarySourceEffect(true), new ManaCostsImpl("{G}{U}")));
+ this.addAbility(new SimpleActivatedAbility(
+ new PutOnLibrarySourceEffect(true), new ManaCostsImpl<>("{G}{U}")
+ ));
}
private Cromat(final Cromat card) {
diff --git a/Mage.Sets/src/mage/cards/c/CrookedCustodian.java b/Mage.Sets/src/mage/cards/c/CrookedCustodian.java
new file mode 100644
index 00000000000..fb4963065ef
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CrookedCustodian.java
@@ -0,0 +1,37 @@
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTappedAbility;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+
+/**
+ *
+ * @author weirddan455
+ */
+public final class CrookedCustodian extends CardImpl {
+
+ public CrookedCustodian(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
+
+ this.subtype.add(SubType.OGRE);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Crooked Custodian enters the battlefield tapped.
+ this.addAbility(new EntersBattlefieldTappedAbility());
+ }
+
+ private CrookedCustodian(final CrookedCustodian card) {
+ super(card);
+ }
+
+ @Override
+ public CrookedCustodian copy() {
+ return new CrookedCustodian(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CrosissCharm.java b/Mage.Sets/src/mage/cards/c/CrosissCharm.java
index ba0c61798fa..6b1f220a260 100644
--- a/Mage.Sets/src/mage/cards/c/CrosissCharm.java
+++ b/Mage.Sets/src/mage/cards/c/CrosissCharm.java
@@ -26,13 +26,11 @@ public final class CrosissCharm extends CardImpl {
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent());
// or destroy target nonblack creature, and it can't be regenerated;
- Mode mode = new Mode();
- mode.addEffect(new DestroyTargetEffect(true));
+ Mode mode = new Mode(new DestroyTargetEffect(true));
mode.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURE_NON_BLACK));
this.getSpellAbility().addMode(mode);
// or destroy target artifact.
- mode = new Mode();
- mode.addEffect(new DestroyTargetEffect());
+ mode = new Mode(new DestroyTargetEffect());
Target target = new TargetArtifactPermanent();
mode.addTarget(target);
this.getSpellAbility().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/c/CrownOfConvergence.java b/Mage.Sets/src/mage/cards/c/CrownOfConvergence.java
index c23faefedb9..d344968c4b6 100644
--- a/Mage.Sets/src/mage/cards/c/CrownOfConvergence.java
+++ b/Mage.Sets/src/mage/cards/c/CrownOfConvergence.java
@@ -75,7 +75,7 @@ class CrownOfConvergenceColorBoostEffect extends BoostAllEffect {
if (you != null) {
Card topCard = you.getLibrary().getFromTop(game);
if (topCard != null) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source, game)) {
if (permanent.getColor(game).shares(topCard.getColor(game)) && !permanent.getColor(game).isColorless()) {
permanent.addPower(power.calculate(game, source, this));
permanent.addToughness(toughness.calculate(game, source, this));
diff --git a/Mage.Sets/src/mage/cards/c/CrownOfDoom.java b/Mage.Sets/src/mage/cards/c/CrownOfDoom.java
index 5fcb5a82d9c..0d05fa45b1d 100644
--- a/Mage.Sets/src/mage/cards/c/CrownOfDoom.java
+++ b/Mage.Sets/src/mage/cards/c/CrownOfDoom.java
@@ -78,7 +78,7 @@ enum CrownOfDoomPredicate implements ObjectSourcePlayerPredicate {
@Override
public boolean apply(ObjectSourcePlayer input, Game game) {
Player targetPlayer = input.getObject();
- Permanent sourceObject = game.getPermanentOrLKIBattlefield(input.getSourceId());
+ Permanent sourceObject = input.getSource().getSourcePermanentOrLKI(game);
if (targetPlayer == null || sourceObject == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/CrownOfTheAges.java b/Mage.Sets/src/mage/cards/c/CrownOfTheAges.java
index 2dfd51581aa..2201e4b4702 100644
--- a/Mage.Sets/src/mage/cards/c/CrownOfTheAges.java
+++ b/Mage.Sets/src/mage/cards/c/CrownOfTheAges.java
@@ -91,8 +91,8 @@ class CrownOfTheAgesEffect extends OneShotEffect {
Target chosenCreatureToAttachAura = new TargetPermanent(filterChoice);
chosenCreatureToAttachAura.setNotTarget(true);
- if (chosenCreatureToAttachAura.canChoose(source.getSourceId(), source.getControllerId(), game)
- && controller.choose(Outcome.Neutral, chosenCreatureToAttachAura, source.getSourceId(), game)) {
+ if (chosenCreatureToAttachAura.canChoose(source.getControllerId(), source, game)
+ && controller.choose(Outcome.Neutral, chosenCreatureToAttachAura, source, game)) {
Permanent creatureToAttachAura = game.getPermanent(chosenCreatureToAttachAura.getFirstTarget());
if (creatureToAttachAura != null) {
if (passed) {
diff --git a/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java b/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java
index ea8181859f4..9d089af6268 100644
--- a/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java
+++ b/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java
@@ -89,7 +89,7 @@ class CrucibleOfTheSpiritDragonManaCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- MageObject object = game.getObject(source.getSourceId());
+ MageObject object = game.getObject(source);
if (object != null && object.hasSubtype(SubType.DRAGON, game)) {
return true;
}
diff --git a/Mage.Sets/src/mage/cards/c/CrudeRampart.java b/Mage.Sets/src/mage/cards/c/CrudeRampart.java
index 155f1176142..31fc79d5f8f 100644
--- a/Mage.Sets/src/mage/cards/c/CrudeRampart.java
+++ b/Mage.Sets/src/mage/cards/c/CrudeRampart.java
@@ -26,7 +26,7 @@ public final class CrudeRampart extends CardImpl {
// Defender
this.addAbility(DefenderAbility.getInstance());
// Morph {4}{W}
- this.addAbility(new MorphAbility(this, new ManaCostsImpl("{4}{W}")));
+ this.addAbility(new MorphAbility(new ManaCostsImpl("{4}{W}")));
}
private CrudeRampart(final CrudeRampart card) {
diff --git a/Mage.Sets/src/mage/cards/c/CruelFate.java b/Mage.Sets/src/mage/cards/c/CruelFate.java
index b76e2edb42e..6c5a44dbaa6 100644
--- a/Mage.Sets/src/mage/cards/c/CruelFate.java
+++ b/Mage.Sets/src/mage/cards/c/CruelFate.java
@@ -40,7 +40,7 @@ public final class CruelFate extends CardImpl {
class CruelFateEffect extends OneShotEffect {
CruelFateEffect() {
- super(Outcome.DrawCard);
+ super(Outcome.Detriment);
this.staticText = "Look at the top five cards of target opponent's library. " +
"Put one of those cards into that player's graveyard and the rest on top of their library in any order";
}
@@ -75,6 +75,6 @@ class CruelFateEffect extends OneShotEffect {
controller.moveCards(card, Zone.GRAVEYARD, source, game);
cards.remove(card);
}
- return controller.putCardsOnTopOfLibrary(card, game, source, true);
+ return controller.putCardsOnTopOfLibrary(cards, game, source, true);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CruelReality.java b/Mage.Sets/src/mage/cards/c/CruelReality.java
index e3249e40188..b80779dbeaf 100644
--- a/Mage.Sets/src/mage/cards/c/CruelReality.java
+++ b/Mage.Sets/src/mage/cards/c/CruelReality.java
@@ -86,8 +86,8 @@ class CruelRealityEffect extends OneShotEffect {
}
TargetPermanent target = new TargetPermanent(filter);
target.setNotTarget(true);
- if (target.canChoose(source.getSourceId(), cursedPlayer.getId(), game)
- && cursedPlayer.choose(Outcome.Sacrifice, target, source.getId(), game)) {
+ if (target.canChoose(cursedPlayer.getId(), source, game)
+ && cursedPlayer.choose(Outcome.Sacrifice, target, source, game)) {
Permanent objectToBeSacrificed = game.getPermanent(target.getFirstTarget());
if (objectToBeSacrificed != null) {
if (objectToBeSacrificed.sacrifice(source, game)) {
diff --git a/Mage.Sets/src/mage/cards/c/CruelUltimatum.java b/Mage.Sets/src/mage/cards/c/CruelUltimatum.java
index 56c45460de6..6abad936cb2 100644
--- a/Mage.Sets/src/mage/cards/c/CruelUltimatum.java
+++ b/Mage.Sets/src/mage/cards/c/CruelUltimatum.java
@@ -2,8 +2,6 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.DrawCardSourceControllerEffect;
-import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
@@ -32,13 +30,13 @@ public final class CruelUltimatum extends CardImpl {
// Target opponent sacrifices a creature, discards three cards, then loses 5 life.
// You return a creature card from your graveyard to your hand, draw three cards, then gain 5 life.
this.getSpellAbility().addTarget(new TargetOpponent());
- this.getSpellAbility().addEffect(new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "Target opponent"));
- this.getSpellAbility().addEffect(new DiscardTargetEffect(3));
- this.getSpellAbility().addEffect(new LoseLifeTargetEffect(5));
-
+ this.getSpellAbility().addEffect(new SacrificeEffect(
+ StaticFilters.FILTER_PERMANENT_CREATURE,
+ 1, "Target opponent"
+ ));
+ this.getSpellAbility().addEffect(new DiscardTargetEffect(3).setText(", discards three cards"));
+ this.getSpellAbility().addEffect(new LoseLifeTargetEffect(5).setText(", then loses 5 life"));
this.getSpellAbility().addEffect(new CruelUltimatumEffect());
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3));
- this.getSpellAbility().addEffect(new GainLifeEffect(5));
}
private CruelUltimatum(final CruelUltimatum card) {
@@ -55,7 +53,8 @@ class CruelUltimatumEffect extends OneShotEffect {
public CruelUltimatumEffect() {
super(Outcome.ReturnToHand);
- this.staticText = "Return a creature card from your graveyard to your hand";
+ this.staticText = "You return a creature card from your graveyard " +
+ "to your hand, draw three cards, then gain 5 life";
}
public CruelUltimatumEffect(final CruelUltimatumEffect effect) {
@@ -74,14 +73,13 @@ class CruelUltimatumEffect extends OneShotEffect {
return false;
}
TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD);
- if (target.canChoose(source.getSourceId(), source.getControllerId(), game) && controller.choose(Outcome.ReturnToHand, target, source.getSourceId(), game)) {
- Card card = game.getCard(target.getFirstTarget());
- if (card == null) {
- return false;
- }
-
+ controller.choose(Outcome.ReturnToHand, target, source, game);
+ Card card = game.getCard(target.getFirstTarget());
+ if (card != null) {
return controller.moveCards(card, Zone.HAND, source, game);
}
+ controller.drawCards(1, source, game);
+ controller.gainLife(1, game, source);
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CrueltyOfTheSith.java b/Mage.Sets/src/mage/cards/c/CrueltyOfTheSith.java
index 458c9acd38d..59655b30359 100644
--- a/Mage.Sets/src/mage/cards/c/CrueltyOfTheSith.java
+++ b/Mage.Sets/src/mage/cards/c/CrueltyOfTheSith.java
@@ -28,14 +28,12 @@ public final class CrueltyOfTheSith extends CardImpl {
this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_NON_CREATURE));
// Target player sacrifices a creture.
- Mode mode = new Mode();
- mode.addEffect(new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "Target player"));
+ Mode mode = new Mode(new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "Target player"));
mode.addTarget(new TargetPlayer());
this.getSpellAbility().addMode(mode);
// Cruelty of the Sith deals 3 damage to target player. That player discards a card.
- mode = new Mode();
- mode.addEffect(new DamageTargetEffect(3));
+ mode = new Mode(new DamageTargetEffect(3));
mode.addEffect(new DiscardTargetEffect(1));
mode.addTarget(new TargetPlayer());
this.getSpellAbility().addMode(mode);
diff --git a/Mage.Sets/src/mage/cards/c/CrushContraband.java b/Mage.Sets/src/mage/cards/c/CrushContraband.java
index 6cbb1125974..9ae9cf09ec5 100644
--- a/Mage.Sets/src/mage/cards/c/CrushContraband.java
+++ b/Mage.Sets/src/mage/cards/c/CrushContraband.java
@@ -26,8 +26,7 @@ public final class CrushContraband extends CardImpl {
this.getSpellAbility().addEffect(new ExileTargetEffect());
this.getSpellAbility().addTarget(new TargetArtifactPermanent().withChooseHint("destroy"));
- Mode mode1 = new Mode();
- mode1.addEffect(new ExileTargetEffect());
+ Mode mode1 = new Mode(new ExileTargetEffect());
mode1.addTarget(new TargetEnchantmentPermanent().withChooseHint("destroy"));
this.getSpellAbility().addMode(mode1);
}
diff --git a/Mage.Sets/src/mage/cards/c/CrushUnderfoot.java b/Mage.Sets/src/mage/cards/c/CrushUnderfoot.java
index 0b2ceda2144..6ddb8c5ce71 100644
--- a/Mage.Sets/src/mage/cards/c/CrushUnderfoot.java
+++ b/Mage.Sets/src/mage/cards/c/CrushUnderfoot.java
@@ -72,7 +72,7 @@ class CrushUnderfootEffect extends OneShotEffect {
if (controller != null) {
// Choose a Giant creature you control (not targeted, happens during effect resolving )
Target target = new TargetControlledCreaturePermanent(1,1, filter,false);
- if (target.canChoose(source.getSourceId(), controller.getId(), game)
+ if (target.canChoose(controller.getId(), source, game)
&& controller.chooseTarget(outcome, target, source, game)) {
Permanent giant = game.getPermanent(target.getFirstTarget());
if (giant != null) {
diff --git a/Mage.Sets/src/mage/cards/c/CrushingCanopy.java b/Mage.Sets/src/mage/cards/c/CrushingCanopy.java
index 73303ad3a95..e55610d8772 100644
--- a/Mage.Sets/src/mage/cards/c/CrushingCanopy.java
+++ b/Mage.Sets/src/mage/cards/c/CrushingCanopy.java
@@ -33,9 +33,8 @@ public final class CrushingCanopy extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
this.getSpellAbility().addEffect(new DestroyTargetEffect());
// * Destroy target enchantment.
- Mode mode = new Mode();
+ Mode mode = new Mode(new DestroyTargetEffect());
mode.addTarget(new TargetEnchantmentPermanent());
- mode.addEffect(new DestroyTargetEffect());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/CrushingVines.java b/Mage.Sets/src/mage/cards/c/CrushingVines.java
index 97330fd2a5c..4492a1c88cb 100644
--- a/Mage.Sets/src/mage/cards/c/CrushingVines.java
+++ b/Mage.Sets/src/mage/cards/c/CrushingVines.java
@@ -32,9 +32,8 @@ public final class CrushingVines extends CardImpl {
// Choose one - Destroy target creature with flying; or destroy target artifact.
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
this.getSpellAbility().addEffect(new DestroyTargetEffect());
- Mode mode = new Mode();
+ Mode mode = new Mode(new DestroyTargetEffect());
mode.addTarget(new TargetArtifactPermanent());
- mode.addEffect(new DestroyTargetEffect());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/CruxOfFate.java b/Mage.Sets/src/mage/cards/c/CruxOfFate.java
index 29766422e8b..8b6b22051cb 100644
--- a/Mage.Sets/src/mage/cards/c/CruxOfFate.java
+++ b/Mage.Sets/src/mage/cards/c/CruxOfFate.java
@@ -30,8 +30,7 @@ public final class CruxOfFate extends CardImpl {
// * Destroy all Dragon creatures.
this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterCreaturePermanent(SubType.DRAGON, "Dragon creatures")));
// * Destroy all non-Dragon creatures.
- Mode mode = new Mode();
- mode.addEffect(new DestroyAllEffect(new FilterCreaturePermanent(filterNonDragon)));
+ Mode mode = new Mode(new DestroyAllEffect(new FilterCreaturePermanent(filterNonDragon)));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java b/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java
index ba9584e3488..0079b741b7d 100644
--- a/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java
+++ b/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java
@@ -64,15 +64,14 @@ class CryOfTheCarnariumExileEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
+ Player controller = game.getPlayer(source.getControllerId());
CardsPutIntoGraveyardWatcher watcher = game.getState().getWatcher(CardsPutIntoGraveyardWatcher.class);
- if (player == null || watcher == null) {
- return false;
- }
- Cards cards = new CardsImpl(watcher.getCardsPutToGraveyardFromBattlefield(game));
+ if (controller == null || watcher == null) { return false; }
+
+ Cards cards = new CardsImpl(watcher.getCardsPutIntoGraveyardFromBattlefield(game));
cards.removeIf(uuid -> !game.getCard(uuid).isCreature(game));
- player.moveCards(cards, Zone.EXILED, source, game);
- return true;
+
+ return controller.moveCards(cards, Zone.EXILED, source, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/Crypsis.java b/Mage.Sets/src/mage/cards/c/Crypsis.java
index 1046b126a47..16d69bb17fa 100644
--- a/Mage.Sets/src/mage/cards/c/Crypsis.java
+++ b/Mage.Sets/src/mage/cards/c/Crypsis.java
@@ -8,8 +8,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.TargetController;
-import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
@@ -19,23 +18,15 @@ import java.util.UUID;
*/
public final class Crypsis extends CardImpl {
- static final FilterPermanent filter = new FilterPermanent("creatures your opponents control");
-
- static {
- filter.add(CardType.CREATURE.getPredicate());
- filter.add(TargetController.OPPONENT.getControllerPredicate());
- }
-
public Crypsis(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Target creature you control gains protection from creatures your opponents control until end of turn. Untap it.
- this.getSpellAbility().addEffect(new GainAbilityTargetEffect(new ProtectionAbility(filter), Duration.EndOfTurn));
- Effect effect = new UntapTargetEffect();
- effect.setText("Untap it.");
- this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
+ new ProtectionAbility(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES),
+ Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new UntapTargetEffect("untap it"));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
-
}
private Crypsis(final Crypsis card) {
diff --git a/Mage.Sets/src/mage/cards/c/CryptAngel.java b/Mage.Sets/src/mage/cards/c/CryptAngel.java
index b975fcec681..03c8c823a6a 100644
--- a/Mage.Sets/src/mage/cards/c/CryptAngel.java
+++ b/Mage.Sets/src/mage/cards/c/CryptAngel.java
@@ -1,12 +1,10 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
@@ -18,8 +16,9 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author LoneFox
*/
public final class CryptAngel extends CardImpl {
@@ -27,21 +26,26 @@ public final class CryptAngel extends CardImpl {
private static final FilterCreatureCard filter2 = new FilterCreatureCard("blue or red creature card from your graveyard");
static {
- filter2.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.BLUE)));
+ filter2.add(Predicates.or(
+ new ColorPredicate(ObjectColor.RED),
+ new ColorPredicate(ObjectColor.BLUE)
+ ));
}
public CryptAngel(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.ANGEL);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
+
// protection from white
this.addAbility(ProtectionAbility.from(ObjectColor.WHITE));
+
// When Crypt Angel enters the battlefield, return target blue or red creature card from your graveyard to your hand.
- Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false);
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false);
ability.addTarget(new TargetCardInYourGraveyard(filter2));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/c/CryptChampion.java b/Mage.Sets/src/mage/cards/c/CryptChampion.java
index fbf59417c09..1b30f26a4c2 100644
--- a/Mage.Sets/src/mage/cards/c/CryptChampion.java
+++ b/Mage.Sets/src/mage/cards/c/CryptChampion.java
@@ -89,7 +89,7 @@ class CryptChampionEffect extends OneShotEffect {
filter.add(new OwnerIdPredicate(playerId));
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4));
Target target = new TargetCardInGraveyard(filter);
- if (target.canChoose(source.getSourceId(), playerId, game)
+ if (target.canChoose(playerId, source, game)
&& player.chooseTarget(outcome, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/c/CryptLurker.java b/Mage.Sets/src/mage/cards/c/CryptLurker.java
index 153d25dbef3..903b417678a 100644
--- a/Mage.Sets/src/mage/cards/c/CryptLurker.java
+++ b/Mage.Sets/src/mage/cards/c/CryptLurker.java
@@ -33,10 +33,9 @@ public final class CryptLurker extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(
new DrawCardSourceControllerEffect(1),
new OrCost(
- new SacrificeTargetCost(new TargetControlledPermanent(
+ "sacrifice a creature or discard a creature card", new SacrificeTargetCost(new TargetControlledPermanent(
StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT
- )), new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)),
- "sacrifice a creature or discard a creature card"
+ )), new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A))
)
)));
}
diff --git a/Mage.Sets/src/mage/cards/c/CryptSliver.java b/Mage.Sets/src/mage/cards/c/CryptSliver.java
index 2fc6d710326..f7f025a6906 100644
--- a/Mage.Sets/src/mage/cards/c/CryptSliver.java
+++ b/Mage.Sets/src/mage/cards/c/CryptSliver.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -15,8 +14,10 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
+import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
+import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -25,6 +26,7 @@ import mage.target.common.TargetCreaturePermanent;
*/
public final class CryptSliver extends CardImpl {
+ private static final FilterPermanent filter=new FilterPermanent(SubType.SLIVER,"Sliver");
public CryptSliver(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.SLIVER);
@@ -33,9 +35,11 @@ public final class CryptSliver extends CardImpl {
this.toughness = new MageInt(1);
// All Slivers have "{tap}: Regenerate target Sliver."
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new TapSourceCost());
- ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent(SubType.SLIVER, "Sliver")));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS)));
+ Ability ability = new SimpleActivatedAbility( new RegenerateTargetEffect(), new TapSourceCost());
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(new SimpleStaticAbility( new GainAbilityAllEffect(
+ ability, Duration.WhileOnBattlefield, filter
+ ).setText("all Slivers have \"{T}: Regenerate target Sliver.\"")));
}
private CryptSliver(final CryptSliver card) {
diff --git a/Mage.Sets/src/mage/cards/c/CrypticCommand.java b/Mage.Sets/src/mage/cards/c/CrypticCommand.java
index ba26fac0186..c5f614dd13a 100644
--- a/Mage.Sets/src/mage/cards/c/CrypticCommand.java
+++ b/Mage.Sets/src/mage/cards/c/CrypticCommand.java
@@ -1,21 +1,15 @@
package mage.cards.c;
import java.util.UUID;
-import mage.abilities.Ability;
import mage.abilities.Mode;
-import mage.abilities.effects.Effect;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.TapAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.filter.StaticFilters;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.TargetSpell;
@@ -31,27 +25,22 @@ public final class CrypticCommand extends CardImpl {
// Choose two -
this.getSpellAbility().getModes().setMinModes(2);
this.getSpellAbility().getModes().setMaxModes(2);
+
// Counter target spell;
- Effect effect1 = new CounterTargetEffect();
- effect1.setText("Counter target spell.");
- this.getSpellAbility().addEffect(effect1);
+ this.getSpellAbility().addEffect(new CounterTargetEffect());
this.getSpellAbility().addTarget(new TargetSpell());
+
// or return target permanent to its owner's hand;
- Mode mode = new Mode();
- Effect effect2 = new ReturnToHandTargetEffect();
- effect2.setText("Return target permanent to its owner's hand.");
- mode.addEffect(effect2);
+ Mode mode = new Mode(new ReturnToHandTargetEffect());
mode.addTarget(new TargetPermanent());
this.getSpellAbility().getModes().addMode(mode);
+
// or tap all creatures your opponents control;
- mode = new Mode();
- mode.addEffect(new CrypticCommandEffect());
+ mode = new Mode(new TapAllEffect(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES));
this.getSpellAbility().getModes().addMode(mode);
+
// or draw a card.
- mode = new Mode();
- Effect effect3 = new DrawCardSourceControllerEffect(1);
- mode.addEffect(effect3);
- effect3.setText("Draw a card.");
+ mode = new Mode(new DrawCardSourceControllerEffect(1));
this.getSpellAbility().getModes().addMode(mode);
}
@@ -64,32 +53,3 @@ public final class CrypticCommand extends CardImpl {
return new CrypticCommand(this);
}
}
-
-class CrypticCommandEffect extends OneShotEffect {
-
- public CrypticCommandEffect() {
- super(Outcome.Tap);
- staticText = "Tap all creatures your opponents control";
- }
-
- public CrypticCommandEffect(final CrypticCommandEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
- if (player == null) {
- return false;
- }
- for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE, player.getId(), source.getSourceId(), game)) {
- creature.tap(source, game);
- }
- return true;
- }
-
- @Override
- public CrypticCommandEffect copy() {
- return new CrypticCommandEffect(this);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/c/CrypticGateway.java b/Mage.Sets/src/mage/cards/c/CrypticGateway.java
index 28396688e11..68db417fc4e 100644
--- a/Mage.Sets/src/mage/cards/c/CrypticGateway.java
+++ b/Mage.Sets/src/mage/cards/c/CrypticGateway.java
@@ -1,31 +1,29 @@
package mage.cards.c;
+import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.CostImpl;
+import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.filter.FilterCard;
-import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
-import mage.filter.predicate.Predicate;
-import mage.filter.predicate.permanent.TappedPredicate;
+import mage.filter.predicate.mageobject.SharesCreatureTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledPermanent;
+import mage.util.CardUtil;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.List;
+import java.util.stream.Collectors;
import java.util.UUID;
/**
- * @author spjspj
+ * @author awjackson
*/
public final class CrypticGateway extends CardImpl {
@@ -33,7 +31,9 @@ public final class CrypticGateway extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
// Tap two untapped creatures you control: You may put a creature card from your hand that shares a creature type with each creature tapped this way onto the battlefield.
- this.addAbility(new SimpleActivatedAbility(new CrypticGatewayEffect(), new CrypticGatewayCost()));
+ this.addAbility(new SimpleActivatedAbility(new CrypticGatewayEffect(), new TapTargetCost(
+ new TargetControlledPermanent(2, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES)
+ )));
}
private CrypticGateway(final CrypticGateway card) {
@@ -46,70 +46,11 @@ public final class CrypticGateway extends CardImpl {
}
}
-class CrypticGatewayCost extends CostImpl {
-
- private static final FilterControlledCreaturePermanent filter
- = new FilterControlledCreaturePermanent("untapped creatures you control");
-
- static {
- filter.add(TappedPredicate.UNTAPPED);
- }
-
- private final TargetControlledPermanent target = new TargetControlledPermanent(2, filter);
- private CrypticGatewayPredicate predicate;
-
- public CrypticGatewayCost() {
- this.text = "Tap two untapped creatures you control";
- }
-
- public CrypticGatewayCost(final CrypticGatewayCost cost) {
- super(cost);
- }
-
- @Override
- public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
- int numTargets = 0;
- Set permanents = new HashSet<>();
- while (numTargets < 2 && target.choose(Outcome.Tap, controllerId, source.getSourceId(), game)) {
- for (UUID targetId : target.getTargets()) {
- Permanent permanent = game.getPermanent(targetId);
- if (permanent == null) {
- return false;
- }
- paid |= permanent.tap(source, game);
- if (paid) {
- numTargets++;
- target.clearChosen();
- permanents.add(permanent);
- }
- }
- }
- if (paid) {
- this.predicate = new CrypticGatewayPredicate(permanents);
- }
- return paid;
- }
-
- @Override
- public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return target.canChoose(source.getSourceId(), controllerId, game);
- }
-
- public CrypticGatewayPredicate getPredicate() {
- return predicate;
- }
-
- @Override
- public CrypticGatewayCost copy() {
- return new CrypticGatewayCost(this);
- }
-}
-
class CrypticGatewayEffect extends OneShotEffect {
public CrypticGatewayEffect() {
super(Outcome.PutCreatureInPlay);
- this.staticText = "Put a creature card from your hand that shares a creature type with each creature tapped this way onto the battlefield";
+ this.staticText = "you may put a creature card from your hand that shares a creature type with each creature tapped this way onto the battlefield";
}
public CrypticGatewayEffect(final CrypticGatewayEffect effect) {
@@ -123,36 +64,16 @@ class CrypticGatewayEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- if (source.getCosts() == null) {
+ List tapped = (List) getValue("tappedPermanents");
+ if (tapped == null || tapped.isEmpty()) {
return false;
}
- FilterCard filter = new FilterCreatureCard("creature card from your hand that shares a creature type with each creature tapped this way");
- for (Cost cost : source.getCosts()) {
- if (cost instanceof CrypticGatewayCost) {
- Predicate predicate = ((CrypticGatewayCost) cost).getPredicate();
- filter.add(predicate);
- return new PutCardFromHandOntoBattlefieldEffect(filter).apply(game, source);
- }
+ FilterCreatureCard filter = new FilterCreatureCard("creature card that shares a creature type with "
+ + CardUtil.concatWithAnd(tapped.stream().map(MageObject::getName).collect(Collectors.toList()))
+ );
+ for (Permanent perm : tapped) {
+ filter.add(new SharesCreatureTypePredicate(perm));
}
- return false;
- }
-}
-
-class CrypticGatewayPredicate implements Predicate {
-
- private final Set permanents = new HashSet<>();
-
- CrypticGatewayPredicate(Set