forked from External/mage
Merge branch 'External-master'
All checks were successful
/ build_release (push) Successful in 27m57s
All checks were successful
/ build_release (push) Successful in 27m57s
This commit is contained in:
commit
d2c32ec53f
435 changed files with 12052 additions and 2085 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-client</artifactId>
|
<artifactId>mage-client</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -2626,19 +2626,19 @@
|
||||||
<Component class="javax.swing.JCheckBox" name="cbStopBlockWithAny">
|
<Component class="javax.swing.JCheckBox" name="cbStopBlockWithAny">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="selected" type="boolean" value="true"/>
|
<Property name="selected" type="boolean" value="true"/>
|
||||||
<Property name="text" type="java.lang.String" value="STOP skips on declare blockers if ANY blockers are available"/>
|
<Property name="text" type="java.lang.String" value="STOP skips when attacked and on declare blockers if ANY blockers are available"/>
|
||||||
<Property name="actionCommand" type="java.lang.String" value=""/>
|
<Property name="actionCommand" type="java.lang.String" value=""/>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JCheckBox" name="cbStopBlockWithZero">
|
<Component class="javax.swing.JCheckBox" name="cbStopBlockWithZero">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" value="STOP skips on declare blockers if ZERO blockers are available"/>
|
<Property name="text" type="java.lang.String" value="STOP skips when attacked if ZERO blockers are available"/>
|
||||||
<Property name="actionCommand" type="java.lang.String" value=""/>
|
<Property name="actionCommand" type="java.lang.String" value=""/>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JCheckBox" name="cbStopOnNewStackObjects">
|
<Component class="javax.swing.JCheckBox" name="cbStopOnNewStackObjects">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" value="Skip to STACK resolved (F10): stop on new objects added (on) or stop until empty (off)"/>
|
<Property name="text" type="java.lang.String" value="Skip to STACK resolved (F10): stop on new objects added (on) or stop when stack empty (off)"/>
|
||||||
<Property name="actionCommand" type="java.lang.String" value=""/>
|
<Property name="actionCommand" type="java.lang.String" value=""/>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[300, 25]"/>
|
<Dimension value="[300, 25]"/>
|
||||||
|
|
|
||||||
|
|
@ -2403,15 +2403,15 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
||||||
phases_stopSettings.add(cbStopAttack);
|
phases_stopSettings.add(cbStopAttack);
|
||||||
|
|
||||||
cbStopBlockWithAny.setSelected(true);
|
cbStopBlockWithAny.setSelected(true);
|
||||||
cbStopBlockWithAny.setText("STOP skips on declare blockers if ANY blockers are available");
|
cbStopBlockWithAny.setText("STOP skips when attacked and on declare blockers if ANY blockers are available");
|
||||||
cbStopBlockWithAny.setActionCommand("");
|
cbStopBlockWithAny.setActionCommand("");
|
||||||
phases_stopSettings.add(cbStopBlockWithAny);
|
phases_stopSettings.add(cbStopBlockWithAny);
|
||||||
|
|
||||||
cbStopBlockWithZero.setText("STOP skips on declare blockers if ZERO blockers are available");
|
cbStopBlockWithZero.setText("STOP skips when attacked if ZERO blockers are available");
|
||||||
cbStopBlockWithZero.setActionCommand("");
|
cbStopBlockWithZero.setActionCommand("");
|
||||||
phases_stopSettings.add(cbStopBlockWithZero);
|
phases_stopSettings.add(cbStopBlockWithZero);
|
||||||
|
|
||||||
cbStopOnNewStackObjects.setText("Skip to STACK resolved (F10): stop on new objects added (on) or stop until empty (off)");
|
cbStopOnNewStackObjects.setText("Skip to STACK resolved (F10): stop on new objects added (on) or stop when stack empty (off)");
|
||||||
cbStopOnNewStackObjects.setActionCommand("");
|
cbStopOnNewStackObjects.setActionCommand("");
|
||||||
cbStopOnNewStackObjects.setPreferredSize(new java.awt.Dimension(300, 25));
|
cbStopOnNewStackObjects.setPreferredSize(new java.awt.Dimension(300, 25));
|
||||||
phases_stopSettings.add(cbStopOnNewStackObjects);
|
phases_stopSettings.add(cbStopOnNewStackObjects);
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
public static final Color ERROR_COLOR = new Color(255, 0, 255);
|
public static final Color ERROR_COLOR = new Color(255, 0, 255);
|
||||||
|
|
||||||
static String SUB_TYPE_ADVENTURE = "Adventure";
|
static String SUB_TYPE_ADVENTURE = "Adventure";
|
||||||
|
static String SUB_TYPE_OMEN = "Omen";
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Layout metrics for modern border cards
|
// Layout metrics for modern border cards
|
||||||
|
|
@ -168,8 +169,8 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
// Processed mana cost string
|
// Processed mana cost string
|
||||||
protected String manaCostString;
|
protected String manaCostString;
|
||||||
|
|
||||||
// Is an adventure
|
// Is an adventure or omen
|
||||||
protected boolean isAdventure = false;
|
protected boolean isCardWithSpellOption = false;
|
||||||
|
|
||||||
public ModernCardRenderer(CardView card) {
|
public ModernCardRenderer(CardView card) {
|
||||||
// Pass off to parent
|
// Pass off to parent
|
||||||
|
|
@ -179,12 +180,13 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
manaCostString = ManaSymbols.getClearManaCost(cardView.getManaCostStr());
|
manaCostString = ManaSymbols.getClearManaCost(cardView.getManaCostStr());
|
||||||
|
|
||||||
if (cardView.isSplitCard()) {
|
if (cardView.isSplitCard()) {
|
||||||
isAdventure = cardView.getRightSplitTypeLine().contains(SUB_TYPE_ADVENTURE);
|
isCardWithSpellOption = cardView.getRightSplitTypeLine().contains(SUB_TYPE_ADVENTURE)
|
||||||
|
|| cardView.getRightSplitTypeLine().contains(SUB_TYPE_OMEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isAdventure() {
|
protected boolean isCardWithSpellOption() {
|
||||||
return isAdventure;
|
return isCardWithSpellOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -660,7 +662,7 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
drawRulesText(g, textboxKeywords, textboxRules,
|
drawRulesText(g, textboxKeywords, textboxRules,
|
||||||
contentWidth / 2 + totalContentInset + 4, totalContentInset + boxHeight + 2,
|
contentWidth / 2 + totalContentInset + 4, totalContentInset + boxHeight + 2,
|
||||||
contentWidth / 2 - 8, typeLineY - totalContentInset - boxHeight - 6, false);
|
contentWidth / 2 - 8, typeLineY - totalContentInset - boxHeight - 6, false);
|
||||||
} else if (isAdventure) {
|
} else if (isCardWithSpellOption) {
|
||||||
drawRulesText(g, textboxKeywords, textboxRules,
|
drawRulesText(g, textboxKeywords, textboxRules,
|
||||||
contentWidth / 2 + totalContentInset + 4, typeLineY + boxHeight + 2,
|
contentWidth / 2 + totalContentInset + 4, typeLineY + boxHeight + 2,
|
||||||
contentWidth / 2 - 8, cardHeight - typeLineY - boxHeight - 4 - borderWidth * 3, false);
|
contentWidth / 2 - 8, cardHeight - typeLineY - boxHeight - 4 - borderWidth * 3, false);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
||||||
private boolean isAftermath = false;
|
private boolean isAftermath = false;
|
||||||
|
|
||||||
private static String trimAdventure(String rule) {
|
private static String trimAdventure(String rule) {
|
||||||
if (rule.startsWith("Adventure")) {
|
if (rule.startsWith("Adventure") || rule.startsWith("Omen")) {
|
||||||
return rule.substring(rule.lastIndexOf("—") + 8);
|
return rule.substring(rule.lastIndexOf("—") + 8);
|
||||||
}
|
}
|
||||||
return rule;
|
return rule;
|
||||||
|
|
@ -71,7 +71,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
||||||
rightHalf.color = new ObjectColor(cardView.getRightSplitCostsStr());
|
rightHalf.color = new ObjectColor(cardView.getRightSplitCostsStr());
|
||||||
leftHalf.color = new ObjectColor(cardView.getLeftSplitCostsStr());
|
leftHalf.color = new ObjectColor(cardView.getLeftSplitCostsStr());
|
||||||
|
|
||||||
if (isAdventure()) {
|
if (isCardWithSpellOption()) {
|
||||||
List<String> trimmedRules = new ArrayList<>();
|
List<String> trimmedRules = new ArrayList<>();
|
||||||
for (String rule : view.getRightSplitRules()) {
|
for (String rule : view.getRightSplitRules()) {
|
||||||
trimmedRules.add(trimAdventure(rule));
|
trimmedRules.add(trimAdventure(rule));
|
||||||
|
|
@ -95,7 +95,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
||||||
// they "rotate" in opposite directions making consquence and normal split cards
|
// they "rotate" in opposite directions making consquence and normal split cards
|
||||||
// have the "right" vs "left" as the top half.
|
// have the "right" vs "left" as the top half.
|
||||||
// Adventures are treated differently and not rotated at all.
|
// Adventures are treated differently and not rotated at all.
|
||||||
if (isAdventure()) {
|
if (isCardWithSpellOption()) {
|
||||||
manaCostString = leftHalf.manaCostString;
|
manaCostString = leftHalf.manaCostString;
|
||||||
textboxKeywords = leftHalf.keywords;
|
textboxKeywords = leftHalf.keywords;
|
||||||
textboxRules = leftHalf.rules;
|
textboxRules = leftHalf.rules;
|
||||||
|
|
@ -159,7 +159,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
||||||
protected void drawBackground(Graphics2D g) {
|
protected void drawBackground(Graphics2D g) {
|
||||||
if (cardView.isFaceDown()) {
|
if (cardView.isFaceDown()) {
|
||||||
drawCardBackTexture(g);
|
drawCardBackTexture(g);
|
||||||
} if (isAdventure()) {
|
} if (isCardWithSpellOption()) {
|
||||||
super.drawBackground(g);
|
super.drawBackground(g);
|
||||||
} else {
|
} else {
|
||||||
{ // Left half background (top of the card)
|
{ // Left half background (top of the card)
|
||||||
|
|
@ -204,7 +204,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawArt(Graphics2D g) {
|
protected void drawArt(Graphics2D g) {
|
||||||
if (isAdventure) {
|
if (isCardWithSpellOption) {
|
||||||
super.drawArt(g);
|
super.drawArt(g);
|
||||||
} else if (artImage != null) {
|
} else if (artImage != null) {
|
||||||
if (isAftermath()) {
|
if (isAftermath()) {
|
||||||
|
|
@ -318,7 +318,7 @@ public class ModernSplitCardRenderer extends ModernCardRenderer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawFrame(Graphics2D g, CardPanelAttributes attribs, BufferedImage image, boolean lessOpaqueRulesTextBox) {
|
protected void drawFrame(Graphics2D g, CardPanelAttributes attribs, BufferedImage image, boolean lessOpaqueRulesTextBox) {
|
||||||
if (isAdventure()) {
|
if (isCardWithSpellOption()) {
|
||||||
super.drawFrame(g, attribs, image, lessOpaqueRulesTextBox);
|
super.drawFrame(g, attribs, image, lessOpaqueRulesTextBox);
|
||||||
|
|
||||||
CardPanelAttributes adventureAttribs = new CardPanelAttributes(
|
CardPanelAttributes adventureAttribs = new CardPanelAttributes(
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public class ScryfallApiCard {
|
||||||
this.card_faces.forEach(ScryfallApiCardFace::prepareCompatibleData);
|
this.card_faces.forEach(ScryfallApiCardFace::prepareCompatibleData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// workaround for adventure card name fix:
|
// workaround for adventure/omen card name fix:
|
||||||
// - scryfall: Ondu Knotmaster // Throw a Line
|
// - scryfall: Ondu Knotmaster // Throw a Line
|
||||||
// - xmage: Ondu Knotmaster
|
// - xmage: Ondu Knotmaster
|
||||||
if (this.layout.equals("adventure")) {
|
if (this.layout.equals("adventure")) {
|
||||||
|
|
@ -100,12 +100,12 @@ public class ScryfallApiCard {
|
||||||
}
|
}
|
||||||
this.name = this.card_faces.get(0).name;
|
this.name = this.card_faces.get(0).name;
|
||||||
} else if (this.card_faces.get(0).layout.equals("adventure")) {
|
} else if (this.card_faces.get(0).layout.equals("adventure")) {
|
||||||
// adventure card
|
// adventure/omen card
|
||||||
// Bloomvine Regent // Claim Territory
|
// Bloomvine Regent // Claim Territory
|
||||||
// https://scryfall.com/card/tdm/381/bloomvine-regent-claim-territory-bloomvine-regent
|
// https://scryfall.com/card/tdm/381/bloomvine-regent-claim-territory-bloomvine-regent
|
||||||
this.name = this.card_faces.get(0).name;
|
this.name = this.card_faces.get(0).name;
|
||||||
if (this.card_faces.get(0).name.equals(this.card_faces.get(1).name)) {
|
if (this.card_faces.get(0).name.equals(this.card_faces.get(1).name)) {
|
||||||
throw new IllegalArgumentException("Scryfall: unsupported data type, adventure's reversible_card must have diff names in faces "
|
throw new IllegalArgumentException("Scryfall: unsupported data type, adventure/omen's reversible_card must have diff names in faces "
|
||||||
+ this.set + " - " + this.collector_number + " - " + this.name);
|
+ this.set + " - " + this.collector_number + " - " + this.name);
|
||||||
}
|
}
|
||||||
} else if (this.card_faces.get(0).layout.equals("token")) {
|
} else if (this.card_faces.get(0).layout.equals("token")) {
|
||||||
|
|
|
||||||
|
|
@ -2183,6 +2183,7 @@ public class ScryfallImageSupportTokens {
|
||||||
// WHO
|
// WHO
|
||||||
put("WHO/Alien", "https://api.scryfall.com/cards/twho/2?format=image");
|
put("WHO/Alien", "https://api.scryfall.com/cards/twho/2?format=image");
|
||||||
put("WHO/Alien Insect", "https://api.scryfall.com/cards/twho/19/en?format=image");
|
put("WHO/Alien Insect", "https://api.scryfall.com/cards/twho/19/en?format=image");
|
||||||
|
put("WHO/Alien Rhino", "https://api.scryfall.com/cards/twho/3/en?format=image");
|
||||||
put("WHO/Alien Salamander", "https://api.scryfall.com/cards/twho/16?format=image");
|
put("WHO/Alien Salamander", "https://api.scryfall.com/cards/twho/16?format=image");
|
||||||
put("WHO/Alien Warrior", "https://api.scryfall.com/cards/twho/14?format=image");
|
put("WHO/Alien Warrior", "https://api.scryfall.com/cards/twho/14?format=image");
|
||||||
put("WHO/Beast", "https://api.scryfall.com/cards/twho/17?format=image");
|
put("WHO/Beast", "https://api.scryfall.com/cards/twho/17?format=image");
|
||||||
|
|
@ -2196,7 +2197,8 @@ public class ScryfallImageSupportTokens {
|
||||||
put("WHO/Food/2", "https://api.scryfall.com/cards/twho/26?format=image");
|
put("WHO/Food/2", "https://api.scryfall.com/cards/twho/26?format=image");
|
||||||
put("WHO/Food/3", "https://api.scryfall.com/cards/twho/27?format=image");
|
put("WHO/Food/3", "https://api.scryfall.com/cards/twho/27?format=image");
|
||||||
put("WHO/Horse", "https://api.scryfall.com/cards/twho/4/en?format=image");
|
put("WHO/Horse", "https://api.scryfall.com/cards/twho/4/en?format=image");
|
||||||
put("WHO/Human", "https://api.scryfall.com/cards/twho/5?format=image");
|
put("WHO/Human/1", "https://api.scryfall.com/cards/twho/6/en?format=image");
|
||||||
|
put("WHO/Human/2", "https://api.scryfall.com/cards/twho/5/en?format=image");
|
||||||
put("WHO/Human Noble", "https://api.scryfall.com/cards/twho/7/en?format=image");
|
put("WHO/Human Noble", "https://api.scryfall.com/cards/twho/7/en?format=image");
|
||||||
put("WHO/Mark of the Rani", "https://api.scryfall.com/cards/twho/15?format=image");
|
put("WHO/Mark of the Rani", "https://api.scryfall.com/cards/twho/15?format=image");
|
||||||
put("WHO/Soldier", "https://api.scryfall.com/cards/twho/8?format=image");
|
put("WHO/Soldier", "https://api.scryfall.com/cards/twho/8?format=image");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-common</artifactId>
|
<artifactId>mage-common</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
|
||||||
// * launcher gives priority to 1.4.48 instead 1.4.48-any-text, so don't use empty release info
|
// * launcher gives priority to 1.4.48 instead 1.4.48-any-text, so don't use empty release info
|
||||||
public static final int MAGE_VERSION_MAJOR = 1;
|
public static final int MAGE_VERSION_MAJOR = 1;
|
||||||
public static final int MAGE_VERSION_MINOR = 4;
|
public static final int MAGE_VERSION_MINOR = 4;
|
||||||
public static final int MAGE_VERSION_RELEASE = 56;
|
public static final int MAGE_VERSION_RELEASE = 57;
|
||||||
public static final String MAGE_VERSION_RELEASE_INFO = "V3"; // V1, V1a, V1b for releases; V1-beta3, V1-beta4 for betas
|
public static final String MAGE_VERSION_RELEASE_INFO = "V1"; // V1, V1a, V1b for releases; V1-beta3, V1-beta4 for betas
|
||||||
|
|
||||||
// strict mode
|
// strict mode
|
||||||
// Each update requires a strict version
|
// Each update requires a strict version
|
||||||
|
|
|
||||||
|
|
@ -432,21 +432,21 @@ public class CardView extends SimpleCardView {
|
||||||
fullCardName = mainCard.getLeftHalfCard().getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + mainCard.getRightHalfCard().getName();
|
fullCardName = mainCard.getLeftHalfCard().getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + mainCard.getRightHalfCard().getName();
|
||||||
this.manaCostLeftStr = mainCard.getLeftHalfCard().getManaCostSymbols();
|
this.manaCostLeftStr = mainCard.getLeftHalfCard().getManaCostSymbols();
|
||||||
this.manaCostRightStr = mainCard.getRightHalfCard().getManaCostSymbols();
|
this.manaCostRightStr = mainCard.getRightHalfCard().getManaCostSymbols();
|
||||||
} else if (card instanceof AdventureCard) {
|
} else if (card instanceof CardWithSpellOption) {
|
||||||
this.isSplitCard = true;
|
this.isSplitCard = true;
|
||||||
AdventureCard adventureCard = ((AdventureCard) card);
|
CardWithSpellOption mainCard = ((CardWithSpellOption) card);
|
||||||
leftSplitName = adventureCard.getName();
|
leftSplitName = mainCard.getName();
|
||||||
leftSplitCostsStr = String.join("", adventureCard.getManaCostSymbols());
|
leftSplitCostsStr = String.join("", mainCard.getManaCostSymbols());
|
||||||
leftSplitRules = adventureCard.getSharedRules(game);
|
leftSplitRules = mainCard.getSharedRules(game);
|
||||||
leftSplitTypeLine = getCardTypeLine(game, adventureCard);
|
leftSplitTypeLine = getCardTypeLine(game, mainCard);
|
||||||
AdventureCardSpell adventureCardSpell = adventureCard.getSpellCard();
|
SpellOptionCard splitCardSpell = mainCard.getSpellCard();
|
||||||
rightSplitName = adventureCardSpell.getName();
|
rightSplitName = splitCardSpell.getName();
|
||||||
rightSplitCostsStr = String.join("", adventureCardSpell.getManaCostSymbols());
|
rightSplitCostsStr = String.join("", splitCardSpell.getManaCostSymbols());
|
||||||
rightSplitRules = adventureCardSpell.getRules(game);
|
rightSplitRules = splitCardSpell.getRules(game);
|
||||||
rightSplitTypeLine = getCardTypeLine(game, adventureCardSpell);
|
rightSplitTypeLine = getCardTypeLine(game, splitCardSpell);
|
||||||
fullCardName = adventureCard.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + adventureCardSpell.getName();
|
fullCardName = mainCard.getName() + MockCard.CARD_WITH_SPELL_OPTION_NAME_SEPARATOR + splitCardSpell.getName();
|
||||||
this.manaCostLeftStr = adventureCard.getManaCostSymbols();
|
this.manaCostLeftStr = mainCard.getManaCostSymbols();
|
||||||
this.manaCostRightStr = adventureCardSpell.getManaCostSymbols();
|
this.manaCostRightStr = splitCardSpell.getManaCostSymbols();
|
||||||
} else if (card instanceof MockCard) {
|
} else if (card instanceof MockCard) {
|
||||||
// deck editor cards
|
// deck editor cards
|
||||||
fullCardName = ((MockCard) card).getFullName(true);
|
fullCardName = ((MockCard) card).getFullName(true);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-plugins</artifactId>
|
<artifactId>mage-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-counter-plugin</artifactId>
|
<artifactId>mage-counter-plugin</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-plugins</artifactId>
|
<artifactId>mage-plugins</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-reports</artifactId>
|
<artifactId>mage-reports</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-server-console</artifactId>
|
<artifactId>mage-server-console</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-deck-constructed</artifactId>
|
<artifactId>mage-deck-constructed</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-deck-limited</artifactId>
|
<artifactId>mage-deck-limited</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-brawlduel</artifactId>
|
<artifactId>mage-game-brawlduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-brawlfreeforall</artifactId>
|
<artifactId>mage-game-brawlfreeforall</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-canadianhighlanderduel</artifactId>
|
<artifactId>mage-game-canadianhighlanderduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-commanderduel</artifactId>
|
<artifactId>mage-game-commanderduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-commanderfreeforall</artifactId>
|
<artifactId>mage-game-commanderfreeforall</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-custompillaroftheparunsduel</artifactId>
|
<artifactId>mage-game-custompillaroftheparunsduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-freeforall</artifactId>
|
<artifactId>mage-game-freeforall</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-freeformcommanderduel</artifactId>
|
<artifactId>mage-game-freeformcommanderduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-freeformunlimitedcommander</artifactId>
|
<artifactId>mage-game-freeformunlimitedcommander</artifactId>
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-momirduel</artifactId>
|
<artifactId>mage-game-momirduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-momirfreeforall</artifactId>
|
<artifactId>mage-game-momirfreeforall</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-oathbreakerduel</artifactId>
|
<artifactId>mage-game-oathbreakerduel</artifactId>
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-game-oathbreakerfreeforall</artifactId>
|
<artifactId>mage-game-oathbreakerfreeforall</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-oathbreakerfreeforall</artifactId>
|
<artifactId>mage-game-oathbreakerfreeforall</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>
|
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-tinyleadersduel</artifactId>
|
<artifactId>mage-game-tinyleadersduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-twoplayerduel</artifactId>
|
<artifactId>mage-game-twoplayerduel</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai-draftbot</artifactId>
|
<artifactId>mage-player-ai-draftbot</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai-ma</artifactId>
|
<artifactId>mage-player-ai-ma</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai</artifactId>
|
<artifactId>mage-player-ai</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -1863,8 +1863,11 @@ public class ComputerPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int announceXMana(int min, int max, String message, Game game, Ability ability) {
|
public int announceXMana(int min, int max, String message, Game game, Ability ability) {
|
||||||
log.debug("announceXMana");
|
// current logic - use max possible mana
|
||||||
//TODO: improve this
|
|
||||||
|
// TODO: add good/bad effects support
|
||||||
|
// TODO: add simple game simulations like declare blocker?
|
||||||
|
|
||||||
int numAvailable = getAvailableManaProducers(game).size() - ability.getManaCosts().manaValue();
|
int numAvailable = getAvailableManaProducers(game).size() - ability.getManaCosts().manaValue();
|
||||||
if (numAvailable < 0) {
|
if (numAvailable < 0) {
|
||||||
numAvailable = 0;
|
numAvailable = 0;
|
||||||
|
|
@ -1881,12 +1884,17 @@ public class ComputerPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variablCost) {
|
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variablCost) {
|
||||||
log.debug("announceXCost");
|
// current logic - use random non-zero value
|
||||||
|
|
||||||
|
// TODO: add good/bad effects support
|
||||||
|
// TODO: remove random logic
|
||||||
|
|
||||||
int value = RandomUtil.nextInt(CardUtil.overflowInc(max, 1));
|
int value = RandomUtil.nextInt(CardUtil.overflowInc(max, 1));
|
||||||
if (value < min) {
|
if (value < min) {
|
||||||
value = min;
|
value = min;
|
||||||
}
|
}
|
||||||
if (value < max) {
|
if (value < max) {
|
||||||
|
// do not use zero values
|
||||||
value++;
|
value++;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai-mcts</artifactId>
|
<artifactId>mage-player-ai-mcts</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-human</artifactId>
|
<artifactId>mage-player-human</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -380,9 +380,13 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canCallFeedback(Game game) {
|
||||||
|
return !gameInCheckPlayableState(game) && !game.isSimulation();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseMulligan(Game game) {
|
public boolean chooseMulligan(Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -509,7 +513,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int chooseReplacementEffect(Map<String, String> effectsMap, Map<String, MageObject> objectsMap, Game game) {
|
public int chooseReplacementEffect(Map<String, String> effectsMap, Map<String, MageObject> objectsMap, Game game) {
|
||||||
if (gameInCheckPlayableState(game, true)) { // ignore warning logs until double call for TAPPED_FOR_MANA will be fix
|
if (gameInCheckPlayableState(game, true) || game.isSimulation()) { // TODO: ignore warning logs until double call for TAPPED_FOR_MANA will be fix
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,7 +619,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Choice choice, Game game) {
|
public boolean choose(Outcome outcome, Choice choice, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,7 +682,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map<String, Serializable> options) {
|
public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map<String, Serializable> options) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -782,7 +786,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) {
|
public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -862,7 +866,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
|
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -944,7 +948,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
// choose one or multiple target cards
|
// choose one or multiple target cards
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
|
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1025,7 +1029,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
|
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
|
||||||
// choose amount
|
// choose amount
|
||||||
// human can choose or un-choose MULTIPLE targets at once
|
// human can choose or un-choose MULTIPLE targets at once
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1486,8 +1490,8 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
@Override
|
@Override
|
||||||
public TriggeredAbility chooseTriggeredAbility(java.util.List<TriggeredAbility> abilities, Game game) {
|
public TriggeredAbility chooseTriggeredAbility(java.util.List<TriggeredAbility> abilities, Game game) {
|
||||||
// choose triggered abilitity from list
|
// choose triggered abilitity from list
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return null;
|
return abilities.isEmpty() ? null : abilities.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// automatically order triggers with same ability, rules text, and targets
|
// automatically order triggers with same ability, rules text, and targets
|
||||||
|
|
@ -1615,7 +1619,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
protected boolean playManaHandling(Ability abilityToCast, ManaCost unpaid, String promptText, Game game) {
|
protected boolean playManaHandling(Ability abilityToCast, ManaCost unpaid, String promptText, Game game) {
|
||||||
// choose mana to pay (from permanents or from pool)
|
// choose mana to pay (from permanents or from pool)
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1661,7 +1665,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int announceRepetitions(Game game) {
|
public int announceRepetitions(Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1694,8 +1698,8 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int announceXMana(int min, int max, String message, Game game, Ability ability) {
|
public int announceXMana(int min, int max, String message, Game game, Ability ability) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return 0;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xValue = 0;
|
int xValue = 0;
|
||||||
|
|
@ -1709,6 +1713,8 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
if (response.getInteger() != null) {
|
if (response.getInteger() != null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add response verify here
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.getInteger() != null) {
|
if (response.getInteger() != null) {
|
||||||
|
|
@ -1719,8 +1725,8 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost) {
|
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return 0;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xValue = 0;
|
int xValue = 0;
|
||||||
|
|
@ -1792,7 +1798,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectAttackers(Game game, UUID attackingPlayerId) {
|
public void selectAttackers(Game game, UUID attackingPlayerId) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2062,7 +2068,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectBlockers(Ability source, Game game, UUID defendingPlayerId) {
|
public void selectBlockers(Ability source, Game game, UUID defendingPlayerId) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2072,7 +2078,6 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
// stop skip on any/zero permanents available
|
// stop skip on any/zero permanents available
|
||||||
int possibleBlockersCount = game.getBattlefield().count(filter, playerId, source, game);
|
int possibleBlockersCount = game.getBattlefield().count(filter, playerId, source, game);
|
||||||
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
|
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
|
||||||
boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
|
|
||||||
|
|
||||||
// skip declare blocker step
|
// skip declare blocker step
|
||||||
// as opposed to declare attacker - it can be skipped by ANY skip button TODO: make same for declare attackers and rework skip buttons (normal and forced)
|
// as opposed to declare attacker - it can be skipped by ANY skip button TODO: make same for declare attackers and rework skip buttons (normal and forced)
|
||||||
|
|
@ -2081,9 +2086,11 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|| passedTurn
|
|| passedTurn
|
||||||
|| passedUntilEndOfTurn
|
|| passedUntilEndOfTurn
|
||||||
|| passedUntilNextMain;
|
|| passedUntilNextMain;
|
||||||
if (skipButtonActivated && !canStopOnAny && !canStopOnZero) {
|
if (skipButtonActivated && !canStopOnAny) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Skip prompt to select blockers if player has none
|
||||||
|
if (possibleBlockersCount == 0) return;
|
||||||
|
|
||||||
while (canRespond()) {
|
while (canRespond()) {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
|
@ -2123,7 +2130,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
|
protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TargetAttackingCreature target = new TargetAttackingCreature();
|
TargetAttackingCreature target = new TargetAttackingCreature();
|
||||||
|
|
@ -2177,8 +2184,8 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAmount(int min, int max, String message, Game game) {
|
public int getAmount(int min, int max, String message, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return 0;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (canRespond()) {
|
while (canRespond()) {
|
||||||
|
|
@ -2217,7 +2224,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
return defaultList;
|
return defaultList;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return defaultList;
|
return defaultList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2285,7 +2292,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
* @param unpaidForManaAction - set unpaid for mana actions like convoke
|
* @param unpaidForManaAction - set unpaid for mana actions like convoke
|
||||||
*/
|
*/
|
||||||
protected void activateSpecialAction(Game game, ManaCost unpaidForManaAction) {
|
protected void activateSpecialAction(Game game, ManaCost unpaidForManaAction) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2316,7 +2323,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void activateAbility(Map<UUID, ? extends ActivatedAbility> abilities, MageObject object, Game game) {
|
protected void activateAbility(Map<UUID, ? extends ActivatedAbility> abilities, MageObject object, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2378,7 +2385,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
Card mainCard = game.getCard(CardUtil.getMainCardId(game, ability.getSourceId()));
|
Card mainCard = game.getCard(CardUtil.getMainCardId(game, ability.getSourceId()));
|
||||||
if (mainCard != null && !Zone.BATTLEFIELD.equals(game.getState().getZone(mainCard.getId()))) {
|
if (mainCard != null && !Zone.BATTLEFIELD.equals(game.getState().getZone(mainCard.getId()))) {
|
||||||
if (mainCard instanceof SplitCard
|
if (mainCard instanceof SplitCard
|
||||||
|| mainCard instanceof AdventureCard
|
|| mainCard instanceof CardWithSpellOption
|
||||||
|| mainCard instanceof ModalDoubleFacedCard) {
|
|| mainCard instanceof ModalDoubleFacedCard) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2401,7 +2408,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean noMana) {
|
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean noMana) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2441,7 +2448,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActivatedAbility chooseLandOrSpellAbility(Card card, Game game, boolean noMana) {
|
public ActivatedAbility chooseLandOrSpellAbility(Card card, Game game, boolean noMana) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2488,7 +2495,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
@Override
|
@Override
|
||||||
public Mode chooseMode(Modes modes, Ability source, Game game) {
|
public Mode chooseMode(Modes modes, Ability source, Game game) {
|
||||||
// choose mode to activate
|
// choose mode to activate
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2616,7 +2623,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choosePile(Outcome outcome, String message, java.util.List<? extends Card> pile1, java.util.List<? extends Card> pile2, Game game) {
|
public boolean choosePile(Outcome outcome, String message, java.util.List<? extends Card> pile1, java.util.List<? extends Card> pile2, Game game) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (!canCallFeedback(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-tournament-boosterdraft</artifactId>
|
<artifactId>mage-tournament-boosterdraft</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-tournament-constructed</artifactId>
|
<artifactId>mage-tournament-constructed</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-tournament-sealed</artifactId>
|
<artifactId>mage-tournament-sealed</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-server</artifactId>
|
<artifactId>mage-server</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,6 @@ hand:Human:Angelic Edict:3
|
||||||
battlefield:Computer:Grizzly Bears:2
|
battlefield:Computer:Grizzly Bears:2
|
||||||
battlefield:Human:Grizzly Bears:2
|
battlefield:Human:Grizzly Bears:2
|
||||||
|
|
||||||
// special command, see SystemUtil for more special commands list
|
|
||||||
[@activate opponent ability]
|
|
||||||
|
|
||||||
[diff set codes example]
|
[diff set codes example]
|
||||||
battlefield:Human:XLN-Island:1
|
battlefield:Human:XLN-Island:1
|
||||||
battlefield:Human:UST-Island:1
|
battlefield:Human:UST-Island:1
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.56</version>
|
<version>1.4.57</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-sets</artifactId>
|
<artifactId>mage-sets</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,30 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.costs.costadjusters.DiscardXCardsCostAdjuster;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
|
||||||
import mage.abilities.costs.CostAdjuster;
|
|
||||||
import mage.abilities.costs.common.DiscardTargetCost;
|
|
||||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||||
import mage.abilities.effects.common.InfoEffect;
|
|
||||||
import mage.abilities.effects.common.discard.LookTargetHandChooseDiscardEffect;
|
import mage.abilities.effects.common.discard.LookTargetHandChooseDiscardEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.target.common.TargetCardInHand;
|
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
import mage.util.CardUtil;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author fireshoes
|
* @author fireshoes, JayDi85
|
||||||
*/
|
*/
|
||||||
public final class AbandonHope extends CardImpl {
|
public final class AbandonHope extends CardImpl {
|
||||||
|
|
||||||
public AbandonHope(UUID ownerId, CardSetInfo setInfo) {
|
public AbandonHope(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}");
|
||||||
|
|
||||||
// As an additional cost to cast Abandon Hope, discard X cards.
|
// As an additional cost to cast this spell, discard X cards.
|
||||||
Ability ability = new SimpleStaticAbility(
|
DiscardXCardsCostAdjuster.addAdjusterAndMessage(this, StaticFilters.FILTER_CARD_CARDS);
|
||||||
Zone.ALL, new InfoEffect("As an additional cost to cast this spell, discard X cards")
|
|
||||||
);
|
|
||||||
ability.setRuleAtTheTop(true);
|
|
||||||
this.addAbility(ability);
|
|
||||||
|
|
||||||
// Look at target opponent's hand and choose X cards from it. That player discards those cards.
|
// Look at target opponent's hand and choose X cards from it. That player discards those cards.
|
||||||
this.getSpellAbility().addEffect(new LookTargetHandChooseDiscardEffect(false, GetXValue.instance, StaticFilters.FILTER_CARD_CARDS));
|
this.getSpellAbility().addEffect(new LookTargetHandChooseDiscardEffect(false, GetXValue.instance, StaticFilters.FILTER_CARD_CARDS));
|
||||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||||
this.getSpellAbility().setCostAdjuster(AbandonHopeAdjuster.instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AbandonHope(final AbandonHope card) {
|
private AbandonHope(final AbandonHope card) {
|
||||||
|
|
@ -48,16 +35,4 @@ public final class AbandonHope extends CardImpl {
|
||||||
public AbandonHope copy() {
|
public AbandonHope copy() {
|
||||||
return new AbandonHope(this);
|
return new AbandonHope(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AbandonHopeAdjuster implements CostAdjuster {
|
|
||||||
instance;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
|
||||||
int xValue = CardUtil.getSourceCostsTag(game, ability, "X", 0);
|
|
||||||
if (xValue > 0) {
|
|
||||||
ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, StaticFilters.FILTER_CARD_CARDS)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,8 +9,6 @@ import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.dynamicvalue.common.GreatestToughnessAmongControlledCreaturesValue;
|
import mage.abilities.dynamicvalue.common.GreatestToughnessAmongControlledCreaturesValue;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||||
import mage.abilities.hint.Hint;
|
|
||||||
import mage.abilities.hint.ValueHint;
|
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
|
@ -41,11 +39,6 @@ public final class AbzanMonument extends CardImpl {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Hint hint = new ValueHint(
|
|
||||||
"Greatest toughness among creatures you control",
|
|
||||||
GreatestToughnessAmongControlledCreaturesValue.instance
|
|
||||||
);
|
|
||||||
|
|
||||||
public AbzanMonument(UUID ownerId, CardSetInfo setInfo) {
|
public AbzanMonument(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
|
||||||
|
|
||||||
|
|
@ -60,7 +53,7 @@ public final class AbzanMonument extends CardImpl {
|
||||||
);
|
);
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
ability.addCost(new SacrificeSourceCost());
|
ability.addCost(new SacrificeSourceCost());
|
||||||
this.addAbility(ability.addHint(hint));
|
this.addAbility(ability.addHint(GreatestToughnessAmongControlledCreaturesValue.ALL.getHint()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private AbzanMonument(final AbzanMonument card) {
|
private AbzanMonument(final AbzanMonument card) {
|
||||||
|
|
@ -93,9 +86,7 @@ class AbzanMonumentEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
return new SpiritXXToken(
|
return new SpiritXXToken(
|
||||||
GreatestToughnessAmongControlledCreaturesValue
|
GreatestToughnessAmongControlledCreaturesValue.ALL.calculate(game, source, this)
|
||||||
.instance
|
|
||||||
.calculate(game, source, this)
|
|
||||||
).putOntoBattlefield(1, game, source);
|
).putOntoBattlefield(1, game, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
50
Mage.Sets/src/mage/cards/a/AdaptiveTrainingPost.java
Normal file
50
Mage.Sets/src/mage/cards/a/AdaptiveTrainingPost.java
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||||
|
import mage.abilities.common.delayed.CopyNextSpellDelayedTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||||
|
import mage.abilities.costs.common.RemoveCountersSourceCost;
|
||||||
|
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class AdaptiveTrainingPost extends CardImpl {
|
||||||
|
|
||||||
|
private static final Condition condition = new SourceHasCounterCondition(CounterType.CHARGE, 0, 2);
|
||||||
|
|
||||||
|
public AdaptiveTrainingPost(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}");
|
||||||
|
|
||||||
|
// Whenever you cast an instant or sorcery spell, if this artifact has fewer than three charge counters on it, put a charge counter on it.
|
||||||
|
this.addAbility(new SpellCastControllerTriggeredAbility(
|
||||||
|
new AddCountersSourceEffect(CounterType.CHARGE.createInstance()),
|
||||||
|
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
|
||||||
|
).withInterveningIf(condition));
|
||||||
|
|
||||||
|
// Remove three charge counters from this artifact: When you next cast an instant or sorcery spell this turn, copy it and you may choose new targets for the copy.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(
|
||||||
|
new CreateDelayedTriggeredAbilityEffect(new CopyNextSpellDelayedTriggeredAbility()),
|
||||||
|
new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(3))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private AdaptiveTrainingPost(final AdaptiveTrainingPost card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AdaptiveTrainingPost copy() {
|
||||||
|
return new AdaptiveTrainingPost(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ public final class AeonChronicler extends CardImpl {
|
||||||
this.toughness = new MageInt(0);
|
this.toughness = new MageInt(0);
|
||||||
|
|
||||||
// Aeon Chronicler's power and toughness are each equal to the number of cards in your hand.
|
// Aeon Chronicler's power and toughness are each equal to the number of cards in your hand.
|
||||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.instance)));
|
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.ANY)));
|
||||||
|
|
||||||
// Suspend X-{X}{3}{U}. X can't be 0.
|
// Suspend X-{X}{3}{U}. X can't be 0.
|
||||||
this.addAbility(new SuspendAbility(Integer.MAX_VALUE, new ManaCostsImpl<>("{3}{U}"), this, true));
|
this.addAbility(new SuspendAbility(Integer.MAX_VALUE, new ManaCostsImpl<>("{3}{U}"), this, true));
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,18 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.costs.costadjusters.DiscardXCardsCostAdjuster;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
|
||||||
import mage.abilities.costs.CostAdjuster;
|
|
||||||
import mage.abilities.costs.common.DiscardTargetCost;
|
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.common.InfoEffect;
|
|
||||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.target.common.TargetCardInHand;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.target.targetadjustment.XTargetsCountAdjuster;
|
import mage.target.targetadjustment.XTargetsCountAdjuster;
|
||||||
import mage.util.CardUtil;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class AetherTide extends CardImpl {
|
public final class AetherTide extends CardImpl {
|
||||||
|
|
@ -29,10 +20,8 @@ public final class AetherTide extends CardImpl {
|
||||||
public AetherTide(UUID ownerId, CardSetInfo setInfo) {
|
public AetherTide(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}");
|
||||||
|
|
||||||
// As an additional cost to cast Aether Tide, discard X creature cards.
|
// As an additional cost to cast this spell, discard X creature cards.
|
||||||
Ability ability = new SimpleStaticAbility(Zone.ALL, new InfoEffect("As an additional cost to cast this spell, discard X creature cards"));
|
DiscardXCardsCostAdjuster.addAdjusterAndMessage(this, StaticFilters.FILTER_CARD_CREATURES);
|
||||||
ability.setRuleAtTheTop(true);
|
|
||||||
this.addAbility(ability);
|
|
||||||
|
|
||||||
// Return X target creatures to their owners' hands.
|
// Return X target creatures to their owners' hands.
|
||||||
Effect effect = new ReturnToHandTargetEffect();
|
Effect effect = new ReturnToHandTargetEffect();
|
||||||
|
|
@ -40,8 +29,6 @@ public final class AetherTide extends CardImpl {
|
||||||
this.getSpellAbility().addEffect(effect);
|
this.getSpellAbility().addEffect(effect);
|
||||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||||
this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster());
|
this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster());
|
||||||
this.getSpellAbility().setCostAdjuster(AetherTideCostAdjuster.instance);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AetherTide(final AetherTide card) {
|
private AetherTide(final AetherTide card) {
|
||||||
|
|
@ -53,15 +40,3 @@ public final class AetherTide extends CardImpl {
|
||||||
return new AetherTide(this);
|
return new AetherTide(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AetherTideCostAdjuster implements CostAdjuster {
|
|
||||||
instance;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
|
||||||
int xValue = CardUtil.getSourceCostsTag(game, ability, "X", 0);
|
|
||||||
if (xValue > 0) {
|
|
||||||
ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, StaticFilters.FILTER_CARD_CREATURES)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
47
Mage.Sets/src/mage/cards/a/AggressiveNegotiations.java
Normal file
47
Mage.Sets/src/mage/cards/a/AggressiveNegotiations.java
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.ExileCardYouChooseTargetOpponentEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
|
import mage.target.targetpointer.SecondTargetPointer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggressive Negotiations implementation
|
||||||
|
* Author: @mikejcunn
|
||||||
|
*/
|
||||||
|
public final class AggressiveNegotiations extends CardImpl {
|
||||||
|
|
||||||
|
public AggressiveNegotiations(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
|
||||||
|
|
||||||
|
// Target opponent reveals their hand. You choose a nonland card from it. That player exiles that card.
|
||||||
|
Effect effect1 = new ExileCardYouChooseTargetOpponentEffect(StaticFilters.FILTER_CARD_A_NON_LAND);
|
||||||
|
this.getSpellAbility().addEffect(effect1);
|
||||||
|
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||||
|
|
||||||
|
// Put a +1/+1 counter on target creature you control.
|
||||||
|
this.getSpellAbility().addEffect(new AddCountersTargetEffect(
|
||||||
|
CounterType.P1P1.createInstance()
|
||||||
|
).setTargetPointer(new SecondTargetPointer()));
|
||||||
|
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private AggressiveNegotiations(final AggressiveNegotiations card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AggressiveNegotiations copy() {
|
||||||
|
return new AggressiveNegotiations(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ class AgrusKosEternalSoldierTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
if (!event.getTargetId().equals(getSourceId())) {
|
if (!event.getTargetId().equals(getSourceId())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
StackObject targetingObject = CardUtil.getTargetingStackObject(event, game);
|
StackObject targetingObject = CardUtil.getTargetingStackObject(this.getId().toString(), event, game);
|
||||||
if (targetingObject == null || targetingObject instanceof Spell) {
|
if (targetingObject == null || targetingObject instanceof Spell) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.CostAdjuster;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.costs.mana.VariableManaCost;
|
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -36,12 +36,8 @@ public final class AladdinsLamp extends CardImpl {
|
||||||
// {X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0.
|
// {X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0.
|
||||||
Ability ability = new SimpleActivatedAbility(new AladdinsLampEffect(), new ManaCostsImpl<>("{X}"));
|
Ability ability = new SimpleActivatedAbility(new AladdinsLampEffect(), new ManaCostsImpl<>("{X}"));
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
for (Object cost : ability.getManaCosts()) {
|
ability.setCostAdjuster(AladdinsLampCostAdjuster.instance);
|
||||||
if (cost instanceof VariableManaCost) {
|
|
||||||
((VariableManaCost) cost).setMinX(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,3 +97,17 @@ class AladdinsLampEffect extends ReplacementEffectImpl {
|
||||||
return source.isControlledBy(event.getPlayerId());
|
return source.isControlledBy(event.getPlayerId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AladdinsLampCostAdjuster implements CostAdjuster {
|
||||||
|
instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareX(Ability ability, Game game) {
|
||||||
|
Player controller = game.getPlayer(ability.getControllerId());
|
||||||
|
if (controller == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ability.setVariableCostsMinMax(1, Math.max(1, controller.getLibrary().size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,8 @@ public final class AlandraSkyDreamer extends CardImpl {
|
||||||
// Whenever you draw your fifth card each turn, Alandra, Sky Dreamer and Drakes you control each get +X/+X until end of turn, where X is the number of cards in your hand.
|
// Whenever you draw your fifth card each turn, Alandra, Sky Dreamer and Drakes you control each get +X/+X until end of turn, where X is the number of cards in your hand.
|
||||||
DrawNthCardTriggeredAbility drawNthCardTriggeredAbility = new DrawNthCardTriggeredAbility(
|
DrawNthCardTriggeredAbility drawNthCardTriggeredAbility = new DrawNthCardTriggeredAbility(
|
||||||
new BoostSourceEffect(
|
new BoostSourceEffect(
|
||||||
CardsInControllerHandCount.instance,
|
CardsInControllerHandCount.ANY,
|
||||||
CardsInControllerHandCount.instance,
|
CardsInControllerHandCount.ANY,
|
||||||
Duration.EndOfTurn
|
Duration.EndOfTurn
|
||||||
).setText("{this}"),
|
).setText("{this}"),
|
||||||
false,
|
false,
|
||||||
|
|
@ -56,8 +56,8 @@ public final class AlandraSkyDreamer extends CardImpl {
|
||||||
);
|
);
|
||||||
drawNthCardTriggeredAbility.addEffect(
|
drawNthCardTriggeredAbility.addEffect(
|
||||||
new BoostControlledEffect(
|
new BoostControlledEffect(
|
||||||
CardsInControllerHandCount.instance,
|
CardsInControllerHandCount.ANY,
|
||||||
CardsInControllerHandCount.instance,
|
CardsInControllerHandCount.ANY,
|
||||||
Duration.EndOfTurn,
|
Duration.EndOfTurn,
|
||||||
filter,
|
filter,
|
||||||
false
|
false
|
||||||
|
|
|
||||||
42
Mage.Sets/src/mage/cards/a/AlignedHeart.java
Normal file
42
Mage.Sets/src/mage/cards/a/AlignedHeart.java
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.FlurryAbility;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||||
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.game.permanent.token.MonasteryMentorToken;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class AlignedHeart extends CardImpl {
|
||||||
|
|
||||||
|
private static final DynamicValue xValue = new CountersSourceCount(CounterType.RALLY);
|
||||||
|
|
||||||
|
public AlignedHeart(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
|
||||||
|
|
||||||
|
// Flurry -- Whenever you cast your second spell each turn, put a rally counter on this enchantment. Then create a 1/1 white Monk creature token with prowess for each rally counter on it.
|
||||||
|
Ability ability = new FlurryAbility(new AddCountersSourceEffect(CounterType.RALLY.createInstance()));
|
||||||
|
ability.addEffect(new CreateTokenEffect(new MonasteryMentorToken(), xValue)
|
||||||
|
.setText("then create a 1/1 white Monk creature token with prowess for each rally counter on it"));
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AlignedHeart(final AlignedHeart card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AlignedHeart copy() {
|
||||||
|
return new AlignedHeart(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ class AncientExcavationEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
DynamicValue numCards = CardsInControllerHandCount.instance;
|
DynamicValue numCards = CardsInControllerHandCount.ANY;
|
||||||
int amount = numCards.calculate(game, source, this);
|
int amount = numCards.calculate(game, source, this);
|
||||||
int cardsDrawn = player.drawCards(amount, source, game);
|
int cardsDrawn = player.drawCards(amount, source, game);
|
||||||
player.discard(cardsDrawn, false, false, source, game);
|
player.discard(cardsDrawn, false, false, source, game);
|
||||||
|
|
|
||||||
48
Mage.Sets/src/mage/cards/a/ArborAdherent.java
Normal file
48
Mage.Sets/src/mage/cards/a/ArborAdherent.java
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.Mana;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.dynamicvalue.common.GreatestToughnessAmongControlledCreaturesValue;
|
||||||
|
import mage.abilities.mana.AnyColorManaAbility;
|
||||||
|
import mage.abilities.mana.DynamicManaAbility;
|
||||||
|
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 ArborAdherent extends CardImpl {
|
||||||
|
|
||||||
|
public ArborAdherent(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DOG);
|
||||||
|
this.subtype.add(SubType.DRUID);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
|
// {T}: Add one mana of any color.
|
||||||
|
this.addAbility(new AnyColorManaAbility());
|
||||||
|
|
||||||
|
// {T}: Add X mana of any one color, where X is the greatest toughness among other creatures you control.
|
||||||
|
this.addAbility(new DynamicManaAbility(
|
||||||
|
Mana.AnyMana(1), GreatestToughnessAmongControlledCreaturesValue.OTHER,
|
||||||
|
new TapSourceCost(), "add X mana of any one color, where X is the " +
|
||||||
|
"greatest toughness among other creatures you control", true
|
||||||
|
).addHint(GreatestToughnessAmongControlledCreaturesValue.OTHER.getHint()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArborAdherent(final ArborAdherent card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArborAdherent copy() {
|
||||||
|
return new ArborAdherent(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -26,7 +25,7 @@ public final class Archivist extends CardImpl {
|
||||||
this.power = new MageInt(1);
|
this.power = new MageInt(1);
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
//{T}: Draw a card.
|
// {T}: Draw a card.
|
||||||
this.addAbility(new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost()));
|
this.addAbility(new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ enum ArmMountedAnchorAdjuster implements CostAdjuster {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void reduceCost(Ability ability, Game game) {
|
||||||
// checking state
|
// checking state
|
||||||
if (HeckbentCondition.instance.apply(game, ability)) {
|
if (HeckbentCondition.instance.apply(game, ability)) {
|
||||||
CardUtil.reduceCost(ability, 2);
|
CardUtil.reduceCost(ability, 2);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.common.EntersBattlefieldAbility;
|
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.ModeChoiceSourceCondition;
|
|
||||||
import mage.abilities.effects.common.ChooseModeEffect;
|
import mage.abilities.effects.common.ChooseModeEffect;
|
||||||
import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect;
|
import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
|
||||||
|
|
@ -14,31 +11,44 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Zone;
|
import mage.constants.ModeChoice;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.EntersTheBattlefieldEvent;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Eirkei
|
* @author Eirkei
|
||||||
*/
|
*/
|
||||||
public final class AshlingsPrerogative extends CardImpl {
|
public final class AshlingsPrerogative extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filterMatch
|
||||||
|
= new FilterCreaturePermanent("each creature with mana value of the chosen quality");
|
||||||
|
private static final FilterPermanent filterNotMatch
|
||||||
|
= new FilterCreaturePermanent("each creature without mana value of the chosen quality");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filterMatch.add(AshlingsPrerogativePredicate.WITH);
|
||||||
|
filterNotMatch.add(AshlingsPrerogativePredicate.WITHOUT);
|
||||||
|
}
|
||||||
|
|
||||||
public AshlingsPrerogative(UUID ownerId, CardSetInfo setInfo) {
|
public AshlingsPrerogative(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
|
||||||
|
|
||||||
// As Ashling's Prerogative enters the battlefield, choose odd or even.
|
// As Ashling's Prerogative enters the battlefield, choose odd or even.
|
||||||
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Odd or even?", "Odd", "Even"), null, "As {this} enters, choose odd or even. <i>(Zero is even.)</i>", ""));
|
this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.ODD, ModeChoice.EVEN)));
|
||||||
|
|
||||||
// Each creature with converted mana cost of the chosen value has haste.
|
// Each creature with converted mana cost of the chosen value has haste.
|
||||||
this.addAbility(new SimpleStaticAbility(new AshlingsPrerogativeCorrectOddityEffect()));
|
this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect(
|
||||||
|
HasteAbility.getInstance(), Duration.WhileOnBattlefield, filterMatch
|
||||||
|
)));
|
||||||
|
|
||||||
// Each creature without converted mana cost of the chosen value enters the battlefield tapped.
|
// Each creature without converted mana cost of the chosen value enters the battlefield tapped.
|
||||||
this.addAbility(new SimpleStaticAbility(new AshlingsPrerogativeIncorrectOddityEffect()));
|
this.addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(filterNotMatch)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AshlingsPrerogative(final AshlingsPrerogative card) {
|
private AshlingsPrerogative(final AshlingsPrerogative card) {
|
||||||
|
|
@ -51,67 +61,23 @@ public final class AshlingsPrerogative extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AshlingsPrerogativeIncorrectOddityEffect extends PermanentsEnterBattlefieldTappedEffect {
|
enum AshlingsPrerogativePredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||||
|
WITH(true),
|
||||||
|
WITHOUT(false);
|
||||||
|
private final boolean match;
|
||||||
|
|
||||||
private static final FilterCreaturePermanent creaturefilter = new FilterCreaturePermanent("Each creature without mana value of the chosen quality");
|
AshlingsPrerogativePredicate(boolean match) {
|
||||||
private static final ModeChoiceSourceCondition oddCondition = new ModeChoiceSourceCondition("Odd");
|
this.match = match;
|
||||||
|
|
||||||
public AshlingsPrerogativeIncorrectOddityEffect() {
|
|
||||||
super(creaturefilter);
|
|
||||||
staticText = "Each creature without mana value of the chosen quality enters the battlefield tapped.";
|
|
||||||
}
|
|
||||||
|
|
||||||
private AshlingsPrerogativeIncorrectOddityEffect(final AshlingsPrerogativeIncorrectOddityEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||||
int incorrectModResult;
|
if (ModeChoice.ODD.checkMode(game, input.getSource())) {
|
||||||
|
return (input.getObject().getManaValue() % 2 == 1) == match;
|
||||||
if (oddCondition.apply(game, source)) {
|
} else if (ModeChoice.EVEN.checkMode(game, input.getSource())) {
|
||||||
incorrectModResult = 0;
|
return (input.getObject().getManaValue() % 2 == 0) == match;
|
||||||
} else {
|
} else {
|
||||||
incorrectModResult = 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
|
|
||||||
|
|
||||||
return permanent != null && creaturefilter.match(permanent, game) && permanent.getManaValue() % 2 == incorrectModResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AshlingsPrerogativeIncorrectOddityEffect copy() {
|
|
||||||
return new AshlingsPrerogativeIncorrectOddityEffect(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AshlingsPrerogativeCorrectOddityEffect extends GainAbilityAllEffect {
|
|
||||||
|
|
||||||
private static final FilterCreaturePermanent creaturefilter = new FilterCreaturePermanent("Each creature with mana value of the chosen quality");
|
|
||||||
private static final ModeChoiceSourceCondition oddCondition = new ModeChoiceSourceCondition("Odd");
|
|
||||||
|
|
||||||
public AshlingsPrerogativeCorrectOddityEffect() {
|
|
||||||
super(HasteAbility.getInstance(), Duration.WhileOnBattlefield, creaturefilter);
|
|
||||||
staticText = "Each creature with mana value of the chosen quality has haste.";
|
|
||||||
}
|
|
||||||
private AshlingsPrerogativeCorrectOddityEffect(final AshlingsPrerogativeCorrectOddityEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean selectedByRuntimeData(Permanent permanent, Ability source, Game game) {
|
|
||||||
int correctModResult;
|
|
||||||
if (oddCondition.apply(game, source)) {
|
|
||||||
correctModResult = 1;
|
|
||||||
} else {
|
|
||||||
correctModResult = 0;
|
|
||||||
}
|
|
||||||
return permanent != null && creaturefilter.match(permanent, game) && permanent.getManaValue() % 2 == correctModResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AshlingsPrerogativeCorrectOddityEffect copy() {
|
|
||||||
return new AshlingsPrerogativeCorrectOddityEffect(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ public final class BaldinCenturyHerdmaster extends CardImpl {
|
||||||
|
|
||||||
// Whenever Baldin, Century Herdmaster attacks, up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand.
|
// Whenever Baldin, Century Herdmaster attacks, up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand.
|
||||||
Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(
|
Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(
|
||||||
StaticValue.get(0), CardsInControllerHandCount.instance, Duration.EndOfTurn
|
StaticValue.get(0), CardsInControllerHandCount.ANY, Duration.EndOfTurn
|
||||||
).setText("up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand"));
|
).setText("up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand"));
|
||||||
ability.addTarget(new TargetCreaturePermanent(0, 100));
|
ability.addTarget(new TargetCreaturePermanent(0, 100));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
|
||||||
|
|
@ -144,10 +144,9 @@ class BanditsTalentDiscardEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum BanditsTalentValue implements DynamicValue {
|
enum BanditsTalentValue implements DynamicValue {
|
||||||
instance;
|
instance;
|
||||||
private static final Hint hint = new ValueHint("opponents who have one or fewer cards in hand", instance);
|
private static final Hint hint = new ValueHint("Opponents who have one or fewer cards in hand", instance);
|
||||||
|
|
||||||
public static Hint getHint() {
|
public static Hint getHint() {
|
||||||
return hint;
|
return hint;
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,28 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.CostAdjuster;
|
import mage.abilities.costs.CostAdjuster;
|
||||||
|
import mage.abilities.costs.EarlyTargetCost;
|
||||||
|
import mage.abilities.costs.VariableCostType;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
import mage.abilities.costs.mana.VariableManaCost;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.InfoEffect;
|
import mage.abilities.effects.common.InfoEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
import mage.target.Target;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
import mage.util.CardUtil;
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @author awjackson, JayDi85
|
||||||
* @author awjackson
|
|
||||||
*/
|
*/
|
||||||
public final class BargainingTable extends CardImpl {
|
public final class BargainingTable extends CardImpl {
|
||||||
|
|
||||||
|
|
@ -27,13 +30,10 @@ public final class BargainingTable extends CardImpl {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
||||||
|
|
||||||
// {X}, {T}: Draw a card. X is the number of cards in an opponent's hand.
|
// {X}, {T}: Draw a card. X is the number of cards in an opponent's hand.
|
||||||
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{X}"));
|
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new BargainingTableXCost());
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
ability.addEffect(new InfoEffect("X is the number of cards in an opponent's hand"));
|
ability.addEffect(new InfoEffect("X is the number of cards in an opponent's hand"));
|
||||||
// You choose an opponent on announcement. This is not targeted, but a choice is still made.
|
ability.setCostAdjuster(BargainingTableCostAdjuster.instance);
|
||||||
// This choice is made before determining the value for X that is used in the cost. (2004-10-04)
|
|
||||||
ability.addTarget(new TargetOpponent(true));
|
|
||||||
ability.setCostAdjuster(BargainingTableAdjuster.instance);
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,26 +47,70 @@ public final class BargainingTable extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BargainingTableAdjuster implements CostAdjuster {
|
class BargainingTableXCost extends VariableManaCost implements EarlyTargetCost {
|
||||||
|
|
||||||
|
// You choose an opponent on announcement. This is not targeted, but a choice is still made.
|
||||||
|
// This choice is made before determining the value for X that is used in the cost.
|
||||||
|
// (2004-10-04)
|
||||||
|
|
||||||
|
public BargainingTableXCost() {
|
||||||
|
super(VariableCostType.NORMAL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BargainingTableXCost(final BargainingTableXCost cost) {
|
||||||
|
super(cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void chooseTarget(Game game, Ability source, Player controller) {
|
||||||
|
Target targetOpponent = new TargetOpponent(true);
|
||||||
|
controller.choose(Outcome.Benefit, targetOpponent, source, game);
|
||||||
|
addTarget(targetOpponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BargainingTableXCost copy() {
|
||||||
|
return new BargainingTableXCost(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BargainingTableCostAdjuster implements CostAdjuster {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void prepareX(Ability ability, Game game) {
|
||||||
int handSize = Integer.MAX_VALUE;
|
// make sure early target used
|
||||||
if (game.inCheckPlayableState()) {
|
BargainingTableXCost cost = ability.getManaCostsToPay().getVariableCosts().stream()
|
||||||
for (UUID playerId : CardUtil.getAllPossibleTargets(ability, game)) {
|
.filter(c -> c instanceof BargainingTableXCost)
|
||||||
Player player = game.getPlayer(playerId);
|
.map(c -> (BargainingTableXCost) c)
|
||||||
if (player != null) {
|
.findFirst()
|
||||||
handSize = Math.min(handSize, player.getHand().size());
|
.orElse(null);
|
||||||
}
|
if (cost == null) {
|
||||||
}
|
throw new IllegalArgumentException("Wrong code usage: cost item lost");
|
||||||
} else {
|
}
|
||||||
Player player = game.getPlayer(ability.getFirstTarget());
|
|
||||||
if (player != null) {
|
if (game.inCheckPlayableState()) {
|
||||||
handSize = player.getHand().size();
|
// possible X
|
||||||
}
|
int minHandSize = game.getOpponents(ability.getControllerId(), true).stream()
|
||||||
|
.map(game::getPlayer)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.mapToInt(p -> p.getHand().size())
|
||||||
|
.min()
|
||||||
|
.orElse(0);
|
||||||
|
int maxHandSize = game.getOpponents(ability.getControllerId(), true).stream()
|
||||||
|
.map(game::getPlayer)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.mapToInt(p -> p.getHand().size())
|
||||||
|
.max()
|
||||||
|
.orElse(Integer.MAX_VALUE);
|
||||||
|
ability.setVariableCostsMinMax(minHandSize, maxHandSize);
|
||||||
|
} else {
|
||||||
|
// real X
|
||||||
|
Player opponent = game.getPlayer(cost.getTargets().getFirstTarget());
|
||||||
|
if (opponent == null) {
|
||||||
|
throw new IllegalStateException("Wrong code usage: cost target lost");
|
||||||
|
}
|
||||||
|
ability.setVariableCostsValue(opponent.getHand().size());
|
||||||
}
|
}
|
||||||
ability.clearManaCostsToPay();
|
|
||||||
ability.addManaCostsToPay(new GenericManaCost(handSize));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.abilities.common.EntersBattlefieldAbility;
|
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.CreatureDiedControlledCondition;
|
import mage.abilities.condition.common.CreatureDiedControlledCondition;
|
||||||
import mage.abilities.condition.common.ModeChoiceSourceCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.ChooseModeEffect;
|
import mage.abilities.effects.common.ChooseModeEffect;
|
||||||
import mage.abilities.effects.common.SacrificeOpponentsEffect;
|
import mage.abilities.effects.common.SacrificeOpponentsEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
|
||||||
import mage.abilities.effects.common.counter.AddCountersAllEffect;
|
import mage.abilities.effects.common.counter.AddCountersAllEffect;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.ModeChoice;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
|
|
||||||
|
|
@ -22,35 +22,25 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class BarrensteppeSiege extends CardImpl {
|
public final class BarrensteppeSiege extends CardImpl {
|
||||||
|
|
||||||
private static final Condition condition1 = new ModeChoiceSourceCondition("Abzan");
|
|
||||||
private static final String rule1 = "&bull Abzan — At the beginning of your end step, " +
|
|
||||||
"put a +1/+1 counter on each creature you control.";
|
|
||||||
private static final Condition condition2 = new ModeChoiceSourceCondition("Mardu");
|
|
||||||
private static final String rule2 = "&bull Mardu — At the beginning of your end step, " +
|
|
||||||
"if a creature died under your control this turn, each opponent sacrifices a creature of their choice.";
|
|
||||||
|
|
||||||
public BarrensteppeSiege(UUID ownerId, CardSetInfo setInfo) {
|
public BarrensteppeSiege(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{B}");
|
||||||
|
|
||||||
// As this enchantment enters, choose Abzan or Mardu.
|
// As this enchantment enters, choose Abzan or Mardu.
|
||||||
this.addAbility(new EntersBattlefieldAbility(
|
this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.ABZAN, ModeChoice.MARDU)));
|
||||||
new ChooseModeEffect("Abzan or Mardu?", "Abzan", "Mardu"),
|
|
||||||
null, "As {this} enters, choose Abzan or Mardu.", ""
|
|
||||||
));
|
|
||||||
|
|
||||||
// * Abzan -- At the beginning of your end step, put a +1/+1 counter on each creature you control.
|
// * Abzan -- At the beginning of your end step, put a +1/+1 counter on each creature you control.
|
||||||
this.addAbility(new ConditionalTriggeredAbility(
|
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
|
||||||
new BeginningOfEndStepTriggeredAbility(new AddCountersAllEffect(
|
new BeginningOfEndStepTriggeredAbility(new AddCountersAllEffect(
|
||||||
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
|
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
|
||||||
)), condition1, rule1
|
)), ModeChoice.ABZAN
|
||||||
));
|
)));
|
||||||
|
|
||||||
// * Mardu -- At the beginning of your end step, if a creature died under your control this turn, each opponent sacrifices a creature of their choice.
|
// * Mardu -- At the beginning of your end step, if a creature died under your control this turn, each opponent sacrifices a creature of their choice.
|
||||||
this.addAbility(new ConditionalTriggeredAbility(
|
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(
|
||||||
new BeginningOfEndStepTriggeredAbility(
|
new BeginningOfEndStepTriggeredAbility(
|
||||||
new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE)
|
new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE)
|
||||||
).withInterveningIf(CreatureDiedControlledCondition.instance), condition2, rule2
|
).withInterveningIf(CreatureDiedControlledCondition.instance), ModeChoice.MARDU
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BarrensteppeSiege(final BarrensteppeSiege card) {
|
private BarrensteppeSiege(final BarrensteppeSiege card) {
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,7 @@ import mage.abilities.hint.ValueHint;
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.*;
|
||||||
import mage.constants.Duration;
|
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.SuperType;
|
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
|
@ -116,7 +113,7 @@ enum BaruWurmspeakerAdjuster implements CostAdjuster {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void reduceCost(Ability ability, Game game) {
|
||||||
int value = BaruWurmspeakerValue.instance.calculate(game, ability, null);
|
int value = BaruWurmspeakerValue.instance.calculate(game, ability, null);
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
CardUtil.reduceCost(ability, value);
|
CardUtil.reduceCost(ability, value);
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,35 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AsEntersBattlefieldAbility;
|
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||||
import mage.abilities.condition.common.ModeChoiceSourceCondition;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.ChooseModeEffect;
|
import mage.abilities.effects.common.ChooseModeEffect;
|
||||||
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect;
|
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
|
||||||
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.ComparisonType;
|
import mage.constants.ComparisonType;
|
||||||
|
import mage.constants.ModeChoice;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterCreatureCard;
|
import mage.filter.common.FilterCreatureCard;
|
||||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||||
import mage.target.common.TargetCardInYourGraveyard;
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Cguy7777
|
* @author Cguy7777
|
||||||
*/
|
*/
|
||||||
public final class BattleOfHooverDam extends CardImpl {
|
public final class BattleOfHooverDam extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCreatureCard filter = new FilterCreatureCard();
|
private static final FilterCard filter = new FilterCreatureCard();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4));
|
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4));
|
||||||
|
|
@ -37,32 +39,23 @@ public final class BattleOfHooverDam extends CardImpl {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
|
||||||
|
|
||||||
// As Battle of Hoover Dam enters the battlefield, choose NCR or Legion.
|
// As Battle of Hoover Dam enters the battlefield, choose NCR or Legion.
|
||||||
this.addAbility(new AsEntersBattlefieldAbility(
|
this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.NCR, ModeChoice.LEGION)));
|
||||||
new ChooseModeEffect("NCR or Legion?", "NCR", "Legion")));
|
|
||||||
|
|
||||||
// * NCR -- At the beginning of your end step, return target creature card with mana value 3 or less
|
// * NCR -- At the beginning of your end step, return target creature card with mana value 3 or less
|
||||||
// from your graveyard to the battlefield with a finality counter on it.
|
// from your graveyard to the battlefield with a finality counter on it.
|
||||||
Ability ncrAbility = new ConditionalTriggeredAbility(
|
Ability ability = new BeginningOfEndStepTriggeredAbility(
|
||||||
new BeginningOfEndStepTriggeredAbility(
|
new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.FINALITY.createInstance())
|
||||||
new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.FINALITY.createInstance())
|
);
|
||||||
),
|
ability.addTarget(new TargetCardInYourGraveyard(filter));
|
||||||
new ModeChoiceSourceCondition("NCR"),
|
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.NCR)));
|
||||||
"&bull NCR — At the beginning of your end step, return target creature card with " +
|
|
||||||
"mana value 3 or less from your graveyard to the battlefield with a finality counter on it.");
|
|
||||||
ncrAbility.addTarget(new TargetCardInYourGraveyard(filter));
|
|
||||||
this.addAbility(ncrAbility);
|
|
||||||
|
|
||||||
// * Legion -- Whenever a creature you control dies, put two +1/+1 counters on target creature you control.
|
// * Legion -- Whenever a creature you control dies, put two +1/+1 counters on target creature you control.
|
||||||
Ability legionAbility = new ConditionalTriggeredAbility(
|
ability = new DiesCreatureTriggeredAbility(
|
||||||
new DiesCreatureTriggeredAbility(
|
new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)),
|
||||||
new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)),
|
false, StaticFilters.FILTER_CONTROLLED_A_CREATURE
|
||||||
false,
|
);
|
||||||
StaticFilters.FILTER_CONTROLLED_A_CREATURE),
|
ability.addTarget(new TargetControlledCreaturePermanent());
|
||||||
new ModeChoiceSourceCondition("Legion"),
|
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.LEGION)));
|
||||||
"&bull Legion — Whenever a creature you control dies, " +
|
|
||||||
"put two +1/+1 counters on target creature you control.");
|
|
||||||
legionAbility.addTarget(new TargetControlledCreaturePermanent());
|
|
||||||
this.addAbility(legionAbility);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BattleOfHooverDam(final BattleOfHooverDam card) {
|
private BattleOfHooverDam(final BattleOfHooverDam card) {
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ enum BattlefieldButcherAdjuster implements CostAdjuster {
|
||||||
private static final Hint hint = new ValueHint("Creature cards in your graveyard", xValue);
|
private static final Hint hint = new ValueHint("Creature cards in your graveyard", xValue);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void reduceCost(Ability ability, Game game) {
|
||||||
CardUtil.reduceCost(ability, xValue.calculate(game, ability, null));
|
CardUtil.reduceCost(ability, xValue.calculate(game, ability, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
55
Mage.Sets/src/mage/cards/b/BecomeTheAvalanche.java
Normal file
55
Mage.Sets/src/mage/cards/b/BecomeTheAvalanche.java
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
package mage.cards.b;
|
||||||
|
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
|
||||||
|
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||||
|
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.ComparisonType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.predicate.mageobject.PowerPredicate;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class BecomeTheAvalanche extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter
|
||||||
|
= new FilterControlledCreaturePermanent("creature you control with power 4 or greater");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
|
||||||
|
private static final Hint hint = new ValueHint("Creatures you control with power 4 or greater", xValue);
|
||||||
|
|
||||||
|
public BecomeTheAvalanche(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{G}");
|
||||||
|
|
||||||
|
// Draw a card for each creature you control with power 4 or greater. Then creatures you control get +X/+X until end of turn, where X is the number of cards in your hand.
|
||||||
|
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(xValue));
|
||||||
|
this.getSpellAbility().addEffect(new BoostControlledEffect(
|
||||||
|
CardsInControllerHandCount.ANY, CardsInControllerHandCount.ANY, Duration.EndOfTurn
|
||||||
|
));
|
||||||
|
this.getSpellAbility().addHint(hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BecomeTheAvalanche(final BecomeTheAvalanche card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BecomeTheAvalanche copy() {
|
||||||
|
return new BecomeTheAvalanche(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,20 +3,21 @@ package mage.cards.b;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.costs.CostAdjuster;
|
import mage.abilities.costs.CostAdjuster;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
import mage.abilities.effects.common.continuous.SetBasePowerToughnessEnchantedEffect;
|
import mage.abilities.effects.common.continuous.SetBasePowerToughnessEnchantedEffect;
|
||||||
import mage.abilities.keyword.EquipAbility;
|
import mage.abilities.keyword.EquipAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
|
|
@ -35,7 +36,7 @@ public final class BeltOfGiantStrength extends CardImpl {
|
||||||
// Equip {10}. This ability costs {X} less to activate where X is the power of the creature it targets.
|
// Equip {10}. This ability costs {X} less to activate where X is the power of the creature it targets.
|
||||||
EquipAbility ability = new EquipAbility(Outcome.BoostCreature, new GenericManaCost(10), new TargetControlledCreaturePermanent(), false);
|
EquipAbility ability = new EquipAbility(Outcome.BoostCreature, new GenericManaCost(10), new TargetControlledCreaturePermanent(), false);
|
||||||
ability.setCostReduceText("This ability costs {X} less to activate, where X is the power of the creature it targets.");
|
ability.setCostReduceText("This ability costs {X} less to activate, where X is the power of the creature it targets.");
|
||||||
ability.setCostAdjuster(BeltOfGiantStrengthAdjuster.instance);
|
ability.setCostAdjuster(BeltOfGiantStrengthCostAdjuster.instance);
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,33 +50,23 @@ public final class BeltOfGiantStrength extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BeltOfGiantStrengthAdjuster implements CostAdjuster {
|
enum BeltOfGiantStrengthCostAdjuster implements CostAdjuster {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void reduceCost(Ability ability, Game game) {
|
||||||
|
int power;
|
||||||
if (game.inCheckPlayableState()) {
|
if (game.inCheckPlayableState()) {
|
||||||
int maxPower = 0;
|
power = CardUtil.getAllPossibleTargets(ability, game).stream()
|
||||||
for (UUID permId : CardUtil.getAllPossibleTargets(ability, game)) {
|
.map(game::getPermanent)
|
||||||
Permanent permanent = game.getPermanent(permId);
|
.filter(Objects::nonNull)
|
||||||
if (permanent != null) {
|
.mapToInt(p -> p.getPower().getValue())
|
||||||
int power = permanent.getPower().getValue();
|
.max().orElse(0);
|
||||||
if (power > maxPower) {
|
|
||||||
maxPower = power;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (maxPower > 0) {
|
|
||||||
CardUtil.reduceCost(ability, maxPower);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Permanent permanent = game.getPermanent(ability.getFirstTarget());
|
power = Optional.ofNullable(game.getPermanent(ability.getFirstTarget()))
|
||||||
if (permanent != null) {
|
.map(p -> p.getPower().getValue())
|
||||||
int power = permanent.getPower().getValue();
|
.orElse(0);
|
||||||
if (power > 0) {
|
|
||||||
CardUtil.reduceCost(ability, power);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
CardUtil.reduceCost(ability, power);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
165
Mage.Sets/src/mage/cards/b/BetorKinToAll.java
Normal file
165
Mage.Sets/src/mage/cards/b/BetorKinToAll.java
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
package mage.cards.b;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.hint.Hint;
|
||||||
|
import mage.abilities.hint.ValueHint;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author androosss
|
||||||
|
*/
|
||||||
|
public final class BetorKinToAll extends CardImpl {
|
||||||
|
|
||||||
|
private static final Hint hint = new ValueHint(
|
||||||
|
"Total toughness of creatures you control", ControlledCreaturesToughnessValue.instance);
|
||||||
|
|
||||||
|
public BetorKinToAll(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[] { CardType.CREATURE }, "{2}{W}{B}{G}");
|
||||||
|
|
||||||
|
this.supertype.add(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.SPIRIT);
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(5);
|
||||||
|
this.toughness = new MageInt(7);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// At the beginning of your end step, if creatures you control have total
|
||||||
|
// toughness 10 or greater, draw a card. Then if creatures you control have
|
||||||
|
// total toughness 20 or greater, untap each creature you control. Then if
|
||||||
|
// creatures you control have total toughness 40 or greater, each opponent loses
|
||||||
|
// half their life, rounded up.
|
||||||
|
Ability betorAbility = new BeginningOfEndStepTriggeredAbility(new DrawCardSourceControllerEffect(1))
|
||||||
|
.withInterveningIf(BetorKinToAllCondition.instance).addHint(hint);
|
||||||
|
betorAbility.addEffect(new BetorKinToAllEffect());
|
||||||
|
this.addAbility(betorAbility);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BetorKinToAll(final BetorKinToAll card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetorKinToAll copy() {
|
||||||
|
return new BetorKinToAll(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BetorKinToAllCondition implements Condition {
|
||||||
|
instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return ControlledCreaturesToughnessValue.instance.calculate(game, source, null) >= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class BetorKinToAllEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||||
|
|
||||||
|
BetorKinToAllEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
this.staticText = "Then if creatures you control have total toughness 20 or greater, untap each creature you control. Then if creatures you control have total toughness 40 or greater, each opponent loses half their life, rounded up.";
|
||||||
|
}
|
||||||
|
|
||||||
|
private BetorKinToAllEffect(final BetorKinToAllEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetorKinToAllEffect copy() {
|
||||||
|
return new BetorKinToAllEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
if (controller == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sumToughness = ControlledCreaturesToughnessValue.instance.calculate(game, source, null);
|
||||||
|
|
||||||
|
if (sumToughness < 20) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(),
|
||||||
|
game)) {
|
||||||
|
permanent.untap(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sumToughness < 40) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UUID playerId : game.getOpponents(controller.getId())) {
|
||||||
|
Player opponent = game.getPlayer(playerId);
|
||||||
|
if (opponent == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int amount = (int) Math.ceil(opponent.getLife() / 2f);
|
||||||
|
if (amount > 0) {
|
||||||
|
opponent.loseLife(amount, game, source, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ControlledCreaturesToughnessValue implements DynamicValue {
|
||||||
|
instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||||
|
return game
|
||||||
|
.getBattlefield()
|
||||||
|
.getActivePermanents(
|
||||||
|
StaticFilters.FILTER_CONTROLLED_CREATURE,
|
||||||
|
sourceAbility.getControllerId(), sourceAbility, game)
|
||||||
|
.stream()
|
||||||
|
.map(MageObject::getToughness)
|
||||||
|
.mapToInt(MageInt::getValue)
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ControlledCreaturesToughnessValue copy() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return "total toughness of creatures you control";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "X";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,6 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -42,8 +41,10 @@ public final class BighornerRancher extends CardImpl {
|
||||||
|
|
||||||
// Sacrifice Bighorner Rancher: You gain life equal to the greatest toughness among other creatures you control.
|
// Sacrifice Bighorner Rancher: You gain life equal to the greatest toughness among other creatures you control.
|
||||||
this.addAbility(new SimpleActivatedAbility(
|
this.addAbility(new SimpleActivatedAbility(
|
||||||
new GainLifeEffect(GreatestToughnessAmongControlledCreaturesValue.instance).setText("You gain life equal to the greatest toughness among other creatures you control."),
|
new GainLifeEffect(GreatestToughnessAmongControlledCreaturesValue.OTHER)
|
||||||
new SacrificeSourceCost()));
|
.setText("You gain life equal to the greatest toughness among other creatures you control."),
|
||||||
|
new SacrificeSourceCost()
|
||||||
|
).addHint(GreatestToughnessAmongControlledCreaturesValue.OTHER.getHint()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BighornerRancher(final BighornerRancher card) {
|
private BighornerRancher(final BighornerRancher card) {
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ enum BiteDownOnCrimeAdjuster implements CostAdjuster {
|
||||||
private static final OptionalAdditionalCost collectEvidenceCost = CollectEvidenceAbility.makeCost(6);
|
private static final OptionalAdditionalCost collectEvidenceCost = CollectEvidenceAbility.makeCost(6);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void reduceCost(Ability ability, Game game) {
|
||||||
if (CollectedEvidenceCondition.instance.apply(game, ability)
|
if (CollectedEvidenceCondition.instance.apply(game, ability)
|
||||||
|| (game.inCheckPlayableState() && collectEvidenceCost.canPay(ability, null, ability.getControllerId(), game))) {
|
|| (game.inCheckPlayableState() && collectEvidenceCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||||
CardUtil.reduceCost(ability, 2);
|
CardUtil.reduceCost(ability, 2);
|
||||||
|
|
|
||||||
68
Mage.Sets/src/mage/cards/b/BloomvineRegent.java
Normal file
68
Mage.Sets/src/mage/cards/b/BloomvineRegent.java
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
package mage.cards.b;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
|
import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
|
||||||
|
import mage.cards.OmenCard;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.common.FilterBasicLandCard;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.target.Target;
|
||||||
|
import mage.target.common.TargetCardInLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jmlundeen
|
||||||
|
*/
|
||||||
|
public final class BloomvineRegent extends OmenCard {
|
||||||
|
|
||||||
|
private static final FilterCard filter = new FilterCard("basic Forest cards");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(SubType.FOREST.getPredicate());
|
||||||
|
filter.add(SuperType.BASIC.getPredicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BloomvineRegent(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{3}{G}{G}", "Claim Territory", "{2}{G}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(4);
|
||||||
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// Whenever this creature or another Dragon you control enters, you gain 3 life.
|
||||||
|
this.addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility(
|
||||||
|
new GainLifeEffect(3),
|
||||||
|
new FilterCreaturePermanent(SubType.DRAGON, "Dragon"),
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
));
|
||||||
|
|
||||||
|
// Claim Territory
|
||||||
|
// Search your library for up to two basic Forest cards, reveal them, put one onto the battlefield tapped and the other into your hand, then shuffle. (Also shuffle this card.)
|
||||||
|
TargetCardInLibrary target = new TargetCardInLibrary(0, 2, filter);
|
||||||
|
this.getSpellCard().getSpellAbility().addEffect(new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(target, 1));
|
||||||
|
this.finalizeOmen();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BloomvineRegent(final BloomvineRegent card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BloomvineRegent copy() {
|
||||||
|
return new BloomvineRegent(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ public final class BodyOfKnowledge extends CardImpl {
|
||||||
this.addAbility(new SimpleStaticAbility(
|
this.addAbility(new SimpleStaticAbility(
|
||||||
Zone.ALL,
|
Zone.ALL,
|
||||||
new SetBasePowerToughnessSourceEffect(
|
new SetBasePowerToughnessSourceEffect(
|
||||||
CardsInControllerHandCount.instance
|
CardsInControllerHandCount.ANY
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
63
Mage.Sets/src/mage/cards/b/BoneDevourer.java
Normal file
63
Mage.Sets/src/mage/cards/b/BoneDevourer.java
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
package mage.cards.b;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||||
|
import mage.abilities.common.EntersBattlefieldAbility;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||||
|
import mage.abilities.dynamicvalue.common.CreaturesDiedThisTurnCount;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.abilities.hint.common.CreaturesDiedThisTurnHint;
|
||||||
|
import mage.abilities.keyword.FlashAbility;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
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 BoneDevourer extends CardImpl {
|
||||||
|
|
||||||
|
private static final DynamicValue xValue = new CountersSourceCount(null);
|
||||||
|
|
||||||
|
public BoneDevourer(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
|
// Flash
|
||||||
|
this.addAbility(FlashAbility.getInstance());
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// This creature enters with a number of +1/+1 counters on it equal to the number of creatures that died this turn.
|
||||||
|
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(
|
||||||
|
CounterType.P1P1.createInstance(), CreaturesDiedThisTurnCount.instance, false
|
||||||
|
), "with a number of +1/+1 counters on it equal to the number of creatures that died this turn").addHint(CreaturesDiedThisTurnHint.instance));
|
||||||
|
|
||||||
|
// When this creature dies, you draw X cards and you lose X life, where X is the number of +1/+1 counters on it.
|
||||||
|
Ability ability = new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(xValue).setText("you draw X cards"));
|
||||||
|
ability.addEffect(new LoseLifeSourceControllerEffect(xValue));
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BoneDevourer(final BoneDevourer card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoneDevourer copy() {
|
||||||
|
return new BoneDevourer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -52,7 +52,7 @@ public final class BrightcapBadger extends AdventureCard {
|
||||||
// Fungus Frolic
|
// Fungus Frolic
|
||||||
// Create two 1/1 green Saproling creature tokens.
|
// Create two 1/1 green Saproling creature tokens.
|
||||||
this.getSpellCard().getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), 2));
|
this.getSpellCard().getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), 2));
|
||||||
this.getSpellCard().finalizeAdventure();
|
this.finalizeAdventure();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BrightcapBadger(final BrightcapBadger card) {
|
private BrightcapBadger(final BrightcapBadger card) {
|
||||||
|
|
|
||||||
76
Mage.Sets/src/mage/cards/b/BroodcallerScourge.java
Normal file
76
Mage.Sets/src/mage/cards/b/BroodcallerScourge.java
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
package mage.cards.b;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.OneOrMoreDamagePlayerTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.common.FilterPermanentCard;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class BroodcallerScourge extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCard filter
|
||||||
|
= new FilterPermanentCard("a permanent card with mana value less than or equal to that damage");
|
||||||
|
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent(SubType.DRAGON, "Dragons");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(BroodcallerScourgePredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BroodcallerScourge(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(5);
|
||||||
|
this.toughness = new MageInt(7);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// Whenever one or more Dragons you control deal combat damage to a player, you may put a permanent card with mana value less than or equal to that damage from your hand onto the battlefield.
|
||||||
|
this.addAbility(new OneOrMoreDamagePlayerTriggeredAbility(
|
||||||
|
new PutCardFromHandOntoBattlefieldEffect(filter),
|
||||||
|
filter2, true, true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BroodcallerScourge(final BroodcallerScourge card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BroodcallerScourge copy() {
|
||||||
|
return new BroodcallerScourge(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BroodcallerScourgePredicate implements ObjectSourcePlayerPredicate<Card> {
|
||||||
|
instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(ObjectSourcePlayer<Card> input, Game game) {
|
||||||
|
return input
|
||||||
|
.getObject()
|
||||||
|
.getManaValue()
|
||||||
|
<= CardUtil
|
||||||
|
.getEffectValueFromAbility(
|
||||||
|
input.getSource(), "damage",
|
||||||
|
Integer.class, 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -59,7 +59,7 @@ enum CallerOfTheHuntAdjuster implements CostAdjuster {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void prepareCost(Ability ability, Game game) {
|
||||||
if (game.inCheckPlayableState()) {
|
if (game.inCheckPlayableState()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -103,6 +103,7 @@ enum CallerOfTheHuntAdjuster implements CostAdjuster {
|
||||||
game.getState().setValue(sourceObject.getId() + "_type", maxSubType);
|
game.getState().setValue(sourceObject.getId() + "_type", maxSubType);
|
||||||
} else {
|
} else {
|
||||||
// human choose
|
// human choose
|
||||||
|
// TODO: need early target cost instead dialog here
|
||||||
Effect effect = new ChooseCreatureTypeEffect(Outcome.Benefit);
|
Effect effect = new ChooseCreatureTypeEffect(Outcome.Benefit);
|
||||||
effect.apply(game, ability);
|
effect.apply(game, ability);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
83
Mage.Sets/src/mage/cards/c/CanopyGargantuan.java
Normal file
83
Mage.Sets/src/mage/cards/c/CanopyGargantuan.java
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
package mage.cards.c;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.WardAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
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 java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class CanopyGargantuan extends CardImpl {
|
||||||
|
|
||||||
|
public CanopyGargantuan(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(7);
|
||||||
|
this.toughness = new MageInt(7);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// Ward {2}
|
||||||
|
this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}")));
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, put a number of +1/+1 counters on each other creature you control equal to that creature's toughness.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CanopyGargantuanEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CanopyGargantuan(final CanopyGargantuan card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CanopyGargantuan copy() {
|
||||||
|
return new CanopyGargantuan(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CanopyGargantuanEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
CanopyGargantuanEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "put a number of +1/+1 counters on each other creature you control equal to that creature's toughness";
|
||||||
|
}
|
||||||
|
|
||||||
|
private CanopyGargantuanEffect(final CanopyGargantuanEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CanopyGargantuanEffect copy() {
|
||||||
|
return new CanopyGargantuanEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||||
|
StaticFilters.FILTER_OTHER_CONTROLLED_CREATURE,
|
||||||
|
source.getControllerId(), source, game
|
||||||
|
)) {
|
||||||
|
int toughness = permanent.getToughness().getValue();
|
||||||
|
if (toughness > 0) {
|
||||||
|
permanent.addCounters(CounterType.P1P1.createInstance(toughness), source, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.costs.CostImpl;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.Cost;
|
import mage.abilities.costs.Cost;
|
||||||
|
|
@ -130,7 +131,7 @@ enum CaptainAmericaFirstAvengerValue implements DynamicValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CaptainAmericaFirstAvengerUnattachCost extends EarlyTargetCost {
|
class CaptainAmericaFirstAvengerUnattachCost extends CostImpl implements EarlyTargetCost {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterEquipmentPermanent("equipment attached to this creature");
|
private static final FilterPermanent filter = new FilterEquipmentPermanent("equipment attached to this creature");
|
||||||
private static final FilterPermanent subfilter = new FilterControlledPermanent("{this}");
|
private static final FilterPermanent subfilter = new FilterControlledPermanent("{this}");
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public final class CastleLocthwain extends CardImpl {
|
||||||
Ability ability = new SimpleActivatedAbility(
|
Ability ability = new SimpleActivatedAbility(
|
||||||
new DrawCardSourceControllerEffect(1).setText("draw a card,"), new ManaCostsImpl<>("{1}{B}{B}")
|
new DrawCardSourceControllerEffect(1).setText("draw a card,"), new ManaCostsImpl<>("{1}{B}{B}")
|
||||||
);
|
);
|
||||||
ability.addEffect(new LoseLifeSourceControllerEffect(CardsInControllerHandCount.instance)
|
ability.addEffect(new LoseLifeSourceControllerEffect(CardsInControllerHandCount.ANY)
|
||||||
.setText("then you lose life equal to the number of cards in your hand"));
|
.setText("then you lose life equal to the number of cards in your hand"));
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ public final class ChanneledForce extends CardImpl {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{R}");
|
||||||
|
|
||||||
// As an additional cost to cast this spell, discard X cards.
|
// As an additional cost to cast this spell, discard X cards.
|
||||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS));
|
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
|
||||||
|
|
||||||
// Target player draws X cards. Channeled Force deals X damage to up to one target creature or planeswalker.
|
// Target player draws X cards. Channeled Force deals X damage to up to one target creature or planeswalker.
|
||||||
this.getSpellAbility().addEffect(new ChanneledForceEffect());
|
this.getSpellAbility().addEffect(new ChanneledForceEffect());
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public final class ChitinGravestalker extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final DynamicValue xValue = new CardsInControllerGraveyardCount(filter);
|
private static final DynamicValue xValue = new CardsInControllerGraveyardCount(filter);
|
||||||
private static final Hint hint = new ValueHint("Instant and sorcery card in your graveyard", xValue);
|
private static final Hint hint = new ValueHint("Artifact and/or creature cards in your graveyard", xValue);
|
||||||
|
|
||||||
public ChitinGravestalker(UUID ownerId, CardSetInfo setInfo) {
|
public ChitinGravestalker(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}");
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,20 @@
|
||||||
|
|
||||||
package mage.cards.c;
|
package mage.cards.c;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||||
import mage.abilities.common.EntersBattlefieldAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.ModeChoiceSourceCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.ChooseModeEffect;
|
import mage.abilities.effects.common.ChooseModeEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAnchorWordAbilitySourceEffect;
|
||||||
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.ModeChoice;
|
||||||
import mage.constants.TargetController;
|
import mage.constants.TargetController;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.Predicate;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
|
@ -28,36 +25,29 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class CitadelSiege extends CardImpl {
|
public final class CitadelSiege extends CardImpl {
|
||||||
|
|
||||||
private static final String ruleTrigger1 = "&bull Khans — At the beginning of combat on your turn, put two +1/+1 counters on target creature you control.";
|
|
||||||
private static final String ruleTrigger2 = "&bull Dragons — At the beginning of combat on each opponent's turn, tap target creature that player controls.";
|
|
||||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by the active player");
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by the active player");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(CitadelSiegePredicate.instance);
|
filter.add(TargetController.ACTIVE.getControllerPredicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public CitadelSiege(UUID ownerId, CardSetInfo setInfo) {
|
public CitadelSiege(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
|
||||||
|
|
||||||
// As Citadel Siege enters the battlefield, choose Khans or Dragons.
|
// As Citadel Siege enters the battlefield, choose Khans or Dragons.
|
||||||
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null,
|
this.addAbility(new AsEntersBattlefieldAbility(new ChooseModeEffect(ModeChoice.KHANS, ModeChoice.DRAGONS)));
|
||||||
"As {this} enters, choose Khans or Dragons.", ""));
|
|
||||||
|
|
||||||
// * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control.
|
// * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control.
|
||||||
Ability ability = new ConditionalTriggeredAbility(
|
Ability ability = new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)));
|
||||||
new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2))),
|
|
||||||
new ModeChoiceSourceCondition("Khans"),
|
|
||||||
ruleTrigger1);
|
|
||||||
ability.addTarget(new TargetControlledCreaturePermanent());
|
ability.addTarget(new TargetControlledCreaturePermanent());
|
||||||
this.addAbility(ability);
|
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.KHANS)));
|
||||||
|
|
||||||
// * Dragons - At the beginning of combat on each opponent's turn, tap target creature that player controls.
|
// * Dragons - At the beginning of combat on each opponent's turn, tap target creature that player controls.
|
||||||
ability = new ConditionalTriggeredAbility(
|
ability = new BeginningOfCombatTriggeredAbility(
|
||||||
new BeginningOfCombatTriggeredAbility(TargetController.OPPONENT, new TapTargetEffect(), false),
|
TargetController.OPPONENT, new TapTargetEffect("tap target creature that player controls"), false
|
||||||
new ModeChoiceSourceCondition("Dragons"),
|
);
|
||||||
ruleTrigger2);
|
|
||||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||||
this.addAbility(ability);
|
this.addAbility(new SimpleStaticAbility(new GainAnchorWordAbilitySourceEffect(ability, ModeChoice.DRAGONS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private CitadelSiege(final CitadelSiege card) {
|
private CitadelSiege(final CitadelSiege card) {
|
||||||
|
|
@ -69,12 +59,3 @@ public final class CitadelSiege extends CardImpl {
|
||||||
return new CitadelSiege(this);
|
return new CitadelSiege(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CitadelSiegePredicate implements Predicate<Permanent> {
|
|
||||||
instance;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Permanent input, Game game) {
|
|
||||||
return input.getControllerId().equals(game.getActivePlayerId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
72
Mage.Sets/src/mage/cards/c/ClarionConqueror.java
Normal file
72
Mage.Sets/src/mage/cards/c/ClarionConqueror.java
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
package mage.cards.c;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.effects.RestrictionEffect;
|
||||||
|
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.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class ClarionConqueror extends CardImpl {
|
||||||
|
|
||||||
|
public ClarionConqueror(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// Activated abilities of artifacts, creatures, and planeswalkers can't be activated.
|
||||||
|
this.addAbility(new SimpleStaticAbility(new ClarionConquerorEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClarionConqueror(final ClarionConqueror card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClarionConqueror copy() {
|
||||||
|
return new ClarionConqueror(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClarionConquerorEffect extends RestrictionEffect {
|
||||||
|
|
||||||
|
ClarionConquerorEffect() {
|
||||||
|
super(Duration.WhileOnBattlefield);
|
||||||
|
staticText = "activated abilities of artifacts, creatures, and planeswalkers can't be activated";
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClarionConquerorEffect(final ClarionConquerorEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||||
|
return permanent.isArtifact(game) || permanent.isCreature(game) || permanent.isPlaneswalker(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUseActivatedAbilities(Permanent permanent, Ability source, Game game, boolean canUseChooseDialogs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClarionConquerorEffect copy() {
|
||||||
|
return new ClarionConquerorEffect(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
164
Mage.Sets/src/mage/cards/c/ColossalGraveReaver.java
Normal file
164
Mage.Sets/src/mage/cards/c/ColossalGraveReaver.java
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
package mage.cards.c;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.BatchTriggeredAbility;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.MillCardsControllerEffect;
|
||||||
|
import mage.cards.*;
|
||||||
|
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.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.events.ZoneChangeBatchEvent;
|
||||||
|
import mage.game.events.ZoneChangeEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetCard;
|
||||||
|
import mage.target.targetpointer.FixedTargets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Grath
|
||||||
|
*/
|
||||||
|
public final class ColossalGraveReaver extends CardImpl {
|
||||||
|
|
||||||
|
public ColossalGraveReaver(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}{G}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(7);
|
||||||
|
this.toughness = new MageInt(6);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// Whenever this creature enters or attacks, mill three cards.
|
||||||
|
this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new MillCardsControllerEffect(3)));
|
||||||
|
|
||||||
|
// Whenever one or more creature cards are put into your graveyard from your library, put one of them onto the battlefield.
|
||||||
|
this.addAbility(new ColossalGraveReaverTriggeredAbility());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColossalGraveReaver(final ColossalGraveReaver card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColossalGraveReaver copy() {
|
||||||
|
return new ColossalGraveReaver(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColossalGraveReaverEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private static final FilterCard defaultFilter = new FilterCard("creature to return to battlefield");
|
||||||
|
|
||||||
|
public ColossalGraveReaverEffect() {
|
||||||
|
super(Outcome.PutCreatureInPlay);
|
||||||
|
staticText = "put one of them onto the battlefield";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ColossalGraveReaverEffect(final ColossalGraveReaverEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColossalGraveReaverEffect copy() {
|
||||||
|
return new ColossalGraveReaverEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
if (controller != null) {
|
||||||
|
Cards cardsToChooseFrom = new CardsImpl();
|
||||||
|
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
|
||||||
|
Card card = game.getCard(targetId);
|
||||||
|
if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) {
|
||||||
|
cardsToChooseFrom.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<Card> cardsToMove;
|
||||||
|
switch (cardsToChooseFrom.size()) {
|
||||||
|
case 0:
|
||||||
|
return false;
|
||||||
|
case 1:
|
||||||
|
cardsToMove = new HashSet<>(cardsToChooseFrom.getCards(game));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cardsToMove = new HashSet<>();
|
||||||
|
TargetCard target = new TargetCard(1, 1, Zone.ALL, defaultFilter);
|
||||||
|
target.withNotTarget(true);
|
||||||
|
controller.choose(Outcome.PlayForFree, cardsToChooseFrom, target, source, game);
|
||||||
|
cardsToMove.add(cardsToChooseFrom.get(target.getFirstTarget(), game));
|
||||||
|
|
||||||
|
}
|
||||||
|
controller.moveCards(cardsToMove, Zone.BATTLEFIELD, source, game, false, false, false, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColossalGraveReaverTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility<ZoneChangeEvent> {
|
||||||
|
|
||||||
|
ColossalGraveReaverTriggeredAbility() {
|
||||||
|
super(Zone.BATTLEFIELD, new ColossalGraveReaverEffect());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColossalGraveReaverTriggeredAbility(final ColossalGraveReaverTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColossalGraveReaverTriggeredAbility copy() {
|
||||||
|
return new ColossalGraveReaverTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEvent(ZoneChangeEvent event, Game game) {
|
||||||
|
if (event.getFromZone() != Zone.LIBRARY || event.getToZone() != Zone.GRAVEYARD) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Card card = game.getCard(event.getTargetId());
|
||||||
|
return card != null && card.isCreature(game) && card.isOwnedBy(getControllerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
Set<Card> set = getFilteredEvents((ZoneChangeBatchEvent) event, game)
|
||||||
|
.stream()
|
||||||
|
.map(ZoneChangeEvent::getTargetId)
|
||||||
|
.map(game::getCard)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.getEffects().setTargetPointer(new FixedTargets(set, game));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "Whenever one or more creature cards are put into your graveyard " +
|
||||||
|
"from your library, put one of them onto the battlefield tapped.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -72,7 +72,7 @@ enum CrownOfGondorAdjuster implements CostAdjuster {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void reduceCost(Ability ability, Game game) {
|
||||||
if (MonarchIsSourceControllerCondition.instance.apply(game, ability)) {
|
if (MonarchIsSourceControllerCondition.instance.apply(game, ability)) {
|
||||||
CardUtil.reduceCost(ability, 3);
|
CardUtil.reduceCost(ability, 3);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.constants.TargetController;
|
import mage.constants.TargetController;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
|
|
@ -59,7 +58,7 @@ public final class DamiaSageOfStone extends CardImpl {
|
||||||
class DamiaSageOfStoneTriggeredAbility extends BeginningOfUpkeepTriggeredAbility {
|
class DamiaSageOfStoneTriggeredAbility extends BeginningOfUpkeepTriggeredAbility {
|
||||||
|
|
||||||
DamiaSageOfStoneTriggeredAbility() {
|
DamiaSageOfStoneTriggeredAbility() {
|
||||||
super(TargetController.YOU, new DrawCardSourceControllerEffect(new IntPlusDynamicValue(7, new MultipliedValue(CardsInControllerHandCount.instance, -1))), false);
|
super(TargetController.YOU, new DrawCardSourceControllerEffect(new IntPlusDynamicValue(7, new MultipliedValue(CardsInControllerHandCount.ANY, -1))), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DamiaSageOfStoneTriggeredAbility(final DamiaSageOfStoneTriggeredAbility ability) {
|
private DamiaSageOfStoneTriggeredAbility(final DamiaSageOfStoneTriggeredAbility ability) {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ enum IsBeingCastFromHandCondition implements Condition {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
MageObject object = game.getObject(source);
|
MageObject object = game.getObject(source);
|
||||||
if (object instanceof SplitCardHalf || object instanceof AdventureCardSpell || object instanceof ModalDoubleFacedCardHalf) {
|
if (object instanceof SplitCardHalf || object instanceof SpellOptionCard || object instanceof ModalDoubleFacedCardHalf) {
|
||||||
UUID mainCardId = ((Card) object).getMainCard().getId();
|
UUID mainCardId = ((Card) object).getMainCard().getId();
|
||||||
object = game.getObject(mainCardId);
|
object = game.getObject(mainCardId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
83
Mage.Sets/src/mage/cards/d/DeathBegetsLife.java
Normal file
83
Mage.Sets/src/mage/cards/d/DeathBegetsLife.java
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
package mage.cards.d;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
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.FilterPermanent;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author androosss
|
||||||
|
*/
|
||||||
|
public final class DeathBegetsLife extends CardImpl {
|
||||||
|
|
||||||
|
public DeathBegetsLife(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[] { CardType.SORCERY }, "{5}{B}{G}{U}");
|
||||||
|
|
||||||
|
// Destroy all creatures and enchantments. Draw a card for each permanent
|
||||||
|
// destroyed this way.
|
||||||
|
this.getSpellAbility().addEffect(new DeathBegetsLifeEffect());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeathBegetsLife(final DeathBegetsLife card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeathBegetsLife copy() {
|
||||||
|
return new DeathBegetsLife(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeathBegetsLifeEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter = new FilterPermanent("creature or enchantment");
|
||||||
|
static {
|
||||||
|
filter.add(Predicates.or(
|
||||||
|
CardType.CREATURE.getPredicate(),
|
||||||
|
CardType.ENCHANTMENT.getPredicate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
DeathBegetsLifeEffect() {
|
||||||
|
super(Outcome.DestroyPermanent);
|
||||||
|
this.staticText = "Destroy all creatures and enchantments. Draw a card for each permanent destroyed this way";
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeathBegetsLifeEffect(final DeathBegetsLifeEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeathBegetsLifeEffect copy() {
|
||||||
|
return new DeathBegetsLifeEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
if (controller != null) {
|
||||||
|
int destroyedPermanent = 0;
|
||||||
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter,
|
||||||
|
controller.getId(), game)) {
|
||||||
|
if (permanent.destroy(source, game)) {
|
||||||
|
destroyedPermanent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (destroyedPermanent > 0) {
|
||||||
|
game.processAction();
|
||||||
|
controller.drawCards(destroyedPermanent, source, game);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
74
Mage.Sets/src/mage/cards/d/DeceptiveFrostkite.java
Normal file
74
Mage.Sets/src/mage/cards/d/DeceptiveFrostkite.java
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
package mage.cards.d;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||||
|
import mage.abilities.effects.common.CopyPermanentEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.ComparisonType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.predicate.mageobject.PowerPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.util.functions.CopyApplier;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class DeceptiveFrostkite extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter
|
||||||
|
= new FilterControlledCreaturePermanent("a creature you control with power 4 or greater");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final CopyApplier applier = new CopyApplier() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
|
||||||
|
blueprint.addSubType(SubType.DRAGON);
|
||||||
|
blueprint.getAbilities().add(FlyingAbility.getInstance());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public DeceptiveFrostkite(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(1);
|
||||||
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// You may have this creature enter as a copy of a creature you control with power 4 or greater, except it's a Dragon in addition to its other types and it has flying.
|
||||||
|
this.addAbility(new SimpleStaticAbility(
|
||||||
|
Zone.ALL,
|
||||||
|
new EntersBattlefieldEffect(
|
||||||
|
new CopyPermanentEffect(filter, applier), "you may have this creature enter " +
|
||||||
|
"as a copy of a creature you control with power 4 or greater, " +
|
||||||
|
"except it's a Dragon in addition to its other types and it has flying", true
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeceptiveFrostkite(final DeceptiveFrostkite card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeceptiveFrostkite copy() {
|
||||||
|
return new DeceptiveFrostkite(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -62,7 +62,7 @@ enum DeepwoodDenizenAdjuster implements CostAdjuster {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void adjustCosts(Ability ability, Game game) {
|
public void reduceCost(Ability ability, Game game) {
|
||||||
CardUtil.reduceCost(ability, DeepwoodDenizenValue.instance.calculate(game, ability, null));
|
CardUtil.reduceCost(ability, DeepwoodDenizenValue.instance.calculate(game, ability, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.PreventionEffectData;
|
import mage.abilities.effects.PreventionEffectData;
|
||||||
import mage.abilities.effects.PreventionEffectImpl;
|
import mage.abilities.effects.PreventionEffectImpl;
|
||||||
|
|
@ -11,8 +10,6 @@ import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.game.stack.Spell;
|
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetSource;
|
import mage.target.TargetSource;
|
||||||
|
|
||||||
|
|
@ -44,9 +41,11 @@ class DeflectingPalmEffect extends PreventionEffectImpl {
|
||||||
|
|
||||||
private final TargetSource target;
|
private final TargetSource target;
|
||||||
|
|
||||||
public DeflectingPalmEffect() {
|
DeflectingPalmEffect() {
|
||||||
super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false);
|
super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false);
|
||||||
this.staticText = "The next time a source of your choice would deal damage to you this turn, prevent that damage. If damage is prevented this way, {this} deals that much damage to that source's controller";
|
this.staticText = "the next time a source of your choice would deal damage to you this turn, " +
|
||||||
|
"prevent that damage. If damage is prevented this way, " +
|
||||||
|
"{this} deals that much damage to that source's controller";
|
||||||
this.target = new TargetSource();
|
this.target = new TargetSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,31 +70,23 @@ class DeflectingPalmEffect extends PreventionEffectImpl {
|
||||||
PreventionEffectData preventionData = preventDamageAction(event, source, game);
|
PreventionEffectData preventionData = preventDamageAction(event, source, game);
|
||||||
this.used = true;
|
this.used = true;
|
||||||
this.discard(); // only one use
|
this.discard(); // only one use
|
||||||
if (preventionData.getPreventedDamage() > 0) {
|
if (preventionData.getPreventedDamage() < 1) {
|
||||||
MageObject damageDealingObject = game.getObject(target.getFirstTarget());
|
return true;
|
||||||
UUID objectControllerId = null;
|
|
||||||
if (damageDealingObject instanceof Permanent) {
|
|
||||||
objectControllerId = ((Permanent) damageDealingObject).getControllerId();
|
|
||||||
} else if (damageDealingObject instanceof Ability) {
|
|
||||||
objectControllerId = ((Ability) damageDealingObject).getControllerId();
|
|
||||||
} else if (damageDealingObject instanceof Spell) {
|
|
||||||
objectControllerId = ((Spell) damageDealingObject).getControllerId();
|
|
||||||
}
|
|
||||||
if (objectControllerId != null) {
|
|
||||||
Player objectController = game.getPlayer(objectControllerId);
|
|
||||||
if (objectController != null) {
|
|
||||||
objectController.damage(preventionData.getPreventedDamage(), source.getSourceId(), source, game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
UUID objectControllerId = game.getControllerId(target.getFirstTarget());
|
||||||
|
Player objectController = game.getPlayer(objectControllerId);
|
||||||
|
if (objectController == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
objectController.damage(preventionData.getPreventedDamage(), source.getSourceId(), source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
if (!this.used && super.applies(event, source, game)) {
|
return !this.used
|
||||||
return event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget());
|
&& super.applies(event, source, game)
|
||||||
}
|
&& event.getTargetId().equals(source.getControllerId())
|
||||||
return false;
|
&& event.getSourceId().equals(target.getFirstTarget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ class DelayEffect extends OneShotEffect {
|
||||||
if (controller != null && spell != null) {
|
if (controller != null && spell != null) {
|
||||||
Effect effect = new CounterTargetWithReplacementEffect(PutCards.EXILED);
|
Effect effect = new CounterTargetWithReplacementEffect(PutCards.EXILED);
|
||||||
effect.setTargetPointer(this.getTargetPointer().copy());
|
effect.setTargetPointer(this.getTargetPointer().copy());
|
||||||
Card card = game.getCard(spell.getSourceId());
|
Card card = spell.getMainCard();
|
||||||
if (card != null && effect.apply(game, source) && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
if (card != null && effect.apply(game, source) && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
||||||
boolean hasSuspend = card.getAbilities(game).containsClass(SuspendAbility.class);
|
boolean hasSuspend = card.getAbilities(game).containsClass(SuspendAbility.class);
|
||||||
UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game);
|
UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class DemonicLore extends CardImpl {
|
public final class DemonicLore extends CardImpl {
|
||||||
|
|
||||||
private static final DynamicValue xValue = new MultipliedValue(CardsInControllerHandCount.instance, 2);
|
private static final DynamicValue xValue = new MultipliedValue(CardsInControllerHandCount.ANY, 2);
|
||||||
|
|
||||||
public DemonicLore(UUID ownerId, CardSetInfo setInfo) {
|
public DemonicLore(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -28,7 +27,7 @@ public final class DescendantOfSoramaro extends CardImpl {
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
// {1}{U}: Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order.
|
// {1}{U}: Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order.
|
||||||
Effect effect = new LookLibraryControllerEffect(CardsInControllerHandCount.instance);
|
Effect effect = new LookLibraryControllerEffect(CardsInControllerHandCount.ANY);
|
||||||
effect.setText("Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order");
|
effect.setText("Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order");
|
||||||
this.addAbility(new SimpleActivatedAbility(
|
this.addAbility(new SimpleActivatedAbility(
|
||||||
effect, new ManaCostsImpl<>("{1}{U}")));
|
effect, new ManaCostsImpl<>("{1}{U}")));
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import mage.abilities.costs.Cost;
|
||||||
import mage.abilities.costs.VariableCostImpl;
|
import mage.abilities.costs.VariableCostImpl;
|
||||||
import mage.abilities.costs.VariableCostType;
|
import mage.abilities.costs.VariableCostType;
|
||||||
import mage.abilities.costs.common.DiscardTargetCost;
|
import mage.abilities.costs.common.DiscardTargetCost;
|
||||||
|
import mage.abilities.costs.common.DiscardXTargetCost;
|
||||||
|
import mage.abilities.costs.costadjusters.DiscardXCardsCostAdjuster;
|
||||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||||
import mage.abilities.effects.common.DamageAllEffect;
|
import mage.abilities.effects.common.DamageAllEffect;
|
||||||
import mage.abilities.effects.common.SacrificeAllEffect;
|
import mage.abilities.effects.common.SacrificeAllEffect;
|
||||||
|
|
@ -12,6 +14,7 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledLandPermanent;
|
import mage.filter.common.FilterControlledLandPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
@ -28,8 +31,8 @@ public final class DevastatingDreams extends CardImpl {
|
||||||
public DevastatingDreams(UUID ownerId, CardSetInfo setInfo) {
|
public DevastatingDreams(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}{R}");
|
||||||
|
|
||||||
// As an additional cost to cast Devastating Dreams, discard X cards at random.
|
// As an additional cost to cast this spell, discard X cards at random.
|
||||||
this.getSpellAbility().addCost(new DevastatingDreamsAdditionalCost());
|
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true).withRandom());
|
||||||
|
|
||||||
// Each player sacrifices X lands.
|
// Each player sacrifices X lands.
|
||||||
this.getSpellAbility().addEffect(new SacrificeAllEffect(GetXValue.instance, new FilterControlledLandPermanent("lands")));
|
this.getSpellAbility().addEffect(new SacrificeAllEffect(GetXValue.instance, new FilterControlledLandPermanent("lands")));
|
||||||
|
|
|
||||||
52
Mage.Sets/src/mage/cards/d/DirgurIslandDragon.java
Normal file
52
Mage.Sets/src/mage/cards/d/DirgurIslandDragon.java
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
package mage.cards.d;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.WardAbility;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.cards.OmenCard;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jmlundeen
|
||||||
|
*/
|
||||||
|
public final class DirgurIslandDragon extends OmenCard {
|
||||||
|
|
||||||
|
public DirgurIslandDragon(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{5}{U}", "Skimming Strike", "{1}{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.power = new MageInt(4);
|
||||||
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// Ward {2}
|
||||||
|
this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}")));
|
||||||
|
|
||||||
|
// Skimming Strike
|
||||||
|
// Tap up to one target creature. Draw a card.
|
||||||
|
this.getSpellCard().getSpellAbility().addEffect(new TapTargetEffect());
|
||||||
|
this.getSpellCard().getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
|
||||||
|
this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1));
|
||||||
|
this.finalizeOmen();
|
||||||
|
}
|
||||||
|
|
||||||
|
private DirgurIslandDragon(final DirgurIslandDragon card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DirgurIslandDragon copy() {
|
||||||
|
return new DirgurIslandDragon(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue