mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
Merge branch 'master' into refactor/clean-filter-logic
This commit is contained in:
commit
836caec201
499 changed files with 8221 additions and 3606 deletions
|
|
@ -4,8 +4,12 @@ import mage.MageObject;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.client.util.GUISizeHelper;
|
import mage.client.util.GUISizeHelper;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
@ -16,22 +20,73 @@ import java.util.stream.Stream;
|
||||||
* <p>
|
* <p>
|
||||||
* Support:
|
* Support:
|
||||||
* - [x] game changers
|
* - [x] game changers
|
||||||
* - [ ] infinite combos
|
* - [x] infinite combos
|
||||||
* - [x] mass land destruction
|
* - [x] mass land destruction
|
||||||
* - [x] extra turns
|
* - [x] extra turns
|
||||||
* - [x] tutors
|
* - [x] tutors
|
||||||
|
* Features:
|
||||||
|
* - [x] find possible bracket level of the deck
|
||||||
|
* - [x] find affected cards by checking group
|
||||||
|
* - [x] can auto-generate infinite combos list, see verify test downloadAndPrepareCommanderBracketsData
|
||||||
|
* - [ ] TODO: tests
|
||||||
|
* - [ ] TODO: table - players brackets level disclose settings
|
||||||
|
* - [ ] TODO: generate - convert card name to xmage format and assert on bad names (ascii only)
|
||||||
*
|
*
|
||||||
* @author JayDi85
|
* @author JayDi85
|
||||||
*/
|
*/
|
||||||
public class BracketLegalityLabel extends LegalityLabel {
|
public class BracketLegalityLabel extends LegalityLabel {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(BracketLegalityLabel.class);
|
||||||
|
|
||||||
private static final String GROUP_GAME_CHANGES = "Game Changers";
|
private static final String GROUP_GAME_CHANGES = "Game Changers";
|
||||||
private static final String GROUP_INFINITE_COMBOS = "Infinite Combos (unsupported)";
|
private static final String GROUP_INFINITE_COMBOS = "Infinite Combos";
|
||||||
private static final String GROUP_MASS_LAND_DESTRUCTION = "Mass Land Destruction";
|
private static final String GROUP_MASS_LAND_DESTRUCTION = "Mass Land Destruction";
|
||||||
private static final String GROUP_EXTRA_TURN = "Extra Turns";
|
private static final String GROUP_EXTRA_TURN = "Extra Turns";
|
||||||
private static final String GROUP_TUTORS = "Tutors";
|
private static final String GROUP_TUTORS = "Tutors";
|
||||||
|
|
||||||
private final BracketLevel level;
|
private static final Map<String, List<Integer>> MAX_GROUP_LIMITS = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
// 1
|
||||||
|
// No cards from the Game Changer list.
|
||||||
|
// No intentional two-card infinite combos.
|
||||||
|
// No mass land destruction.
|
||||||
|
// No extra turn cards.
|
||||||
|
// Tutors should be sparse.
|
||||||
|
// 2
|
||||||
|
// No cards from the Game Changer list.
|
||||||
|
// No intentional two-card infinite combos.
|
||||||
|
// No mass land destruction.
|
||||||
|
// Extra turn cards should only appear in low quantities and should not be chained in succession or looped.
|
||||||
|
// Tutors should be sparse.
|
||||||
|
// 3
|
||||||
|
// Up to three (3) cards from the Game Changer list.
|
||||||
|
// No intentional early game two-card infinite combos.
|
||||||
|
// No mass land destruction.
|
||||||
|
// Extra turn cards should only appear in low quantities and should not be chained in succession or looped.
|
||||||
|
// 4
|
||||||
|
// 5
|
||||||
|
// allow any cards
|
||||||
|
|
||||||
|
// cards limits per brackets level, it's ok to use 99 as max
|
||||||
|
// group - levels 0, 1, 2, 3, 4, 5
|
||||||
|
MAX_GROUP_LIMITS.put(GROUP_GAME_CHANGES,
|
||||||
|
Arrays.asList(0, 0, 0, 3, 99, 99));
|
||||||
|
MAX_GROUP_LIMITS.put(GROUP_INFINITE_COMBOS,
|
||||||
|
Arrays.asList(0, 0, 0, 0, 99, 99));
|
||||||
|
MAX_GROUP_LIMITS.put(GROUP_MASS_LAND_DESTRUCTION,
|
||||||
|
Arrays.asList(0, 0, 0, 0, 99, 99));
|
||||||
|
MAX_GROUP_LIMITS.put(GROUP_EXTRA_TURN,
|
||||||
|
Arrays.asList(0, 0, 0, 3, 99, 99));
|
||||||
|
MAX_GROUP_LIMITS.put(GROUP_TUTORS,
|
||||||
|
Arrays.asList(0, 3, 3, 99, 99, 99));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String RESOURCE_INFINITE_COMBOS = "brackets/infinite-combos.txt";
|
||||||
|
|
||||||
|
private final String fullName;
|
||||||
|
private final String shortName;
|
||||||
|
private final int maxLevel;
|
||||||
|
|
||||||
private final List<String> foundGameChangers = new ArrayList<>();
|
private final List<String> foundGameChangers = new ArrayList<>();
|
||||||
private final List<String> foundInfiniteCombos = new ArrayList<>();
|
private final List<String> foundInfiniteCombos = new ArrayList<>();
|
||||||
|
|
@ -41,28 +96,14 @@ public class BracketLegalityLabel extends LegalityLabel {
|
||||||
|
|
||||||
private final List<String> badCards = new ArrayList<>();
|
private final List<String> badCards = new ArrayList<>();
|
||||||
private final List<String> fullGameChanges = new ArrayList<>();
|
private final List<String> fullGameChanges = new ArrayList<>();
|
||||||
|
private final Set<String> fullInfiniteCombos = new HashSet<>(); // card1@card2, sorted by names, name must be xmage compatible
|
||||||
|
|
||||||
public enum BracketLevel {
|
public BracketLegalityLabel(String fullName, String shortName, int maxLevel) {
|
||||||
BRACKET_1("Bracket 1"),
|
super(shortName, null);
|
||||||
BRACKET_2_3("Bracket 2-3"),
|
this.fullName = fullName;
|
||||||
BRACKET_4_5("Bracket 4-5");
|
this.shortName = shortName;
|
||||||
|
this.maxLevel = maxLevel;
|
||||||
private final String name;
|
setPreferredSize(DIM_PREFERRED_1_OF_5);
|
||||||
|
|
||||||
BracketLevel(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public BracketLegalityLabel(BracketLevel level) {
|
|
||||||
super(level.toString(), null);
|
|
||||||
this.level = level;
|
|
||||||
setPreferredSize(DIM_PREFERRED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -72,49 +113,26 @@ public class BracketLegalityLabel extends LegalityLabel {
|
||||||
|
|
||||||
private void validateBracketLevel() {
|
private void validateBracketLevel() {
|
||||||
this.badCards.clear();
|
this.badCards.clear();
|
||||||
switch (this.level) {
|
|
||||||
case BRACKET_1:
|
if (this.foundGameChangers.size() > getMaxCardsLimit(GROUP_GAME_CHANGES)) {
|
||||||
// No cards from the Game Changer list.
|
this.badCards.addAll(this.foundGameChangers);
|
||||||
// No intentional two-card infinite combos.
|
|
||||||
// No mass land destruction.
|
|
||||||
// No extra turn cards.
|
|
||||||
// Tutors should be sparse.
|
|
||||||
this.badCards.addAll(this.foundGameChangers);
|
|
||||||
this.badCards.addAll(this.foundInfiniteCombos);
|
|
||||||
this.badCards.addAll(this.foundMassLandDestruction);
|
|
||||||
this.badCards.addAll(this.foundExtraTurn);
|
|
||||||
if (this.foundTutors.size() > 3) {
|
|
||||||
this.badCards.addAll(this.foundTutors);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BRACKET_2_3:
|
|
||||||
// 2
|
|
||||||
// No cards from the Game Changer list.
|
|
||||||
// No intentional two-card infinite combos.
|
|
||||||
// No mass land destruction.
|
|
||||||
// Extra turn cards should only appear in low quantities and should not be chained in succession or looped.
|
|
||||||
// Tutors should be sparse.
|
|
||||||
// 3
|
|
||||||
// Up to three (3) cards from the Game Changer list.
|
|
||||||
// No intentional early game two-card infinite combos.
|
|
||||||
// No mass land destruction.
|
|
||||||
// Extra turn cards should only appear in low quantities and should not be chained in succession or looped.
|
|
||||||
if (this.foundGameChangers.size() > 3) {
|
|
||||||
this.badCards.addAll(this.foundGameChangers);
|
|
||||||
}
|
|
||||||
this.badCards.addAll(this.foundInfiniteCombos);
|
|
||||||
this.badCards.addAll(this.foundMassLandDestruction);
|
|
||||||
if (this.foundExtraTurn.size() > 3) {
|
|
||||||
this.badCards.addAll(this.foundExtraTurn);
|
|
||||||
}
|
|
||||||
// this.badCards.addAll(this.foundTutors); // allow any amount
|
|
||||||
break;
|
|
||||||
case BRACKET_4_5:
|
|
||||||
// allow any cards
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unsupported level: " + this.level);
|
|
||||||
}
|
}
|
||||||
|
if (this.foundInfiniteCombos.size() > getMaxCardsLimit(GROUP_INFINITE_COMBOS)) {
|
||||||
|
this.badCards.addAll(this.foundInfiniteCombos);
|
||||||
|
}
|
||||||
|
if (this.foundMassLandDestruction.size() > getMaxCardsLimit(GROUP_MASS_LAND_DESTRUCTION)) {
|
||||||
|
this.badCards.addAll(this.foundMassLandDestruction);
|
||||||
|
}
|
||||||
|
if (this.foundExtraTurn.size() > getMaxCardsLimit(GROUP_EXTRA_TURN)) {
|
||||||
|
this.badCards.addAll(this.foundExtraTurn);
|
||||||
|
}
|
||||||
|
if (this.foundTutors.size() > getMaxCardsLimit(GROUP_TUTORS)) {
|
||||||
|
this.badCards.addAll(this.foundTutors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer getMaxCardsLimit(String groupName) {
|
||||||
|
return MAX_GROUP_LIMITS.get(groupName).get(this.maxLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -122,31 +140,41 @@ public class BracketLegalityLabel extends LegalityLabel {
|
||||||
collectAll(deck);
|
collectAll(deck);
|
||||||
validateBracketLevel();
|
validateBracketLevel();
|
||||||
|
|
||||||
int infoFontSize = Math.round(GUISizeHelper.cardTooltipFont.getSize() * 0.6f);
|
int infoFontHeaderSize = Math.round(GUISizeHelper.cardTooltipFont.getSize() * 1.0f);
|
||||||
|
int infoFontTextSize = Math.round(GUISizeHelper.cardTooltipFont.getSize() * 0.6f);
|
||||||
|
|
||||||
// show all found cards in any use cases
|
// show all found cards in any use cases
|
||||||
Color showColor = this.badCards.isEmpty() ? COLOR_LEGAL : COLOR_NOT_LEGAL;
|
Color showColor = this.badCards.isEmpty() ? COLOR_LEGAL : COLOR_NOT_LEGAL;
|
||||||
|
|
||||||
List<String> showInfo = new ArrayList<>();
|
List<String> showInfo = new ArrayList<>();
|
||||||
if (this.badCards.isEmpty()) {
|
if (this.badCards.isEmpty()) {
|
||||||
showInfo.add("<p>Deck is <span style='color:green;font-weight:bold;'>GOOD</span> for " + this.level + "</p>");
|
showInfo.add(String.format("<span style='font-weight:bold;font-size:%dpx;'><p>Deck is <span style='color:green;'>GOOD</span> for %s</p></span>",
|
||||||
|
infoFontHeaderSize,
|
||||||
|
this.fullName
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
showInfo.add("<p>Deck is <span style='color:#BF544A;font-weight:bold;'>BAD</span> for " + this.level + "</p>");
|
showInfo.add(String.format("<span style='font-weight:bold;font-size:%dpx;'><p>Deck is <span style='color:#BF544A;'>BAD</span> for %s</p></span>",
|
||||||
|
infoFontHeaderSize,
|
||||||
|
this.fullName
|
||||||
|
));
|
||||||
showInfo.add("<p>(click here to select all bad cards)</p>");
|
showInfo.add("<p>(click here to select all bad cards)</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, List<String>> groups = new LinkedHashMap<>();
|
Map<String, List<String>> groups = new LinkedHashMap<>();
|
||||||
groups.put(GROUP_GAME_CHANGES, this.foundGameChangers);
|
groups.put(GROUP_GAME_CHANGES + getStats(GROUP_GAME_CHANGES), this.foundGameChangers);
|
||||||
groups.put(GROUP_INFINITE_COMBOS, this.foundInfiniteCombos);
|
groups.put(GROUP_INFINITE_COMBOS + getStats(GROUP_INFINITE_COMBOS), this.foundInfiniteCombos);
|
||||||
groups.put(GROUP_MASS_LAND_DESTRUCTION, this.foundMassLandDestruction);
|
groups.put(GROUP_MASS_LAND_DESTRUCTION + getStats(GROUP_MASS_LAND_DESTRUCTION), this.foundMassLandDestruction);
|
||||||
groups.put(GROUP_EXTRA_TURN, this.foundExtraTurn);
|
groups.put(GROUP_EXTRA_TURN + getStats(GROUP_EXTRA_TURN), this.foundExtraTurn);
|
||||||
groups.put(GROUP_TUTORS, this.foundTutors);
|
groups.put(GROUP_TUTORS + getStats(GROUP_TUTORS), this.foundTutors);
|
||||||
groups.forEach((group, cards) -> {
|
groups.forEach((group, cards) -> {
|
||||||
showInfo.add("<br>");
|
showInfo.add("<br>");
|
||||||
showInfo.add("<br>");
|
showInfo.add("<span style='font-weight:bold;font-size: " + infoFontTextSize + "px;'>" + group + "</span>");
|
||||||
showInfo.add("<span style='font-weight:bold;'>" + group + ": " + cards.size() + "</span>");
|
if (cards.isEmpty()) {
|
||||||
if (!cards.isEmpty()) {
|
showInfo.add("<ul style=\"font-size: " + infoFontTextSize + "px; width: " + TOOLTIP_TABLE_WIDTH + "px; padding-left: 10px; margin: 0;\">");
|
||||||
showInfo.add("<ul style=\"font-size: " + infoFontSize + "px; width: " + TOOLTIP_TABLE_WIDTH + "px; padding-left: 10px; margin: 0;\">");
|
showInfo.add("<li style=\"margin-bottom: 2px;\">no cards</li>");
|
||||||
|
showInfo.add("</ul>");
|
||||||
|
} else {
|
||||||
|
showInfo.add("<ul style=\"font-size: " + infoFontTextSize + "px; width: " + TOOLTIP_TABLE_WIDTH + "px; padding-left: 10px; margin: 0;\">");
|
||||||
cards.forEach(s -> showInfo.add(String.format("<li style=\"margin-bottom: 2px;\">%s</li>", s)));
|
cards.forEach(s -> showInfo.add(String.format("<li style=\"margin-bottom: 2px;\">%s</li>", s)));
|
||||||
showInfo.add("</ul>");
|
showInfo.add("</ul>");
|
||||||
}
|
}
|
||||||
|
|
@ -156,6 +184,39 @@ public class BracketLegalityLabel extends LegalityLabel {
|
||||||
showState(showColor, showText, false);
|
showState(showColor, showText, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getStats(String groupName) {
|
||||||
|
int currentAmount = 0;
|
||||||
|
switch (groupName) {
|
||||||
|
case GROUP_GAME_CHANGES:
|
||||||
|
currentAmount = this.foundGameChangers.size();
|
||||||
|
break;
|
||||||
|
case GROUP_INFINITE_COMBOS:
|
||||||
|
currentAmount = this.foundInfiniteCombos.size();
|
||||||
|
break;
|
||||||
|
case GROUP_MASS_LAND_DESTRUCTION:
|
||||||
|
currentAmount = this.foundMassLandDestruction.size();
|
||||||
|
break;
|
||||||
|
case GROUP_EXTRA_TURN:
|
||||||
|
currentAmount = this.foundExtraTurn.size();
|
||||||
|
break;
|
||||||
|
case GROUP_TUTORS:
|
||||||
|
currentAmount = this.foundTutors.size();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown group " + groupName);
|
||||||
|
}
|
||||||
|
int maxAmount = MAX_GROUP_LIMITS.get(groupName).get(this.maxLevel);
|
||||||
|
|
||||||
|
String info;
|
||||||
|
if (currentAmount > maxAmount) {
|
||||||
|
info = " (<span style='color:#BF544A;'>%s of %s</span>)";
|
||||||
|
} else {
|
||||||
|
info = " (<span>%s of %s</span>)";
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(info, currentAmount, maxAmount == 99 ? "any" : maxAmount);
|
||||||
|
}
|
||||||
|
|
||||||
private void collectAll(Deck deck) {
|
private void collectAll(Deck deck) {
|
||||||
collectGameChangers(deck);
|
collectGameChangers(deck);
|
||||||
collectInfiniteCombos(deck);
|
collectInfiniteCombos(deck);
|
||||||
|
|
@ -243,8 +304,64 @@ public class BracketLegalityLabel extends LegalityLabel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectInfiniteCombos(Deck deck) {
|
private void collectInfiniteCombos(Deck deck) {
|
||||||
// TODO: implement
|
|
||||||
this.foundInfiniteCombos.clear();
|
this.foundInfiniteCombos.clear();
|
||||||
|
|
||||||
|
if (this.fullInfiniteCombos.isEmpty()) {
|
||||||
|
InputStream in = BracketLegalityLabel.class.getClassLoader().getResourceAsStream(RESOURCE_INFINITE_COMBOS);
|
||||||
|
if (in == null) {
|
||||||
|
throw new RuntimeException("Commander brackets: can't load infinite combos list");
|
||||||
|
}
|
||||||
|
try (InputStreamReader input = new InputStreamReader(in);
|
||||||
|
BufferedReader reader = new BufferedReader(input)) {
|
||||||
|
String line = reader.readLine();
|
||||||
|
while (line != null) {
|
||||||
|
try {
|
||||||
|
line = line.trim();
|
||||||
|
if (line.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<String> cards = Arrays.asList(line.split("@"));
|
||||||
|
if (cards.size() != 2) {
|
||||||
|
logger.warn("wrong line format in commander brackets file: " + line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(cards);
|
||||||
|
this.fullInfiniteCombos.add(String.join("@", cards));
|
||||||
|
} finally {
|
||||||
|
line = reader.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Tokens brackets: can't load infinite combos list - " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// search and check all x2 combinations
|
||||||
|
List<Card> deckCards = new ArrayList<>();
|
||||||
|
Set<Card> foundCards = new HashSet<>();
|
||||||
|
deckCards.addAll(deck.getCards());
|
||||||
|
deckCards.addAll(deck.getSideboard());
|
||||||
|
for (Card card1 : deckCards) {
|
||||||
|
for (Card card2 : deckCards) {
|
||||||
|
if (card1 == card2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<String> names = Arrays.asList(card1.getName(), card2.getName());
|
||||||
|
Collections.sort(names);
|
||||||
|
String deckCombo = String.join("@", names);
|
||||||
|
if (this.fullInfiniteCombos.contains(deckCombo)) {
|
||||||
|
foundCards.add(card1);
|
||||||
|
foundCards.add(card2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foundCards.stream()
|
||||||
|
.map(MageObject::getName)
|
||||||
|
.sorted()
|
||||||
|
.forEach(this.foundInfiniteCombos::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectMassLandDestruction(Deck deck) {
|
private void collectMassLandDestruction(Deck deck) {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package mage.client.components;
|
||||||
|
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.client.util.GUISizeHelper;
|
import mage.client.util.GUISizeHelper;
|
||||||
import mage.client.util.gui.GuiDisplayUtil;
|
|
||||||
import mage.deck.Commander;
|
import mage.deck.Commander;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -22,7 +21,7 @@ public class EdhPowerLevelLegalityLabel extends LegalityLabel {
|
||||||
|
|
||||||
public EdhPowerLevelLegalityLabel() {
|
public EdhPowerLevelLegalityLabel() {
|
||||||
super("EDH Power Level: ?", null);
|
super("EDH Power Level: ?", null);
|
||||||
setPreferredSize(DIM_PREFERRED_X3);
|
setPreferredSize(DIM_PREFERRED_3_OF_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,10 @@ public class LegalityLabel extends JLabel {
|
||||||
protected static final Color COLOR_TEXT = new Color(255, 255, 255);
|
protected static final Color COLOR_TEXT = new Color(255, 255, 255);
|
||||||
protected static final Dimension DIM_MINIMUM = new Dimension(75, 25);
|
protected static final Dimension DIM_MINIMUM = new Dimension(75, 25);
|
||||||
protected static final Dimension DIM_MAXIMUM = new Dimension(150, 75);
|
protected static final Dimension DIM_MAXIMUM = new Dimension(150, 75);
|
||||||
protected static final Dimension DIM_PREFERRED = new Dimension(75, 25);
|
protected static final Dimension DIM_PREFERRED_1_OF_3 = new Dimension(75, 25);
|
||||||
protected static final Dimension DIM_PREFERRED_X2 = new Dimension(DIM_PREFERRED.width * 2 + 5, 25);
|
protected static final Dimension DIM_PREFERRED_2_OF_3 = new Dimension(DIM_PREFERRED_1_OF_3.width * 2 + 5, 25);
|
||||||
protected static final Dimension DIM_PREFERRED_X3 = new Dimension(DIM_PREFERRED.width * 3 + 5 + 5, 25);
|
protected static final Dimension DIM_PREFERRED_3_OF_3 = new Dimension(DIM_PREFERRED_1_OF_3.width * 3 + 5 * 2, 25);
|
||||||
|
protected static final Dimension DIM_PREFERRED_1_OF_5 = new Dimension((DIM_PREFERRED_3_OF_3.width - 5 * 4) / 5, 25);
|
||||||
|
|
||||||
protected static final int TOOLTIP_TABLE_WIDTH = 400; // size of the label's tooltip
|
protected static final int TOOLTIP_TABLE_WIDTH = 400; // size of the label's tooltip
|
||||||
protected static final int TOOLTIP_MAX_ERRORS = 20; // max errors to show in tooltip
|
protected static final int TOOLTIP_MAX_ERRORS = 20; // max errors to show in tooltip
|
||||||
|
|
@ -54,7 +55,7 @@ public class LegalityLabel extends JLabel {
|
||||||
setMaximumSize(DIM_MAXIMUM);
|
setMaximumSize(DIM_MAXIMUM);
|
||||||
setName(text); // NOI18N
|
setName(text); // NOI18N
|
||||||
setOpaque(true);
|
setOpaque(true);
|
||||||
setPreferredSize(DIM_PREFERRED);
|
setPreferredSize(DIM_PREFERRED_1_OF_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -80,7 +81,7 @@ public class LegalityLabel extends JLabel {
|
||||||
setMinimumSize(DIM_MINIMUM);
|
setMinimumSize(DIM_MINIMUM);
|
||||||
setMaximumSize(DIM_MAXIMUM);
|
setMaximumSize(DIM_MAXIMUM);
|
||||||
setOpaque(true);
|
setOpaque(true);
|
||||||
setPreferredSize(DIM_PREFERRED);
|
setPreferredSize(DIM_PREFERRED_1_OF_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,7 +92,7 @@ public class LegalityLabel extends JLabel {
|
||||||
button.setHorizontalAlignment(SwingConstants.CENTER);
|
button.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
button.setMinimumSize(DIM_MINIMUM);
|
button.setMinimumSize(DIM_MINIMUM);
|
||||||
button.setMaximumSize(DIM_MAXIMUM);
|
button.setMaximumSize(DIM_MAXIMUM);
|
||||||
button.setPreferredSize(DIM_PREFERRED);
|
button.setPreferredSize(DIM_PREFERRED_1_OF_3);
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,11 @@ public class DeckLegalityPanel extends javax.swing.JPanel {
|
||||||
// extra buttons like score
|
// extra buttons like score
|
||||||
this.add(new EdhPowerLevelLegalityLabel());
|
this.add(new EdhPowerLevelLegalityLabel());
|
||||||
// only 3 buttons allowed for one line
|
// only 3 buttons allowed for one line
|
||||||
this.add(new BracketLegalityLabel(BracketLegalityLabel.BracketLevel.BRACKET_1));
|
this.add(new BracketLegalityLabel("Bracket 1", "B1", 1));
|
||||||
this.add(new BracketLegalityLabel(BracketLegalityLabel.BracketLevel.BRACKET_2_3));
|
this.add(new BracketLegalityLabel("Bracket 2", "B2", 2));
|
||||||
this.add(new BracketLegalityLabel(BracketLegalityLabel.BracketLevel.BRACKET_4_5));
|
this.add(new BracketLegalityLabel("Bracket 3", "B3", 3));
|
||||||
|
this.add(new BracketLegalityLabel("Bracket 4", "B4", 4));
|
||||||
|
this.add(new BracketLegalityLabel("Bracket 5", "B5", 5));
|
||||||
|
|
||||||
addHidePanelButton();
|
addHidePanelButton();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,16 +291,25 @@ public class XmageURLConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String downloadText(String resourceUrl) {
|
||||||
|
return downloadText(resourceUrl, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fast download of text data
|
* Fast download of text data
|
||||||
*
|
*
|
||||||
|
* @param additionalHeaders set extra headers like application/json
|
||||||
|
*
|
||||||
* @return downloaded text on OK 200 response or empty on any other errors
|
* @return downloaded text on OK 200 response or empty on any other errors
|
||||||
*/
|
*/
|
||||||
public static String downloadText(String resourceUrl) {
|
public static String downloadText(String resourceUrl, Map<String, String> additionalHeaders) {
|
||||||
XmageURLConnection con = new XmageURLConnection(resourceUrl);
|
XmageURLConnection con = new XmageURLConnection(resourceUrl);
|
||||||
con.startConnection();
|
con.startConnection();
|
||||||
if (con.isConnected()) {
|
if (con.isConnected()) {
|
||||||
try {
|
try {
|
||||||
|
if (additionalHeaders != null) {
|
||||||
|
con.setRequestHeaders(additionalHeaders);
|
||||||
|
}
|
||||||
con.connect();
|
con.connect();
|
||||||
if (con.getResponseCode() == 200) {
|
if (con.getResponseCode() == 200) {
|
||||||
return con.getGoodResponseAsString();
|
return con.getGoodResponseAsString();
|
||||||
|
|
|
||||||
|
|
@ -2201,6 +2201,7 @@ public class ScryfallImageSupportTokens {
|
||||||
put("WHO/Human/2", "https://api.scryfall.com/cards/twho/5/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/Mutant", "https://api.scryfall.com/cards/twho/18?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");
|
||||||
put("WHO/Treasure/1", "https://api.scryfall.com/cards/twho/28?format=image");
|
put("WHO/Treasure/1", "https://api.scryfall.com/cards/twho/28?format=image");
|
||||||
put("WHO/Treasure/2", "https://api.scryfall.com/cards/twho/29?format=image");
|
put("WHO/Treasure/2", "https://api.scryfall.com/cards/twho/29?format=image");
|
||||||
|
|
|
||||||
|
|
@ -853,7 +853,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
||||||
connection.startConnection();
|
connection.startConnection();
|
||||||
if (connection.isConnected()) {
|
if (connection.isConnected()) {
|
||||||
|
|
||||||
// custom headers (ues
|
// custom headers
|
||||||
connection.setRequestHeaders(selectedSource.getHttpRequestHeaders(currentUrl));
|
connection.setRequestHeaders(selectedSource.getHttpRequestHeaders(currentUrl));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Part of testable game dialogs
|
* Part of testable game dialogs
|
||||||
* <p>
|
* <p>
|
||||||
|
* It's a complex dialog with 2 steps: choose targets list + distribute amount between targets
|
||||||
|
* <p>
|
||||||
* Supported methods:
|
* Supported methods:
|
||||||
* - player.chooseTarget(amount)
|
* - player.chooseTarget(amount)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Part of testable game dialogs
|
* Part of testable game dialogs
|
||||||
* <p>
|
* <p>
|
||||||
|
* Its simple dialog to get some amount (example: part of chooseTargetAmount)
|
||||||
|
* <p>
|
||||||
* Supported methods:
|
* Supported methods:
|
||||||
* - player.getAmount()
|
* - player.getAmount()
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
package mage.utils.testers;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.constants.MultiAmountType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.util.MultiAmountMessage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of testable game dialogs
|
||||||
|
* <p>
|
||||||
|
* Its simple dialog to get distributed value between multiple options (example: part of combat damage distributing)
|
||||||
|
* <p>
|
||||||
|
* Supported methods:
|
||||||
|
* - player.getMultiAmountWithIndividualConstraints()
|
||||||
|
* - player.getMultiAmount() - simple version of constraints
|
||||||
|
*
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
class GetMultiAmountTestableDialog extends BaseTestableDialog {
|
||||||
|
|
||||||
|
boolean isYou; // who choose - you or opponent
|
||||||
|
int totalMin;
|
||||||
|
int totalMax;
|
||||||
|
List<MultiAmountMessage> amountOptions = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param options min, max, default
|
||||||
|
*/
|
||||||
|
public GetMultiAmountTestableDialog(boolean isYou, String info, int totalMin, int totalMax, List<List<Integer>> options) {
|
||||||
|
super(String.format("player.getMultiAmount(%s)", isYou ? "you" : "AI"),
|
||||||
|
String.format("%s, %d options from [%d-%d]", info, options.size(), totalMin, totalMax),
|
||||||
|
"");
|
||||||
|
this.isYou = isYou;
|
||||||
|
this.totalMin = totalMin;
|
||||||
|
this.totalMax = totalMax;
|
||||||
|
int optionNumber = 0;
|
||||||
|
for (List<Integer> single : options) {
|
||||||
|
optionNumber++;
|
||||||
|
String mes = "<font color=green>option</font> " + optionNumber + " with html";
|
||||||
|
this.amountOptions.add(new MultiAmountMessage(mes, single.get(0), single.get(1), single.get(2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> showDialog(Player player, Ability source, Game game, Player opponent) {
|
||||||
|
Player choosingPlayer = this.isYou ? player : opponent;
|
||||||
|
//String message = "<font color=green>message</font> with html";
|
||||||
|
List<Integer> chooseRes;
|
||||||
|
List<MultiAmountMessage> options = this.amountOptions.stream().map(MultiAmountMessage::copy).collect(Collectors.toList());
|
||||||
|
chooseRes = choosingPlayer.getMultiAmountWithIndividualConstraints(
|
||||||
|
Outcome.Benefit,
|
||||||
|
options,
|
||||||
|
this.totalMin,
|
||||||
|
this.totalMax,
|
||||||
|
MultiAmountType.DAMAGE,
|
||||||
|
game
|
||||||
|
);
|
||||||
|
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
result.add(getGroup() + " - " + this.getName());
|
||||||
|
int selectedIndex = -1;
|
||||||
|
int selectedTotal = 0;
|
||||||
|
for (Integer selectedValue : chooseRes) {
|
||||||
|
selectedIndex++;
|
||||||
|
selectedTotal += selectedValue;
|
||||||
|
MultiAmountMessage option = this.amountOptions.get(selectedIndex);
|
||||||
|
result.add(String.format("%d from [%d-%d, def %d]",
|
||||||
|
selectedValue,
|
||||||
|
option.min,
|
||||||
|
option.max,
|
||||||
|
option.defaultValue
|
||||||
|
));
|
||||||
|
}
|
||||||
|
result.add("total selected: " + selectedTotal);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public void register(TestableDialogsRunner runner) {
|
||||||
|
List<Boolean> isYous = Arrays.asList(false, true);
|
||||||
|
for (boolean isYou : isYous) {
|
||||||
|
// make sure default values are valid due min/max settings
|
||||||
|
|
||||||
|
// single target
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 0 def", 0, 1, genSameOptions(1, 0, 1, 0)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 0 def", 0, 3, genSameOptions(1, 0, 3, 0)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 1 def", 1, 1, genSameOptions(1, 1, 1, 1)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 1 def", 1, 3, genSameOptions(1, 1, 3, 1)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 5 def", 0, 10, genSameOptions(1, 0, 10, 5)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "one, 10 def", 10, 10, genSameOptions(1, 0, 10, 10)));
|
||||||
|
// multiple targets
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 0 def", 0, 5, genSameOptions(3, 0, 3, 0)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 0 def", 0, 5, genSameOptions(3, 0, 3, 0)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 1 def", 1, 5, genSameOptions(3, 1, 3, 1)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 1 def", 1, 5, genSameOptions(3, 1, 3, 1)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 20 def", 0, 60, genSameOptions(3, 0, 60, 20)));
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "many, 20 def", 60, 60, genSameOptions(3, 0, 60, 20)));
|
||||||
|
// big lists
|
||||||
|
runner.registerDialog(new GetMultiAmountTestableDialog(isYou, "big list", 0, 100, genSameOptions(20, 0, 100, 0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<List<Integer>> genSameOptions(int amount, int min, int max, int def) {
|
||||||
|
List<List<Integer>> res = new ArrayList<>();
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
// min, max, default
|
||||||
|
res.add(Arrays.asList(min, max, def));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ import java.util.stream.Collectors;
|
||||||
* [x] choosePile
|
* [x] choosePile
|
||||||
* [x] announceX
|
* [x] announceX
|
||||||
* [x] getAmount
|
* [x] getAmount
|
||||||
* [ ] getMultiAmountWithIndividualConstraints // TODO: implement
|
* [x] getMultiAmountWithIndividualConstraints
|
||||||
* <p>
|
* <p>
|
||||||
* Support of priority dialogs (can be called by game engine, some can be implemented in theory):
|
* Support of priority dialogs (can be called by game engine, some can be implemented in theory):
|
||||||
* --- priority
|
* --- priority
|
||||||
|
|
@ -75,6 +75,7 @@ public class TestableDialogsRunner {
|
||||||
ChooseAmountTestableDialog.register(this);
|
ChooseAmountTestableDialog.register(this);
|
||||||
AnnounceXTestableDialog.register(this);
|
AnnounceXTestableDialog.register(this);
|
||||||
GetAmountTestableDialog.register(this);
|
GetAmountTestableDialog.register(this);
|
||||||
|
GetMultiAmountTestableDialog.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerDialog(TestableDialog dialog) {
|
void registerDialog(TestableDialog dialog) {
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@
|
||||||
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
|
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
|
||||||
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/>
|
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/>
|
||||||
<tournamentType name="Booster Draft Swiss (Reshuffled)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.ReshuffledBoosterDraftSwissTournament" typeName="mage.tournament.ReshuffledBoosterDraftSwissTournamentType"/>
|
<tournamentType name="Booster Draft Swiss (Reshuffled)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.ReshuffledBoosterDraftSwissTournament" typeName="mage.tournament.ReshuffledBoosterDraftSwissTournamentType"/>
|
||||||
<tournamentType name="Booster Draft Swiss (Rich Man)" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.RichManDraftSwissTournament" typeName="mage.tournament.RichManDraftSwissTournamentType"/>
|
<tournamentType name="Booster Draft Swiss (Rich Man)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RichManDraftSwissTournament" typeName="mage.tournament.RichManDraftSwissTournamentType"/>
|
||||||
<tournamentType name="Booster Draft Swiss (Rich Man Cube)" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.RichManCubeDraftSwissTournament" typeName="mage.tournament.RichManCubeDraftSwissTournamentType"/>
|
<tournamentType name="Booster Draft Swiss (Rich Man Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RichManCubeDraftSwissTournament" typeName="mage.tournament.RichManCubeDraftSwissTournamentType"/>
|
||||||
<tournamentType name="Sealed Elimination" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/>
|
<tournamentType name="Sealed Elimination" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/>
|
||||||
<tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/>
|
<tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/>
|
||||||
<tournamentType name="Sealed Swiss" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/>
|
<tournamentType name="Sealed Swiss" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/>
|
||||||
|
|
@ -108,62 +108,62 @@
|
||||||
</tournamentTypes>
|
</tournamentTypes>
|
||||||
<draftCubes>
|
<draftCubes>
|
||||||
<!-- main cubes -->
|
<!-- main cubes -->
|
||||||
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.CubeFromDeck"/>
|
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.CubeFromDeck"/>
|
||||||
<draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCube"/>
|
<draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCube"/>
|
||||||
<draftCube name="MTGO Vintage Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCube"/>
|
<draftCube name="MTGO Vintage Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube"/>
|
||||||
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegendaryCube"/>
|
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegendaryCube"/>
|
||||||
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegendaryCubeApril2016"/>
|
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
|
||||||
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.ModernCube2017"/>
|
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.ModernCube2017"/>
|
||||||
<draftCube name="MTGO Khans Expanded Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.KhansExpandedCube"/>
|
<draftCube name="MTGO Khans Expanded Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.KhansExpandedCube"/>
|
||||||
<draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.MTGOMarchCube2014"/>
|
<draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/>
|
||||||
<draftCube name="MTGA Cube 2020 April" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.MTGACube2020April"/>
|
<draftCube name="MTGA Cube 2020 April" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGACube2020April"/>
|
||||||
<!-- named cubes (will be removed someday) -->
|
<!-- named cubes (will be removed someday) -->
|
||||||
<draftCube name="SCG Con Cube 2018 December" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.ScgConCube2018December"/>
|
<draftCube name="SCG Con Cube 2018 December" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.ScgConCube2018December"/>
|
||||||
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.PeasantsToolboxCube"/>
|
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
|
||||||
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.MTGCube"/>
|
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGCube"/>
|
||||||
<draftCube name="The Pauper Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.PauperCube"/>
|
<draftCube name="The Pauper Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.PauperCube"/>
|
||||||
<draftCube name="Ben's Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.BensCube"/>
|
<draftCube name="Ben's Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.BensCube"/>
|
||||||
<draftCube name="Cube Tutor 360 Pauper" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.CubeTutor360Pauper"/>
|
<draftCube name="Cube Tutor 360 Pauper" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.CubeTutor360Pauper"/>
|
||||||
<draftCube name="Cube Tutor 720" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.CubeTutor720"/>
|
<draftCube name="Cube Tutor 720" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.CubeTutor720"/>
|
||||||
<draftCube name="Eric Klug's Pro Tour Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.EricKlugsProTourCube"/>
|
<draftCube name="Eric Klug's Pro Tour Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.EricKlugsProTourCube"/>
|
||||||
<draftCube name="Guillaume Matignon's Jenny's/Johnny's Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.GuillaumeMatignonsJennysJohnnysCube"/>
|
<draftCube name="Guillaume Matignon's Jenny's/Johnny's Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.GuillaumeMatignonsJennysJohnnysCube"/>
|
||||||
<draftCube name="Jim Davis's Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.JimDavisCube"/>
|
<draftCube name="Jim Davis's Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.JimDavisCube"/>
|
||||||
<draftCube name="Joseph Vasoli's Peasant Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.JosephVasolisPeasantCube"/>
|
<draftCube name="Joseph Vasoli's Peasant Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.JosephVasolisPeasantCube"/>
|
||||||
<draftCube name="Sam Black's No Search Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.SamBlacksCube"/>
|
<draftCube name="Sam Black's No Search Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.SamBlacksCube"/>
|
||||||
<draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/>
|
<draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/>
|
||||||
<draftCube name="Mono Blue Cube" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.MonoBlueCube"/>
|
<draftCube name="Mono Blue Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MonoBlueCube"/>
|
||||||
<!-- outdated cubes - will be removed on next releases -->
|
<!-- outdated cubes - will be removed on next releases -->
|
||||||
<!--
|
<!--
|
||||||
<draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeMarch2015"/>
|
<draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeSeptember2015"/>
|
<draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeJanuary2016"/>
|
<draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeSeptember2016"/>
|
<draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeJanuary2017"/>
|
<draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeApril2017"/>
|
<draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCube2018February"/>
|
<draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCube2018February"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2019 July" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeJuly2019"/>
|
<draftCube name="MTGO Legacy Cube 2019 July" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJuly2019"/>
|
||||||
<draftCube name="MTGO Legacy Cube 2021 May" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.LegacyCubeMay2021"/>
|
<draftCube name="MTGO Legacy Cube 2021 May" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeMay2021"/>
|
||||||
-->
|
-->
|
||||||
<!-- outdated cubes - will be removed on next releases -->
|
<!-- outdated cubes - will be removed on next releases -->
|
||||||
<!--
|
<!--
|
||||||
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCube2013"/>
|
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2013"/>
|
||||||
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCube2014"/>
|
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2014"/>
|
||||||
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCube2015"/>
|
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2015"/>
|
||||||
<draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCube2016"/>
|
<draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2016"/>
|
||||||
<draftCube name="MTGO Vintage Cube June 2016" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeJune2016"/>
|
<draftCube name="MTGO Vintage Cube June 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJune2016"/>
|
||||||
<draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeNovember2016"/>
|
<draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/>
|
||||||
<draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeJune2017"/>
|
<draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJune2017"/>
|
||||||
<draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeDecember2017"/>
|
<draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/>
|
||||||
<draftCube name="MTGO Vintage Cube June 2018" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeJune2018"/>
|
<draftCube name="MTGO Vintage Cube June 2018" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJune2018"/>
|
||||||
<draftCube name="MTGO Vintage Cube December 2018" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeDecember2018"/>
|
<draftCube name="MTGO Vintage Cube December 2018" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeDecember2018"/>
|
||||||
<draftCube name="MTGO Vintage Cube June 2019" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeJune2019"/>
|
<draftCube name="MTGO Vintage Cube June 2019" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJune2019"/>
|
||||||
<draftCube name="MTGO Vintage Cube December 2019" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeDecember2019"/>
|
<draftCube name="MTGO Vintage Cube December 2019" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeDecember2019"/>
|
||||||
<draftCube name="MTGO Vintage Cube April 2020" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeApril2020"/>
|
<draftCube name="MTGO Vintage Cube April 2020" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeApril2020"/>
|
||||||
<draftCube name="MTGO Vintage Cube July 2020" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeJuly2020"/>
|
<draftCube name="MTGO Vintage Cube July 2020" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJuly2020"/>
|
||||||
<draftCube name="MTGO Vintage Cube December 2020" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeDecember2020"/>
|
<draftCube name="MTGO Vintage Cube December 2020" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeDecember2020"/>
|
||||||
<draftCube name="MTGO Vintage Cube July 2021" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeJuly2021"/>
|
<draftCube name="MTGO Vintage Cube July 2021" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJuly2021"/>
|
||||||
<draftCube name="MTGO Vintage Cube February 2022" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeFebruary2022"/>
|
<draftCube name="MTGO Vintage Cube February 2022" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeFebruary2022"/>
|
||||||
<draftCube name="MTGO Vintage Cube October 2023" jar="mage-tournament-booster-draft-${project.version}.jar" classNam="mage.tournament.cubes.VintageCubeOctober2023"/>
|
<draftCube name="MTGO Vintage Cube October 2023" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeOctober2023"/>
|
||||||
-->
|
-->
|
||||||
</draftCubes>
|
</draftCubes>
|
||||||
<deckTypes>
|
<deckTypes>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.cards.RateCard;
|
import mage.cards.RateCard;
|
||||||
import mage.cards.Sets;
|
import mage.cards.Sets;
|
||||||
import mage.cards.decks.DeckValidatorFactory;
|
import mage.cards.decks.DeckValidatorFactory;
|
||||||
import mage.cards.repository.*;
|
import mage.cards.repository.CardScanner;
|
||||||
|
import mage.cards.repository.PluginClassloaderRegistery;
|
||||||
|
import mage.cards.repository.RepositoryUtil;
|
||||||
import mage.game.match.MatchType;
|
import mage.game.match.MatchType;
|
||||||
import mage.game.tournament.TournamentType;
|
import mage.game.tournament.TournamentType;
|
||||||
import mage.interfaces.MageServer;
|
import mage.interfaces.MageServer;
|
||||||
|
|
@ -507,8 +509,19 @@ public final class Main {
|
||||||
|
|
||||||
private static Class<?> loadPlugin(Plugin plugin) {
|
private static Class<?> loadPlugin(Plugin plugin) {
|
||||||
try {
|
try {
|
||||||
classLoader.addURL(new File(pluginFolder, plugin.getJar()).toURI().toURL());
|
|
||||||
logger.debug("Loading plugin: " + plugin.getClassName());
|
logger.debug("Loading plugin: " + plugin.getClassName());
|
||||||
|
if (plugin.getName() == null || plugin.getName().isEmpty()
|
||||||
|
|| plugin.getJar() == null || plugin.getJar().isEmpty()
|
||||||
|
|| plugin.getClassName() == null || plugin.getClassName().isEmpty()
|
||||||
|
) {
|
||||||
|
logger.error(String.format("Can't load plugin, found miss fields in config.xml: %s, %s, %s",
|
||||||
|
plugin.getName(),
|
||||||
|
plugin.getJar(),
|
||||||
|
plugin.getClassName()
|
||||||
|
));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
classLoader.addURL(new File(pluginFolder, plugin.getJar()).toURI().toURL());
|
||||||
return Class.forName(plugin.getClassName(), true, classLoader);
|
return Class.forName(plugin.getClassName(), true, classLoader);
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
logger.warn(new StringBuilder("Plugin not Found: ").append(plugin.getClassName()).append(" - ").append(plugin.getJar()).append(" - check plugin folder"), ex);
|
logger.warn(new StringBuilder("Plugin not Found: ").append(plugin.getClassName()).append(" - ").append(plugin.getJar()).append(" - check plugin folder"), ex);
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public enum GameFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addGameType(String name, MatchType matchType, Class game) {
|
public void addGameType(String name, MatchType matchType, Class game) {
|
||||||
if (game != null) {
|
if (matchType != null && game != null) {
|
||||||
this.games.put(name, game);
|
this.games.put(name, game);
|
||||||
this.gameTypes.put(name, matchType);
|
this.gameTypes.put(name, matchType);
|
||||||
this.gameTypeViews.add(new GameTypeView(matchType));
|
this.gameTypeViews.add(new GameTypeView(matchType));
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,10 @@ public enum PlayerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPlayerType(String name, Class playerType) {
|
public void addPlayerType(String name, Class playerType) {
|
||||||
|
// will raise error and stop on unknown player and that's ok - it's require HumanPlayer anyway
|
||||||
PlayerType type = PlayerType.getByDescription(name);
|
PlayerType type = PlayerType.getByDescription(name);
|
||||||
if (type != null) {
|
if (playerType != null) {
|
||||||
if (playerType != null) {
|
this.playerTypes.put(type, playerType);
|
||||||
this.playerTypes.put(type, playerType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ public enum TournamentFactory {
|
||||||
|
|
||||||
|
|
||||||
public void addTournamentType(String name, TournamentType tournamentType, Class tournament) {
|
public void addTournamentType(String name, TournamentType tournamentType, Class tournament) {
|
||||||
if (tournament != null) {
|
if (tournamentType != null && tournament != null) {
|
||||||
this.tournaments.put(name, tournament);
|
this.tournaments.put(name, tournament);
|
||||||
this.tournamentTypes.put(name, tournamentType);
|
this.tournamentTypes.put(name, tournamentType);
|
||||||
this.tournamentTypeViews.add(new TournamentTypeView(tournamentType));
|
this.tournamentTypeViews.add(new TournamentTypeView(tournamentType));
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
|
import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster;
|
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ public final class Aberrant extends CardImpl {
|
||||||
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true);
|
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true);
|
||||||
ability.withFlavorWord("Heavy Power Hammer");
|
ability.withFlavorWord("Heavy Power Hammer");
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster());
|
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.common.FilterHistoricCard;
|
import mage.filter.predicate.mageobject.HistoricPredicate;
|
||||||
import mage.target.common.TargetCardInYourGraveyard;
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -24,7 +24,10 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class AbstergoEntertainment extends CardImpl {
|
public final class AbstergoEntertainment extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCard filter = new FilterHistoricCard("historic card from your graveyard");
|
private static final FilterCard filter = new FilterCard("historic card from your graveyard");
|
||||||
|
static {
|
||||||
|
filter.add(HistoricPredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
public AbstergoEntertainment(UUID ownerId, CardSetInfo setInfo) {
|
public AbstergoEntertainment(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,35 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
|
||||||
import mage.abilities.condition.common.ControlsCreatureGreatestToughnessCondition;
|
import mage.abilities.condition.common.ControlsCreatureGreatestToughnessCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
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.SubType;
|
import mage.constants.SubType;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class AbzanBeastmaster extends CardImpl {
|
public final class AbzanBeastmaster extends CardImpl {
|
||||||
|
|
||||||
public AbzanBeastmaster(UUID ownerId, CardSetInfo setInfo) {
|
public AbzanBeastmaster(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
|
||||||
this.subtype.add(SubType.DOG);
|
this.subtype.add(SubType.DOG);
|
||||||
this.subtype.add(SubType.SHAMAN);
|
this.subtype.add(SubType.SHAMAN);
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
// At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness.
|
// At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ConditionalOneShotEffect(
|
||||||
new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1)),
|
new DrawCardSourceControllerEffect(1), ControlsCreatureGreatestToughnessCondition.instance,
|
||||||
ControlsCreatureGreatestToughnessCondition.instance,
|
"draw a card if you control the creature with the greatest toughness or tied for the greatest toughness"
|
||||||
"At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness."
|
)));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AbzanBeastmaster(final AbzanBeastmaster card) {
|
private AbzanBeastmaster(final AbzanBeastmaster card) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
|
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -25,7 +24,7 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class AcclaimedContender extends CardImpl {
|
public final class AcclaimedContender extends CardImpl {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT);
|
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT, "you control another Knight");
|
||||||
private static final FilterCard filter2
|
private static final FilterCard filter2
|
||||||
= new FilterCard("a Knight, Aura, Equipment, or legendary artifact card");
|
= new FilterCard("a Knight, Aura, Equipment, or legendary artifact card");
|
||||||
|
|
||||||
|
|
@ -53,14 +52,9 @@ public final class AcclaimedContender extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// When Acclaimed Contender enters the battlefield, if you control another Knight, look at the top five cards of your library. You may reveal a Knight, Aura, Equipment, or legendary artifact card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
// When Acclaimed Contender enters the battlefield, if you control another Knight, look at the top five cards of your library. You may reveal a Knight, Aura, Equipment, or legendary artifact card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
|
||||||
new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
|
5, 1, filter2, PutCards.HAND, PutCards.BOTTOM_RANDOM
|
||||||
5, 1, filter2, PutCards.HAND, PutCards.BOTTOM_RANDOM
|
)).withInterveningIf(condition));
|
||||||
)), condition, "When {this} enters, " +
|
|
||||||
"if you control another Knight, look at the top five cards of your library. " +
|
|
||||||
"You may reveal a Knight, Aura, Equipment, or legendary artifact card from among them " +
|
|
||||||
"and put it into your hand. Put the rest on the bottom of your library in a random order."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AcclaimedContender(final AcclaimedContender card) {
|
private AcclaimedContender(final AcclaimedContender card) {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.CompletedDungeonCondition;
|
import mage.abilities.condition.common.CompletedDungeonCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||||
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
|
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
|
||||||
|
|
@ -22,8 +21,6 @@ import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.ZombieToken;
|
import mage.game.permanent.token.ZombieToken;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetPermanent;
|
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
|
||||||
import mage.target.common.TargetSacrifice;
|
import mage.target.common.TargetSacrifice;
|
||||||
import mage.watchers.common.CompletedDungeonWatcher;
|
import mage.watchers.common.CompletedDungeonWatcher;
|
||||||
|
|
||||||
|
|
@ -44,13 +41,9 @@ public final class AcererakTheArchlich extends CardImpl {
|
||||||
this.toughness = new MageInt(5);
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
// When Acererak the Archlich enters the battlefield, if you have not completed Tomb of Annihilation, return Acererak the Archlich to its owner's hand and venture into the dungeon.
|
// When Acererak the Archlich enters the battlefield, if you have not completed Tomb of Annihilation, return Acererak the Archlich to its owner's hand and venture into the dungeon.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandSourceEffect(true))
|
||||||
new EntersBattlefieldTriggeredAbility(new ReturnToHandSourceEffect(true)),
|
.withInterveningIf(AcererakTheArchlichCondition.instance);
|
||||||
AcererakTheArchlichCondition.instance, "When {this} enters, " +
|
ability.addEffect(new VentureIntoTheDungeonEffect().concatBy("and"));
|
||||||
"if you haven't completed Tomb of Annihilation, return {this} " +
|
|
||||||
"to its owner's hand and venture into the dungeon."
|
|
||||||
);
|
|
||||||
ability.addEffect(new VentureIntoTheDungeonEffect());
|
|
||||||
ability.addHint(CurrentDungeonHint.instance);
|
ability.addHint(CurrentDungeonHint.instance);
|
||||||
ability.addHint(CompletedDungeonCondition.getHint());
|
ability.addHint(CompletedDungeonCondition.getHint());
|
||||||
this.addAbility(ability, new CompletedDungeonWatcher());
|
this.addAbility(ability, new CompletedDungeonWatcher());
|
||||||
|
|
@ -78,6 +71,11 @@ enum AcererakTheArchlichCondition implements Condition {
|
||||||
source.getControllerId(), game
|
source.getControllerId(), game
|
||||||
).contains("Tomb of Annihilation");
|
).contains("Tomb of Annihilation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "you haven't completed Tomb of Annihilation";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AcererakTheArchlichEffect extends OneShotEffect {
|
class AcererakTheArchlichEffect extends OneShotEffect {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
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.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class AdaptiveTrainingPost extends CardImpl {
|
public final class AdaptiveTrainingPost extends CardImpl {
|
||||||
|
|
||||||
private static final Condition condition = new SourceHasCounterCondition(CounterType.CHARGE, 0, 2);
|
private static final Condition condition = new SourceHasCounterCondition(CounterType.CHARGE, ComparisonType.FEWER_THAN, 3);
|
||||||
|
|
||||||
public AdaptiveTrainingPost(UUID ownerId, CardSetInfo setInfo) {
|
public AdaptiveTrainingPost(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}");
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,41 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.abilities.hint.ConditionHint;
|
||||||
|
import mage.abilities.hint.Hint;
|
||||||
|
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.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPlaneswalkerPermanent;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author htrajan
|
* @author htrajan
|
||||||
*/
|
*/
|
||||||
public final class AdherentOfHope extends CardImpl {
|
public final class AdherentOfHope extends CardImpl {
|
||||||
|
|
||||||
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
|
||||||
|
new FilterControlledPlaneswalkerPermanent(SubType.BASRI, "you control a Basri planeswalker")
|
||||||
static {
|
);
|
||||||
filter.add(CardType.PLANESWALKER.getPredicate());
|
private static final Hint hint = new ConditionHint(condition);
|
||||||
filter.add(SubType.BASRI.getPredicate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public AdherentOfHope(UUID ownerId, CardSetInfo setInfo) {
|
public AdherentOfHope(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
|
||||||
|
|
||||||
this.subtype.add(SubType.HUMAN);
|
this.subtype.add(SubType.HUMAN);
|
||||||
this.subtype.add(SubType.SOLDIER);
|
this.subtype.add(SubType.SOLDIER);
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
// At the beginning of combat on your turn, if you control a Basri planeswalker, put a +1/+1 counter on Adherent of Hope.
|
// At the beginning of combat on your turn, if you control a Basri planeswalker, put a +1/+1 counter on Adherent of Hope.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())).withInterveningIf(condition).addHint(hint));
|
||||||
new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())),
|
|
||||||
new PermanentsOnTheBattlefieldCondition(filter),
|
|
||||||
"At the beginning of combat on your turn, if you control a Basri planeswalker, put a +1/+1 counter on {this}."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AdherentOfHope(final AdherentOfHope card) {
|
private AdherentOfHope(final AdherentOfHope card) {
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,38 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObjectReference;
|
import mage.MageObjectReference;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.ContinuousEffectImpl;
|
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.continuous.AddCardSubTypeSourceEffect;
|
import mage.abilities.effects.common.continuous.AddCardSubTypeSourceEffect;
|
||||||
import mage.abilities.hint.ConditionHint;
|
import mage.abilities.hint.ConditionHint;
|
||||||
import mage.abilities.hint.Hint;
|
import mage.abilities.hint.Hint;
|
||||||
import mage.constants.*;
|
|
||||||
import mage.abilities.keyword.IslandwalkAbility;
|
|
||||||
import mage.abilities.keyword.CrewAbility;
|
import mage.abilities.keyword.CrewAbility;
|
||||||
|
import mage.abilities.keyword.IslandwalkAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.*;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
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.permanent.Permanent;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Grath
|
* @author Grath
|
||||||
*/
|
*/
|
||||||
public final class Adrestia extends CardImpl {
|
public final class Adrestia extends CardImpl {
|
||||||
|
|
||||||
private static final Condition condition = AdrestiaCondition.instance;
|
|
||||||
|
|
||||||
public Adrestia(UUID ownerId, CardSetInfo setInfo) {
|
public Adrestia(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||||
|
|
||||||
this.supertype.add(SuperType.LEGENDARY);
|
this.supertype.add(SuperType.LEGENDARY);
|
||||||
this.subtype.add(SubType.VEHICLE);
|
this.subtype.add(SubType.VEHICLE);
|
||||||
this.power = new MageInt(4);
|
this.power = new MageInt(4);
|
||||||
|
|
@ -44,16 +42,14 @@ public final class Adrestia extends CardImpl {
|
||||||
this.addAbility(new IslandwalkAbility());
|
this.addAbility(new IslandwalkAbility());
|
||||||
|
|
||||||
// Whenever Adrestia attacks, if an Assassin crewed it this turn, draw a card. Adrestia becomes an Assassin in addition to its other types until end of turn.
|
// Whenever Adrestia attacks, if an Assassin crewed it this turn, draw a card. Adrestia becomes an Assassin in addition to its other types until end of turn.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new AttacksTriggeredAbility(new DrawCardSourceControllerEffect(1), false)
|
||||||
new AttacksTriggeredAbility(new DrawCardSourceControllerEffect(1), false),
|
.withInterveningIf(AdrestiaCondition.instance);
|
||||||
condition, "Whenever {this} attacks, if an Assassin crewed it this turn, draw a card. {this} becomes an Assassin in addition to its other types until end of turn.");
|
|
||||||
ability.addEffect(new AddCardSubTypeSourceEffect(Duration.EndOfTurn, true, SubType.ASSASSIN));
|
ability.addEffect(new AddCardSubTypeSourceEffect(Duration.EndOfTurn, true, SubType.ASSASSIN));
|
||||||
ability.addHint(AdrestiaCondition.getHint());
|
ability.addHint(AdrestiaCondition.getHint());
|
||||||
this.addAbility(ability, new AdrestiaWatcher());
|
this.addAbility(ability, new AdrestiaWatcher());
|
||||||
|
|
||||||
// Crew 1
|
// Crew 1
|
||||||
this.addAbility(new CrewAbility(1));
|
this.addAbility(new CrewAbility(1));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Adrestia(final Adrestia card) {
|
private Adrestia(final Adrestia card) {
|
||||||
|
|
@ -68,13 +64,18 @@ public final class Adrestia extends CardImpl {
|
||||||
|
|
||||||
enum AdrestiaCondition implements Condition {
|
enum AdrestiaCondition implements Condition {
|
||||||
instance;
|
instance;
|
||||||
private static final Hint hint = new ConditionHint(instance, "an Assassin crewed it this turn");
|
private static final Hint hint = new ConditionHint(instance);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
return AdrestiaWatcher.checkIfAssassinCrewed(source.getSourcePermanentOrLKI(game), game);
|
return AdrestiaWatcher.checkIfAssassinCrewed(source.getSourcePermanentOrLKI(game), game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "an Assassin crewed it this turn";
|
||||||
|
}
|
||||||
|
|
||||||
public static Hint getHint() {
|
public static Hint getHint() {
|
||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
|
|
@ -97,8 +98,7 @@ class AdrestiaWatcher extends Watcher {
|
||||||
if (crewer != null) {
|
if (crewer != null) {
|
||||||
if (!crewMap.containsKey(vehicle)) {
|
if (!crewMap.containsKey(vehicle)) {
|
||||||
crewMap.put(vehicle, filter.match(crewer, game));
|
crewMap.put(vehicle, filter.match(crewer, game));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
crewMap.put(vehicle, crewMap.get(vehicle) || filter.match(crewer, game));
|
crewMap.put(vehicle, crewMap.get(vehicle) || filter.match(crewer, game));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
|
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
|
||||||
import mage.abilities.hint.Hint;
|
import mage.abilities.hint.Hint;
|
||||||
import mage.abilities.hint.common.LandsYouControlHint;
|
import mage.abilities.hint.common.LandsYouControlHint;
|
||||||
|
|
@ -46,13 +45,10 @@ public final class AerialSurveyor extends CardImpl {
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// Whenever Aerial Surveyor attacks, if defending player controls more lands than you, search your library for a basic Plains card, put it onto the battlefield tapped, then shuffle.
|
// Whenever Aerial Surveyor attacks, if defending player controls more lands than you, search your library for a basic Plains card, put it onto the battlefield tapped, then shuffle.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new AttacksTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true))
|
||||||
new AttacksTriggeredAbility(
|
.withInterveningIf(AerialSurveyorCondition.instance)
|
||||||
new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true)
|
.addHint(LandsYouControlHint.instance)
|
||||||
), AerialSurveyorCondition.instance, "Whenever {this} attacks, if defending player " +
|
.addHint(AerialSurveyorHint.instance));
|
||||||
"controls more lands than you, search your library for a basic Plains card, " +
|
|
||||||
"put it onto the battlefield tapped, then shuffle."
|
|
||||||
).addHint(LandsYouControlHint.instance).addHint(AerialSurveyorHint.instance));
|
|
||||||
|
|
||||||
// Crew 2
|
// Crew 2
|
||||||
this.addAbility(new CrewAbility(2));
|
this.addAbility(new CrewAbility(2));
|
||||||
|
|
@ -85,6 +81,11 @@ enum AerialSurveyorCondition implements Condition {
|
||||||
source.getControllerId(), source, game
|
source.getControllerId(), source, game
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AerialSurveyorHint implements Hint {
|
enum AerialSurveyorHint implements Hint {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
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.common.SpellCastControllerTriggeredAbility;
|
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||||
|
|
@ -10,14 +7,20 @@ import mage.abilities.costs.common.PayEnergyCost;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.continuous.CastFromHandWithoutPayingManaCostEffect;
|
|
||||||
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
|
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.cards.CardsImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author sobiech
|
* @author sobiech
|
||||||
|
|
@ -28,14 +31,12 @@ public final class AetherfluxConduit extends CardImpl {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
|
||||||
|
|
||||||
// Whenever you cast a spell, you get an amount of {E} equal to the amount of mana spent to cast that spell.
|
// Whenever you cast a spell, you get an amount of {E} equal to the amount of mana spent to cast that spell.
|
||||||
this.addAbility(new SpellCastControllerTriggeredAbility(
|
this.addAbility(new SpellCastControllerTriggeredAbility(new AetherfluxConduitManaEffect(), false));
|
||||||
new AetherfluxConduitEffect(),false
|
|
||||||
));
|
|
||||||
|
|
||||||
// {T}, Pay fifty {E}: Draw seven cards. You may cast any number of spells from your hand without paying their mana costs.
|
// {T}, Pay fifty {E}: Draw seven cards. You may cast any number of spells from your hand without paying their mana costs.
|
||||||
final Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(7), new TapSourceCost());
|
final Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(7), new TapSourceCost());
|
||||||
ability.addCost(new PayEnergyCost(50).setText("Pay fifty {E}"));
|
ability.addCost(new PayEnergyCost(50).setText("Pay fifty {E}"));
|
||||||
ability.addEffect(new CastFromHandWithoutPayingManaCostEffect());
|
ability.addEffect(new AetherfluxConduitCastEffect());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,19 +49,21 @@ public final class AetherfluxConduit extends CardImpl {
|
||||||
return new AetherfluxConduit(this);
|
return new AetherfluxConduit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class AetherfluxConduitEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
AetherfluxConduitEffect() {
|
class AetherfluxConduitManaEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
AetherfluxConduitManaEffect() {
|
||||||
super(Outcome.Benefit);
|
super(Outcome.Benefit);
|
||||||
this.staticText = "you get an amount of {E} <i>(energy counters)</i> equal to the amount of mana spent to cast that spell";
|
this.staticText = "you get an amount of {E} <i>(energy counters)</i> equal to the amount of mana spent to cast that spell";
|
||||||
}
|
}
|
||||||
private AetherfluxConduitEffect(AetherfluxConduitEffect effect) {
|
|
||||||
|
private AetherfluxConduitManaEffect(AetherfluxConduitManaEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AetherfluxConduitEffect copy() {
|
public AetherfluxConduitManaEffect copy() {
|
||||||
return new AetherfluxConduitEffect(this);
|
return new AetherfluxConduitManaEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -72,3 +75,31 @@ class AetherfluxConduitEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AetherfluxConduitCastEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
AetherfluxConduitCastEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "You may cast any number of spells from your hand without paying their mana costs";
|
||||||
|
}
|
||||||
|
|
||||||
|
private AetherfluxConduitCastEffect(final AetherfluxConduitCastEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AetherfluxConduitCastEffect copy() {
|
||||||
|
return new AetherfluxConduitCastEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CardUtil.castMultipleWithAttributeForFree(
|
||||||
|
player, source, game, new CardsImpl(player.getHand()), StaticFilters.FILTER_CARD
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,15 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
|
import mage.abilities.hint.Hint;
|
||||||
import mage.abilities.hint.ValueHint;
|
import mage.abilities.hint.ValueHint;
|
||||||
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
|
|
@ -24,12 +25,15 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class AgentOfTreachery extends CardImpl {
|
public final class AgentOfTreachery extends CardImpl {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterControlledPermanent();
|
private static final FilterPermanent filter = new FilterControlledPermanent("you control three or more permanents you don't own");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(TargetController.NOT_YOU.getOwnerPredicate());
|
filter.add(TargetController.NOT_YOU.getOwnerPredicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 2);
|
||||||
|
private static final Hint hint = new ValueHint("Permanents you control but don't own", new PermanentsOnBattlefieldCount(filter));
|
||||||
|
|
||||||
public AgentOfTreachery(UUID ownerId, CardSetInfo setInfo) {
|
public AgentOfTreachery(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
|
||||||
|
|
||||||
|
|
@ -44,12 +48,7 @@ public final class AgentOfTreachery extends CardImpl {
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// At the beginning of your end step, if you control three or more permanents you don't own, draw three cards.
|
// At the beginning of your end step, if you control three or more permanents you don't own, draw three cards.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfEndStepTriggeredAbility(new DrawCardSourceControllerEffect(3)).withInterveningIf(condition).addHint(hint));
|
||||||
new BeginningOfEndStepTriggeredAbility(
|
|
||||||
new DrawCardSourceControllerEffect(3)
|
|
||||||
), new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 2), "At the beginning of your end step, " +
|
|
||||||
"if you control three or more permanents you don't own, draw three cards."
|
|
||||||
).addHint(new ValueHint("Permanents you control but don't own", new PermanentsOnBattlefieldCount(filter))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AgentOfTreachery(final AgentOfTreachery card) {
|
private AgentOfTreachery(final AgentOfTreachery card) {
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,28 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
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.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPlaneswalkerPermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author fireshoes
|
* @author fireshoes
|
||||||
*/
|
*/
|
||||||
public final class AjanisComrade extends CardImpl {
|
public final class AjanisComrade extends CardImpl {
|
||||||
|
|
||||||
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
|
||||||
|
new FilterControlledPlaneswalkerPermanent(SubType.AJANI, "you control an Ajani planeswalker")
|
||||||
static {
|
);
|
||||||
filter.add(CardType.PLANESWALKER.getPredicate());
|
|
||||||
filter.add(SubType.AJANI.getPredicate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public AjanisComrade(UUID ownerId, CardSetInfo setInfo) {
|
public AjanisComrade(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
||||||
|
|
@ -40,10 +36,7 @@ public final class AjanisComrade extends CardImpl {
|
||||||
this.addAbility(TrampleAbility.getInstance());
|
this.addAbility(TrampleAbility.getInstance());
|
||||||
|
|
||||||
// At the beginning of combat on your turn, if you control an Ajani planeswalker, put a +1/+1 counter on Ajani's Comrade.
|
// At the beginning of combat on your turn, if you control an Ajani planeswalker, put a +1/+1 counter on Ajani's Comrade.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())).withInterveningIf(condition));
|
||||||
new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())),
|
|
||||||
new PermanentsOnTheBattlefieldCondition(filter),
|
|
||||||
"At the beginning of combat on your turn, if you control an Ajani planeswalker, put a +1/+1 counter on {this}."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AjanisComrade(final AjanisComrade card) {
|
private AjanisComrade(final AjanisComrade card) {
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,42 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||||
|
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
|
||||||
import mage.abilities.common.DiscardedByOpponentTriggeredAbility;
|
import mage.abilities.common.DiscardedByOpponentTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.abilities.effects.common.DoIfCostPaid;
|
import mage.abilities.effects.common.DoIfCostPaid;
|
||||||
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.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.events.ZoneChangeEvent;
|
|
||||||
import mage.game.permanent.token.AvatarToken2;
|
import mage.game.permanent.token.AvatarToken2;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class AjanisLastStand extends CardImpl {
|
public final class AjanisLastStand extends CardImpl {
|
||||||
|
|
||||||
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
|
||||||
|
new FilterControlledPermanent(SubType.PLAINS, "you control a Plains")
|
||||||
static {
|
);
|
||||||
filter.add(SubType.PLAINS.getPredicate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public AjanisLastStand(UUID ownerId, CardSetInfo setInfo) {
|
public AjanisLastStand(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
|
||||||
|
|
||||||
// Whenever a creature or planeswalker you control dies, you may sacrifice Ajani's Last Stand. If you do, create a 4/4 white Avatar creature token with flying.
|
// Whenever a creature or planeswalker you control dies, you may sacrifice Ajani's Last Stand. If you do, create a 4/4 white Avatar creature token with flying.
|
||||||
this.addAbility(new AjanisLastStandTriggeredAbility());
|
this.addAbility(new DiesCreatureTriggeredAbility(
|
||||||
|
new DoIfCostPaid(new CreateTokenEffect(new AvatarToken2()), new SacrificeSourceCost()),
|
||||||
|
false, StaticFilters.FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER
|
||||||
|
));
|
||||||
|
|
||||||
// When a spell or ability an opponent controls causes you to discard this card, if you control a Plains, create a 4/4 white Avatar creature token with flying.
|
// When a spell or ability an opponent controls causes you to discard this card, if you control a Plains, create a 4/4 white Avatar creature token with flying.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new DiscardedByOpponentTriggeredAbility(new CreateTokenEffect(new AvatarToken2())).withInterveningIf(condition));
|
||||||
new DiscardedByOpponentTriggeredAbility(new CreateTokenEffect(new AvatarToken2())),
|
|
||||||
new PermanentsOnTheBattlefieldCondition(filter),
|
|
||||||
"When a spell or ability an opponent controls causes you to discard this card, "
|
|
||||||
+ "if you control a Plains, create a 4/4 white Avatar creature token with flying."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AjanisLastStand(final AjanisLastStand card) {
|
private AjanisLastStand(final AjanisLastStand card) {
|
||||||
|
|
@ -57,53 +48,3 @@ public final class AjanisLastStand extends CardImpl {
|
||||||
return new AjanisLastStand(this);
|
return new AjanisLastStand(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AjanisLastStandTriggeredAbility extends TriggeredAbilityImpl {
|
|
||||||
|
|
||||||
public AjanisLastStandTriggeredAbility() {
|
|
||||||
super(Zone.BATTLEFIELD, new DoIfCostPaid(
|
|
||||||
new CreateTokenEffect(new AvatarToken2()),
|
|
||||||
new SacrificeSourceCost()
|
|
||||||
), false);
|
|
||||||
setLeavesTheBattlefieldTrigger(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AjanisLastStandTriggeredAbility(final AjanisLastStandTriggeredAbility ability) {
|
|
||||||
super(ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AjanisLastStandTriggeredAbility copy() {
|
|
||||||
return new AjanisLastStandTriggeredAbility(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.isDiesEvent()) {
|
|
||||||
if (zEvent.getTarget().isControlledBy(controllerId)
|
|
||||||
&& (zEvent.getTarget().isCreature(game)
|
|
||||||
|| zEvent.getTarget().isPlaneswalker(game))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRule() {
|
|
||||||
return "Whenever a creature or planeswalker you control dies, "
|
|
||||||
+ "you may sacrifice {this}. "
|
|
||||||
+ "If you do, create a 4/4 white Avatar creature token with flying.";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.dynamicvalue.DynamicValue;
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
|
|
@ -52,18 +51,24 @@ public final class AlchemistsTalent extends CardImpl {
|
||||||
// Treasures you control have "{T}, Sacrifice this artifact: Add two mana of any one color."
|
// Treasures you control have "{T}, Sacrifice this artifact: Add two mana of any one color."
|
||||||
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost());
|
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost());
|
||||||
ability.addCost(new SacrificeSourceCost().setText("sacrifice this artifact"));
|
ability.addCost(new SacrificeSourceCost().setText("sacrifice this artifact"));
|
||||||
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(new GainAbilityControlledEffect(ability, Duration.WhileOnBattlefield, new FilterPermanent(SubType.TREASURE, "Treasures")), 2)));
|
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(
|
||||||
|
new GainAbilityControlledEffect(
|
||||||
|
ability, Duration.WhileOnBattlefield,
|
||||||
|
new FilterPermanent(SubType.TREASURE, "Treasures")
|
||||||
|
), 2
|
||||||
|
)));
|
||||||
|
|
||||||
// {4}{R}: Level 3
|
// {4}{R}: Level 3
|
||||||
this.addAbility(new ClassLevelAbility(3, "{4}{R}"));
|
this.addAbility(new ClassLevelAbility(3, "{4}{R}"));
|
||||||
|
|
||||||
// Whenever you cast a spell, if mana from a Treasure was spent to cast it, this Class deals damage equal to that spell's mana value to each opponent.
|
// Whenever you cast a spell, if mana from a Treasure was spent to cast it, this Class deals damage equal to that spell's mana value to each opponent.
|
||||||
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(
|
||||||
new SpellCastControllerTriggeredAbility(
|
new SpellCastControllerTriggeredAbility(
|
||||||
new DamagePlayersEffect(AlchemistsTalentValue.instance, TargetController.OPPONENT), StaticFilters.FILTER_SPELL, false, SetTargetPointer.SPELL
|
new DamagePlayersEffect(AlchemistsTalentValue.instance, TargetController.OPPONENT)
|
||||||
), AlchemistsTalentCondition.instance, "Whenever you cast a spell, if mana from a Treasure " +
|
.setText("{this} deals damage equal to that spell's mana value to each opponent"),
|
||||||
"was spent to cast it, this Class deals damage equal to that spell's mana value to each opponent"
|
StaticFilters.FILTER_SPELL, false, SetTargetPointer.SPELL
|
||||||
), 3)));
|
).withInterveningIf(AlchemistsTalentCondition.instance), 3
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private AlchemistsTalent(final AlchemistsTalent card) {
|
private AlchemistsTalent(final AlchemistsTalent card) {
|
||||||
|
|
@ -84,6 +89,11 @@ enum AlchemistsTalentCondition implements Condition {
|
||||||
Spell spell = (Spell) source.getEffects().get(0).getValue("spellCast");
|
Spell spell = (Spell) source.getEffects().get(0).getValue("spellCast");
|
||||||
return spell != null && ManaPaidSourceWatcher.getTreasurePaid(spell.getSourceId(), game) > 0;
|
return spell != null && ManaPaidSourceWatcher.getTreasurePaid(spell.getSourceId(), game) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "mana from a Treasure was spent to cast it";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AlchemistsTalentValue implements DynamicValue {
|
enum AlchemistsTalentValue implements DynamicValue {
|
||||||
|
|
@ -111,6 +121,6 @@ enum AlchemistsTalentValue implements DynamicValue {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "";
|
return "1";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import mage.constants.*;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.permanent.token.FaerieRogueToken;
|
import mage.game.permanent.token.FaerieRogueToken;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster;
|
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ public final class AlelaCunningConqueror extends CardImpl {
|
||||||
Effect effect = new GoadTargetEffect().setText("goad target creature that player controls");
|
Effect effect = new GoadTargetEffect().setText("goad target creature that player controls");
|
||||||
Ability ability = new OneOrMoreCombatDamagePlayerTriggeredAbility(Zone.BATTLEFIELD, effect, faerieFilter, SetTargetPointer.PLAYER, false);
|
Ability ability = new OneOrMoreCombatDamagePlayerTriggeredAbility(Zone.BATTLEFIELD, effect, faerieFilter, SetTargetPointer.PLAYER, false);
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster());
|
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||||
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,8 @@ import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.FilterSpell;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.common.FilterHistoricSpell;
|
|
||||||
import mage.filter.predicate.mageobject.HistoricPredicate;
|
import mage.filter.predicate.mageobject.HistoricPredicate;
|
||||||
import mage.game.permanent.token.SoldierToken;
|
import mage.game.permanent.token.SoldierToken;
|
||||||
|
|
||||||
|
|
@ -31,7 +30,6 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class AlistairTheBrigadier extends CardImpl {
|
public final class AlistairTheBrigadier extends CardImpl {
|
||||||
|
|
||||||
private static final FilterSpell filter = new FilterHistoricSpell();
|
|
||||||
private static final FilterPermanent filter2 = new FilterControlledPermanent("historic permanents you control");
|
private static final FilterPermanent filter2 = new FilterControlledPermanent("historic permanents you control");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
@ -52,7 +50,7 @@ public final class AlistairTheBrigadier extends CardImpl {
|
||||||
|
|
||||||
// Whenever you cast a historic spell, create a 1/1 white Soldier creature token.
|
// Whenever you cast a historic spell, create a 1/1 white Soldier creature token.
|
||||||
this.addAbility(new SpellCastControllerTriggeredAbility(
|
this.addAbility(new SpellCastControllerTriggeredAbility(
|
||||||
new CreateTokenEffect(new SoldierToken()), filter, false
|
new CreateTokenEffect(new SoldierToken()), StaticFilters.FILTER_SPELL_HISTORIC, false
|
||||||
));
|
));
|
||||||
|
|
||||||
// Whenever Alistair attacks, you may pay {8}. If you do, creatures you control get +X/+X until end of turn, where X is the number of historic permanents you control.
|
// Whenever Alistair attacks, you may pay {8}. If you do, creatures you control get +X/+X until end of turn, where X is the number of historic permanents you control.
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbility;
|
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.KickedCostCondition;
|
import mage.abilities.condition.common.KickedCostCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -35,6 +35,9 @@ public final class AnaBattlemage extends CardImpl {
|
||||||
filter.add(TappedPredicate.UNTAPPED);
|
filter.add(TappedPredicate.UNTAPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Condition condition = new KickedCostCondition("{2}{U}");
|
||||||
|
private static final Condition condition2 = new KickedCostCondition("{1}{B}");
|
||||||
|
|
||||||
public AnaBattlemage(UUID ownerId, CardSetInfo setInfo) {
|
public AnaBattlemage(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
|
||||||
this.subtype.add(SubType.HUMAN);
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
|
@ -46,16 +49,17 @@ public final class AnaBattlemage extends CardImpl {
|
||||||
KickerAbility kickerAbility = new KickerAbility("{2}{U}");
|
KickerAbility kickerAbility = new KickerAbility("{2}{U}");
|
||||||
kickerAbility.addKickerCost("{1}{B}");
|
kickerAbility.addKickerCost("{1}{B}");
|
||||||
this.addAbility(kickerAbility);
|
this.addAbility(kickerAbility);
|
||||||
|
|
||||||
// When Ana Battlemage enters the battlefield, if it was kicked with its {2}{U} kicker, target player discards three cards.
|
// When Ana Battlemage enters the battlefield, if it was kicked with its {2}{U} kicker, target player discards three cards.
|
||||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(3));
|
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(3)).withInterveningIf(condition);
|
||||||
ability.addTarget(new TargetPlayer());
|
ability.addTarget(new TargetPlayer());
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new KickedCostCondition("{2}{U}"),
|
this.addAbility(ability);
|
||||||
"When {this} enters, if it was kicked with its {2}{U} kicker, target player discards three cards."));
|
|
||||||
// When Ana Battlemage enters the battlefield, if it was kicked with its {1}{B} kicker, tap target untapped creature and that creature deals damage equal to its power to its controller.
|
// When Ana Battlemage enters the battlefield, if it was kicked with its {1}{B} kicker, tap target untapped creature and that creature deals damage equal to its power to its controller.
|
||||||
ability = new EntersBattlefieldTriggeredAbility(new AnaBattlemageKickerEffect());
|
ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()).withInterveningIf(condition2);
|
||||||
|
ability.addEffect(new AnaBattlemageEffect());
|
||||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new KickedCostCondition("{1}{B}"),
|
this.addAbility(ability);
|
||||||
"When {this} enters, if it was kicked with its {1}{B} kicker, tap target untapped creature and that creature deals damage equal to its power to its controller."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnaBattlemage(final AnaBattlemage card) {
|
private AnaBattlemage(final AnaBattlemage card) {
|
||||||
|
|
@ -68,34 +72,31 @@ public final class AnaBattlemage extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnaBattlemageKickerEffect extends OneShotEffect {
|
class AnaBattlemageEffect extends OneShotEffect {
|
||||||
|
|
||||||
AnaBattlemageKickerEffect() {
|
AnaBattlemageEffect() {
|
||||||
super(Outcome.Detriment);
|
super(Outcome.Detriment);
|
||||||
this.staticText = "tap target untapped creature and it deals damage equal to its power to its controller";
|
this.staticText = "and it deals damage equal to its power to its controller";
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnaBattlemageKickerEffect(final AnaBattlemageKickerEffect effect) {
|
private AnaBattlemageEffect(final AnaBattlemageEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnaBattlemageKickerEffect copy() {
|
public AnaBattlemageEffect copy() {
|
||||||
return new AnaBattlemageKickerEffect(this);
|
return new AnaBattlemageEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
boolean applied = false;
|
|
||||||
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
if (targetCreature != null) {
|
if (targetCreature == null) {
|
||||||
applied = targetCreature.tap(source, game);
|
return false;
|
||||||
Player controller = game.getPlayer(targetCreature.getControllerId());
|
|
||||||
if (controller != null) {
|
|
||||||
controller.damage(targetCreature.getPower().getValue(), source.getSourceId(), source, game);
|
|
||||||
applied = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return applied;
|
Player controller = game.getPlayer(targetCreature.getControllerId());
|
||||||
|
return controller != null && controller.damage(
|
||||||
|
targetCreature.getPower().getValue(), source.getSourceId(), source, game
|
||||||
|
) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,12 @@ package mage.cards.a;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObjectReference;
|
import mage.MageObjectReference;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
|
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
|
||||||
import mage.abilities.condition.common.MoreThanStartingLifeTotalCondition;
|
import mage.abilities.condition.common.MoreThanStartingLifeTotalCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.keyword.DoubleStrikeAbility;
|
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
|
|
@ -47,13 +46,8 @@ public final class AngelOfDestiny extends CardImpl {
|
||||||
));
|
));
|
||||||
|
|
||||||
// At the beginning of your end step, if you have at least 15 life more than your starting life total, each player Angel of Destiny attacked this turn loses the game.
|
// At the beginning of your end step, if you have at least 15 life more than your starting life total, each player Angel of Destiny attacked this turn loses the game.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfEndStepTriggeredAbility(new AngelOfDestinyLoseEffect())
|
||||||
new BeginningOfEndStepTriggeredAbility(
|
.withInterveningIf(MoreThanStartingLifeTotalCondition.FIFTEEN), new AngelOfDestinyWatcher());
|
||||||
new AngelOfDestinyLoseEffect()
|
|
||||||
), MoreThanStartingLifeTotalCondition.FIFTEEN, "At the beginning of your end step, " +
|
|
||||||
"if you have at least 15 life more than your starting life total, " +
|
|
||||||
"each player {this} attacked this turn loses the game."
|
|
||||||
), new AngelOfDestinyWatcher());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AngelOfDestiny(final AngelOfDestiny card) {
|
private AngelOfDestiny(final AngelOfDestiny card) {
|
||||||
|
|
@ -101,6 +95,7 @@ class AngelOfDestinyLoseEffect extends OneShotEffect {
|
||||||
|
|
||||||
AngelOfDestinyLoseEffect() {
|
AngelOfDestinyLoseEffect() {
|
||||||
super(Outcome.Benefit);
|
super(Outcome.Benefit);
|
||||||
|
staticText = "each player {this} attacked this turn loses the game";
|
||||||
}
|
}
|
||||||
|
|
||||||
private AngelOfDestinyLoseEffect(final AngelOfDestinyLoseEffect effect) {
|
private AngelOfDestinyLoseEffect(final AngelOfDestinyLoseEffect effect) {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
|
@ -48,11 +47,8 @@ public final class AngelicSellSword extends CardImpl {
|
||||||
));
|
));
|
||||||
|
|
||||||
// Whenever Angelic Sell-Sword attacks, if its power is 6 or greater, draw a card.
|
// Whenever Angelic Sell-Sword attacks, if its power is 6 or greater, draw a card.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new AttacksTriggeredAbility(new DrawCardSourceControllerEffect(1))
|
||||||
new AttacksTriggeredAbility(new DrawCardSourceControllerEffect(1)),
|
.withInterveningIf(AngelicSellSwordCondition.instance));
|
||||||
AngelicSellSwordCondition.instance, "Whenever {this} attacks, " +
|
|
||||||
"if its power is 6 or greater, draw a card."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AngelicSellSword(final AngelicSellSword card) {
|
private AngelicSellSword(final AngelicSellSword card) {
|
||||||
|
|
@ -76,4 +72,9 @@ enum AngelicSellSwordCondition implements Condition {
|
||||||
.map(MageInt::getValue)
|
.map(MageInt::getValue)
|
||||||
.orElse(0) >= 6;
|
.orElse(0) >= 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "its power is 6 or greater";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,45 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbility;
|
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
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.SubType;
|
import mage.constants.SubType;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
|
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
|
||||||
*/
|
*/
|
||||||
public final class ApothecaryGeist extends CardImpl {
|
public final class ApothecaryGeist extends CardImpl {
|
||||||
|
|
||||||
private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Elf");
|
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SPIRIT, "you control another Spirit");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(AnotherPredicate.instance);
|
filter.add(AnotherPredicate.instance);
|
||||||
filter.add(SubType.SPIRIT.getPredicate());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
|
||||||
|
|
||||||
public ApothecaryGeist(UUID ownerId, CardSetInfo setInfo) {
|
public ApothecaryGeist(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
|
||||||
this.subtype.add(SubType.SPIRIT);
|
this.subtype.add(SubType.SPIRIT);
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// Flying
|
// Flying
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// When Apothecary Geist enters the battlefield, if you control another Spirit, you gain 3 life.
|
// When Apothecary Geist enters the battlefield, if you control another Spirit, you gain 3 life.
|
||||||
TriggeredAbility triggeredAbility = new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3));
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3)).withInterveningIf(condition));
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
|
||||||
triggeredAbility,
|
|
||||||
new PermanentsOnTheBattlefieldCondition(filter),
|
|
||||||
"When {this} enters, if you control another Spirit, you gain 3 life."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApothecaryGeist(final ApothecaryGeist card) {
|
private ApothecaryGeist(final ApothecaryGeist card) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
|
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.ExileTargetCardCopyAndCastEffect;
|
import mage.abilities.effects.common.ExileTargetCardCopyAndCastEffect;
|
||||||
import mage.abilities.keyword.PrototypeAbility;
|
import mage.abilities.keyword.PrototypeAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -42,12 +41,11 @@ public final class ArcaneProxy extends CardImpl {
|
||||||
this.addAbility(new PrototypeAbility(this, "{1}{U}{U}", 2, 1));
|
this.addAbility(new PrototypeAbility(this, "{1}{U}{U}", 2, 1));
|
||||||
|
|
||||||
// When Arcane Proxy enters the battlefield, if you cast it, exile target instant or sorcery card with mana value less than or equal to Arcane Proxy's power from your graveyard. Copy that card. You may cast the copy without paying its mana cost.
|
// When Arcane Proxy enters the battlefield, if you cast it, exile target instant or sorcery card with mana value less than or equal to Arcane Proxy's power from your graveyard. Copy that card. You may cast the copy without paying its mana cost.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new EntersBattlefieldTriggeredAbility(
|
||||||
new EntersBattlefieldTriggeredAbility(new ExileTargetCardCopyAndCastEffect(true)),
|
new ExileTargetCardCopyAndCastEffect(true)
|
||||||
CastFromEverywhereSourceCondition.instance, "When {this} enters, " +
|
.setText("exile target instant or sorcery card with mana value less than or equal to {this}'s " +
|
||||||
"if you cast it, exile target instant or sorcery card with mana value less than or equal to {this}'s " +
|
"power from your graveyard. Copy that card. You may cast the copy without paying its mana cost")
|
||||||
"power from your graveyard. Copy that card. You may cast the copy without paying its mana cost."
|
).withInterveningIf(CastFromEverywhereSourceCondition.instance);
|
||||||
);
|
|
||||||
ability.addTarget(new TargetCardInYourGraveyard(filter));
|
ability.addTarget(new TargetCardInYourGraveyard(filter));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbility;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.KickedCondition;
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.DamageTargetEffect;
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
|
|
@ -40,19 +39,19 @@ public final class ArchangelOfWrath extends CardImpl {
|
||||||
// Lifelink
|
// Lifelink
|
||||||
this.addAbility(LifelinkAbility.getInstance());
|
this.addAbility(LifelinkAbility.getInstance());
|
||||||
|
|
||||||
TriggeredAbility triggeredAbility = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2));
|
|
||||||
triggeredAbility.addTarget(new TargetAnyTarget());
|
|
||||||
// When Archangel of Wrath enters the battlefield, if it was kicked, it deals 2 damage to any target.
|
// When Archangel of Wrath enters the battlefield, if it was kicked, it deals 2 damage to any target.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new EntersBattlefieldTriggeredAbility(
|
||||||
triggeredAbility, KickedCondition.ONCE, "When {this} enters, " +
|
new DamageTargetEffect(2, "it")
|
||||||
"if it was kicked, it deals 2 damage to any target."
|
).withInterveningIf(KickedCondition.ONCE);
|
||||||
));
|
ability.addTarget(new TargetAnyTarget());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
// When Archangel of Wrath enters the battlefield, if it was kicked twice, it deals 2 damage to any target.
|
// When Archangel of Wrath enters the battlefield, if it was kicked twice, it deals 2 damage to any target.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
ability = new EntersBattlefieldTriggeredAbility(
|
||||||
triggeredAbility.copy(), KickedCondition.TWICE, "When {this} enters, " +
|
new DamageTargetEffect(2, "it")
|
||||||
"if it was kicked twice, it deals 2 damage to any target."
|
).withInterveningIf(KickedCondition.TWICE);
|
||||||
));
|
ability.addTarget(new TargetAnyTarget());
|
||||||
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArchangelOfWrath(final ArchangelOfWrath card) {
|
private ArchangelOfWrath(final ArchangelOfWrath card) {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
|
||||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||||
import mage.abilities.common.EntersBattlefieldAbility;
|
import mage.abilities.common.EntersBattlefieldAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
|
|
@ -13,9 +12,11 @@ import mage.abilities.effects.common.LoseGameSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
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.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
|
|
@ -33,7 +34,7 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class ArchfiendOfTheDross extends CardImpl {
|
public final class ArchfiendOfTheDross extends CardImpl {
|
||||||
|
|
||||||
private static final Condition condition = new SourceHasCounterCondition(CounterType.OIL, 0, 0);
|
private static final Condition condition = new SourceHasCounterCondition(CounterType.OIL, ComparisonType.EQUAL_TO, 0);
|
||||||
|
|
||||||
public ArchfiendOfTheDross(UUID ownerId, CardSetInfo setInfo) {
|
public ArchfiendOfTheDross(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
|
import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.effects.common.BecomesMonarchSourceEffect;
|
import mage.abilities.effects.common.BecomesMonarchSourceEffect;
|
||||||
import mage.abilities.effects.common.DrawCardTargetEffect;
|
import mage.abilities.effects.common.DrawCardTargetEffect;
|
||||||
import mage.abilities.hint.common.MonarchHint;
|
import mage.abilities.hint.common.MonarchHint;
|
||||||
|
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;
|
||||||
|
|
@ -15,6 +16,7 @@ import mage.constants.SubType;
|
||||||
import mage.constants.TargetController;
|
import mage.constants.TargetController;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.predicate.mageobject.CommanderPredicate;
|
import mage.filter.predicate.mageobject.CommanderPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -39,13 +41,11 @@ public final class ArchivistOfGondor extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// When your commander deals combat damage to a player, if there is no monarch, you become the monarch.
|
// When your commander deals combat damage to a player, if there is no monarch, you become the monarch.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility(
|
||||||
new DealsDamageToAPlayerAllTriggeredAbility(
|
new BecomesMonarchSourceEffect(), filter, false,
|
||||||
new BecomesMonarchSourceEffect(), filter, false,
|
SetTargetPointer.NONE, true
|
||||||
SetTargetPointer.NONE, true
|
).setTriggerPhrase("When your commander deals combat damage to a player, ")
|
||||||
), (game, source) -> game.getMonarchId() == null, "When your commander " +
|
.withInterveningIf(ArchivistOfGondorCondition.instance).addHint(MonarchHint.instance));
|
||||||
"deals combat damage to a player, if there is no monarch, you become the monarch."
|
|
||||||
).addHint(MonarchHint.instance));
|
|
||||||
|
|
||||||
// At the beginning of the monarch's end step, that player draws a card.
|
// At the beginning of the monarch's end step, that player draws a card.
|
||||||
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||||
|
|
@ -62,3 +62,17 @@ public final class ArchivistOfGondor extends CardImpl {
|
||||||
return new ArchivistOfGondor(this);
|
return new ArchivistOfGondor(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ArchivistOfGondorCondition implements Condition {
|
||||||
|
instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return game.getMonarchId() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "there is no monarch";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -30,12 +29,9 @@ public final class ArchmageAscension extends CardImpl {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
|
||||||
|
|
||||||
// At the beginning of each end step, if you drew two or more cards this turn, you may put a quest counter on Archmage Ascension.
|
// At the beginning of each end step, if you drew two or more cards this turn, you may put a quest counter on Archmage Ascension.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||||
new BeginningOfEndStepTriggeredAbility(
|
TargetController.EACH_PLAYER, new AddCountersSourceEffect(CounterType.QUEST.createInstance()),
|
||||||
TargetController.EACH_PLAYER, new AddCountersSourceEffect(CounterType.QUEST.createInstance(1)),
|
true, ArchmageAscensionCondition.instance
|
||||||
true
|
|
||||||
), ArchmageAscensionCondition.instance, "At the beginning of each end step, " +
|
|
||||||
"if you drew two or more cards this turn, you may put a quest counter on {this}."
|
|
||||||
), new CardsAmountDrawnThisTurnWatcher());
|
), new CardsAmountDrawnThisTurnWatcher());
|
||||||
|
|
||||||
// As long as Archmage Ascension has six or more quest counters on it, if you would draw a card,
|
// As long as Archmage Ascension has six or more quest counters on it, if you would draw a card,
|
||||||
|
|
@ -61,6 +57,11 @@ enum ArchmageAscensionCondition implements Condition {
|
||||||
CardsAmountDrawnThisTurnWatcher watcher = game.getState().getWatcher(CardsAmountDrawnThisTurnWatcher.class);
|
CardsAmountDrawnThisTurnWatcher watcher = game.getState().getWatcher(CardsAmountDrawnThisTurnWatcher.class);
|
||||||
return watcher != null && watcher.getAmountCardsDrawn(source.getControllerId()) >= 2;
|
return watcher != null && watcher.getAmountCardsDrawn(source.getControllerId()) >= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "you drew two or more cards this turn";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl {
|
class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl {
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,20 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.FullPartyCondition;
|
import mage.abilities.condition.common.FullPartyCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.dynamicvalue.common.PartyCount;
|
import mage.abilities.dynamicvalue.common.PartyCount;
|
||||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect;
|
import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect;
|
||||||
import mage.abilities.hint.common.PartyCountHint;
|
import mage.abilities.hint.common.PartyCountHint;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -35,19 +36,16 @@ public final class ArchpriestOfIona extends CardImpl {
|
||||||
// Archpriest of Iona's power is equal to the number of creatures in your party.
|
// Archpriest of Iona's power is equal to the number of creatures in your party.
|
||||||
this.addAbility(new SimpleStaticAbility(
|
this.addAbility(new SimpleStaticAbility(
|
||||||
Zone.ALL,
|
Zone.ALL,
|
||||||
new SetBasePowerSourceEffect(
|
new SetBasePowerSourceEffect(PartyCount.instance)
|
||||||
PartyCount.instance
|
.setText("{this}'s power is equal to the number of creatures in your party. " + PartyCount.getReminder())
|
||||||
).setText("{this}'s power is equal to the number of creatures in your party. " + PartyCount.getReminder())
|
|
||||||
).addHint(PartyCountHint.instance));
|
).addHint(PartyCountHint.instance));
|
||||||
|
|
||||||
// At the beginning of combat on your turn, if you have a full party, target creature gets +1/+1 and gains flying until end of turn.
|
// At the beginning of combat on your turn, if you have a full party, target creature gets +1/+1 and gains flying until end of turn.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new BeginningOfCombatTriggeredAbility(
|
||||||
new BeginningOfCombatTriggeredAbility(
|
new BoostTargetEffect(1, 1).setText("target creature gets +1/+1")
|
||||||
new BoostTargetEffect(1, 1, Duration.EndOfTurn)
|
).withInterveningIf(FullPartyCondition.instance);
|
||||||
), FullPartyCondition.instance, "At the beginning of combat on your turn, " +
|
ability.addEffect(new GainAbilityTargetEffect(FlyingAbility.getInstance())
|
||||||
"if you have a full party, target creature gets +1/+1 and gains flying until end of turn."
|
.setText("and gains flying until end of turn"));
|
||||||
);
|
|
||||||
ability.addEffect(new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn));
|
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,18 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
|
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.keyword.HasteAbility;
|
import mage.abilities.keyword.HasteAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.util.CardUtil;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -39,17 +39,10 @@ public final class ArclightPhoenix extends CardImpl {
|
||||||
this.addAbility(HasteAbility.getInstance());
|
this.addAbility(HasteAbility.getInstance());
|
||||||
|
|
||||||
// At the beginning of combat on your turn, if you cast 3 or more instants and/or sorceries this turn, return Arclight Phoenix from your graveyard to the battlefield.
|
// At the beginning of combat on your turn, if you cast 3 or more instants and/or sorceries this turn, return Arclight Phoenix from your graveyard to the battlefield.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfCombatTriggeredAbility(
|
||||||
new BeginningOfCombatTriggeredAbility(
|
Zone.GRAVEYARD, TargetController.YOU,
|
||||||
Zone.GRAVEYARD,
|
new ReturnSourceFromGraveyardToBattlefieldEffect(), false
|
||||||
TargetController.YOU, new ReturnSourceFromGraveyardToBattlefieldEffect(),
|
).withInterveningIf(ArclightPhoenixCondition.instance), new ArclightPhoenixWatcher());
|
||||||
false
|
|
||||||
), ArclightPhoenixCondition.instance,
|
|
||||||
"At the beginning of combat on your turn, "
|
|
||||||
+ "if you've cast three or more instant "
|
|
||||||
+ "and sorcery spells this turn, return {this} "
|
|
||||||
+ "from your graveyard to the battlefield."
|
|
||||||
), new ArclightPhoenixWatcher());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArclightPhoenix(final ArclightPhoenix card) {
|
private ArclightPhoenix(final ArclightPhoenix card) {
|
||||||
|
|
@ -67,8 +60,12 @@ enum ArclightPhoenixCondition implements Condition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
ArclightPhoenixWatcher watcher = game.getState().getWatcher(ArclightPhoenixWatcher.class);
|
return ArclightPhoenixWatcher.getInstantSorceryCount(game, source);
|
||||||
return watcher != null && watcher.getInstantSorceryCount(source.getControllerId()) > 2;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "you've cast three or more instant and sorcery spells this turn";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,15 +79,12 @@ class ArclightPhoenixWatcher extends Watcher {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void watch(GameEvent event, Game game) {
|
public void watch(GameEvent event, Game game) {
|
||||||
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
|
if (event.getType() != GameEvent.EventType.SPELL_CAST) {
|
||||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
return;
|
||||||
if (spell == null || !spell.isInstantOrSorcery(game)) {
|
}
|
||||||
return;
|
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||||
}
|
if (spell != null && spell.isInstantOrSorcery(game)) {
|
||||||
this.instantSorceryCount.putIfAbsent(spell.getControllerId(), 0);
|
this.instantSorceryCount.compute(spell.getControllerId(), CardUtil::setOrIncrementValue);
|
||||||
this.instantSorceryCount.compute(
|
|
||||||
spell.getControllerId(), (k, a) -> a + 1
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,7 +94,11 @@ class ArclightPhoenixWatcher extends Watcher {
|
||||||
this.instantSorceryCount.clear();
|
this.instantSorceryCount.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getInstantSorceryCount(UUID playerId) {
|
static boolean getInstantSorceryCount(Game game, Ability source) {
|
||||||
return this.instantSorceryCount.getOrDefault(playerId, 0);
|
return game
|
||||||
|
.getState()
|
||||||
|
.getWatcher(ArclightPhoenixWatcher.class)
|
||||||
|
.instantSorceryCount
|
||||||
|
.getOrDefault(source.getControllerId(), 0) >= 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterNoncreatureCard;
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.common.TargetCardInLibrary;
|
import mage.target.common.TargetCardInLibrary;
|
||||||
|
|
||||||
|
|
@ -22,9 +22,10 @@ import mage.target.common.TargetCardInLibrary;
|
||||||
*/
|
*/
|
||||||
public final class ArcumDagsson extends CardImpl {
|
public final class ArcumDagsson extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCard filter = new FilterNoncreatureCard("noncreature artifact card");
|
private static final FilterCard filter = new FilterCard("noncreature artifact card");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
|
||||||
filter.add(CardType.ARTIFACT.getPredicate());
|
filter.add(CardType.ARTIFACT.getPredicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class ArixmethesSlumberingIsle extends CardImpl {
|
public final class ArixmethesSlumberingIsle extends CardImpl {
|
||||||
|
|
||||||
private static final Condition condition
|
private static final Condition condition = new SourceHasCounterCondition(CounterType.SLUMBER);
|
||||||
= new SourceHasCounterCondition(CounterType.SLUMBER, 1, Integer.MAX_VALUE);
|
|
||||||
|
|
||||||
public ArixmethesSlumberingIsle(UUID ownerId, CardSetInfo setInfo) {
|
public ArixmethesSlumberingIsle(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}");
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster;
|
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ public final class ArmWithAether extends CardImpl {
|
||||||
// Until end of turn, creatures you control gain "Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand."
|
// Until end of turn, creatures you control gain "Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand."
|
||||||
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandTargetEffect(), false, true);
|
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandTargetEffect(), false, true);
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster());
|
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||||
|
|
||||||
Effect effect = new GainAbilityControlledEffect(ability, Duration.EndOfTurn, new FilterCreaturePermanent());
|
Effect effect = new GainAbilityControlledEffect(ability, Duration.EndOfTurn, new FilterCreaturePermanent());
|
||||||
effect.setText("Until end of turn, creatures you control gain \"Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand.\"");
|
effect.setText("Until end of turn, creatures you control gain \"Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand.\"");
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||||
|
|
@ -12,25 +12,19 @@ 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 mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.FilterPermanent;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class ArmoryGuard extends CardImpl {
|
public final class ArmoryGuard extends CardImpl {
|
||||||
|
|
||||||
private static final String rule = "Armory Guard has vigilance as long as you control a Gate";
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.GATE));
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterPermanent("Gate");
|
|
||||||
|
|
||||||
static {
|
|
||||||
filter.add(SubType.GATE.getPredicate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArmoryGuard(UUID ownerId, CardSetInfo setInfo) {
|
public ArmoryGuard(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
|
||||||
this.subtype.add(SubType.GIANT);
|
this.subtype.add(SubType.GIANT);
|
||||||
this.subtype.add(SubType.SOLDIER);
|
this.subtype.add(SubType.SOLDIER);
|
||||||
|
|
||||||
|
|
@ -38,8 +32,10 @@ public final class ArmoryGuard extends CardImpl {
|
||||||
this.toughness = new MageInt(5);
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
// Armory Guard has vigilance as long as you control a Gate.
|
// Armory Guard has vigilance as long as you control a Gate.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new GainAbilitySourceEffect(VigilanceAbility.getInstance()), new PermanentsOnTheBattlefieldCondition(filter), rule);
|
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
|
||||||
this.addAbility(new SimpleStaticAbility(effect));
|
new GainAbilitySourceEffect(VigilanceAbility.getInstance()),
|
||||||
|
condition, "{this} has vigilance as long as you control a Gate"
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArmoryGuard(final ArmoryGuard card) {
|
private ArmoryGuard(final ArmoryGuard card) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.OpponentsLostLifeCondition;
|
import mage.abilities.condition.common.OpponentsLostLifeCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
|
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
|
||||||
import mage.abilities.hint.common.OpponentsLostLifeHint;
|
import mage.abilities.hint.common.OpponentsLostLifeHint;
|
||||||
|
|
@ -29,13 +28,10 @@ public final class ArrogantOutlaw extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// When Arrogant Outlaw enters the battlefield, if an opponent lost life this turn, each opponent loses 2 life and you gain 2 life.
|
// When Arrogant Outlaw enters the battlefield, if an opponent lost life this turn, each opponent loses 2 life and you gain 2 life.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new EntersBattlefieldTriggeredAbility(
|
||||||
new EntersBattlefieldTriggeredAbility(
|
new LoseLifeOpponentsEffect(2), false
|
||||||
new LoseLifeOpponentsEffect(2), false
|
).withInterveningIf(OpponentsLostLifeCondition.instance);
|
||||||
), OpponentsLostLifeCondition.instance, "When {this} enters, " +
|
ability.addEffect(new GainLifeEffect(2).concatBy("and"));
|
||||||
"if an opponent lost life this turn, each opponent loses 2 life and you gain 2 life."
|
|
||||||
);
|
|
||||||
ability.addEffect(new GainLifeEffect(2));
|
|
||||||
this.addAbility(ability.addHint(OpponentsLostLifeHint.instance));
|
this.addAbility(ability.addHint(OpponentsLostLifeHint.instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,30 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.effects.common.CounterTargetEffect;
|
import mage.abilities.effects.common.CounterTargetEffect;
|
||||||
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.filter.common.FilterArtifactSpell;
|
import mage.filter.FilterSpell;
|
||||||
import mage.target.TargetSpell;
|
import mage.target.TargetSpell;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Jgod
|
* @author Jgod
|
||||||
*/
|
*/
|
||||||
public final class ArtifactBlast extends CardImpl {
|
public final class ArtifactBlast extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterSpell filter = new FilterSpell("artifact spell");
|
||||||
|
static {
|
||||||
|
filter.add(CardType.ARTIFACT.getPredicate());
|
||||||
|
}
|
||||||
|
|
||||||
public ArtifactBlast(UUID ownerId, CardSetInfo setInfo) {
|
public ArtifactBlast(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");
|
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");
|
||||||
|
|
||||||
// Counter target artifact spell.
|
// Counter target artifact spell.
|
||||||
this.getSpellAbility().addTarget(new TargetSpell(new FilterArtifactSpell()));
|
this.getSpellAbility().addTarget(new TargetSpell(filter));
|
||||||
this.getSpellAbility().addEffect(new CounterTargetEffect());
|
this.getSpellAbility().addEffect(new CounterTargetEffect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import mage.constants.Outcome;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterNoncreatureCard;
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.DamageEvent;
|
import mage.game.events.DamageEvent;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
|
@ -33,7 +33,11 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class ArtistsTalent extends CardImpl {
|
public final class ArtistsTalent extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCard filter = new FilterNoncreatureCard("noncreature spells");
|
private static final FilterCard filter = new FilterCard("noncreature spells");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
|
||||||
|
}
|
||||||
|
|
||||||
public ArtistsTalent(UUID ownerId, CardSetInfo setInfo) {
|
public ArtistsTalent(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.common.BecomesBlockedSourceTriggeredAbility;
|
import mage.abilities.common.BecomesBlockedSourceTriggeredAbility;
|
||||||
import mage.abilities.condition.common.HateCondition;
|
import mage.abilities.condition.common.HateCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.dynamicvalue.common.BlockingCreatureCount;
|
import mage.abilities.dynamicvalue.common.BlockingCreatureCount;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect;
|
import mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect;
|
||||||
|
|
@ -15,13 +13,12 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||||
import mage.abilities.keyword.DoubleStrikeAbility;
|
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||||
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.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.common.LifeLossOtherFromCombatWatcher;
|
import mage.watchers.common.LifeLossOtherFromCombatWatcher;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Styxo
|
* @author Styxo
|
||||||
*/
|
*/
|
||||||
|
|
@ -43,10 +40,8 @@ public final class AsajjVentress extends CardImpl {
|
||||||
this.addAbility(new BecomesBlockedSourceTriggeredAbility(effect, false));
|
this.addAbility(new BecomesBlockedSourceTriggeredAbility(effect, false));
|
||||||
|
|
||||||
// <i>Hate</i> — Whenever Asajj Ventress attacks, if an opponent lost life from a source other than combat damage this turn, target creature blocks this turn if able.
|
// <i>Hate</i> — Whenever Asajj Ventress attacks, if an opponent lost life from a source other than combat damage this turn, target creature blocks this turn if able.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new AttacksTriggeredAbility(new BlocksIfAbleTargetEffect(Duration.EndOfTurn), false)
|
||||||
new AttacksTriggeredAbility(new BlocksIfAbleTargetEffect(Duration.EndOfTurn), false),
|
.withInterveningIf(HateCondition.instance).setAbilityWord(AbilityWord.HATE);
|
||||||
HateCondition.instance,
|
|
||||||
"<i>Hate</i> — Whenever Asajj Ventress attacks, if an opponent lost life from a source other than combat damage this turn, target creature blocks this turn if able");
|
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
this.addAbility(ability, new LifeLossOtherFromCombatWatcher());
|
this.addAbility(ability, new LifeLossOtherFromCombatWatcher());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.condition.common.CelebrationCondition;
|
import mage.abilities.condition.common.CelebrationCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.keyword.HasteAbility;
|
import mage.abilities.keyword.HasteAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -36,11 +35,8 @@ public final class AshPartyCrasher extends CardImpl {
|
||||||
this.addAbility(HasteAbility.getInstance());
|
this.addAbility(HasteAbility.getInstance());
|
||||||
|
|
||||||
// Celebration -- Whenever Ash, Party Crasher attacks, if two or more nonland permanents entered the battlefield under your control this turn, put a +1/+1 counter on Ash.
|
// Celebration -- Whenever Ash, Party Crasher attacks, if two or more nonland permanents entered the battlefield under your control this turn, put a +1/+1 counter on Ash.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new AttacksTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), false)
|
||||||
new AttacksTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), false),
|
.withInterveningIf(CelebrationCondition.instance);
|
||||||
CelebrationCondition.instance, "Whenever {this} attacks, if two or more nonland permanents " +
|
|
||||||
"entered the battlefield under your control this turn, put a +1/+1 counter on {this}."
|
|
||||||
);
|
|
||||||
ability.setAbilityWord(AbilityWord.CELEBRATION);
|
ability.setAbilityWord(AbilityWord.CELEBRATION);
|
||||||
ability.addHint(CelebrationCondition.getHint());
|
ability.addHint(CelebrationCondition.getHint());
|
||||||
this.addAbility(ability, new PermanentsEnteredBattlefieldWatcher());
|
this.addAbility(ability, new PermanentsEnteredBattlefieldWatcher());
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster;
|
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ public final class AshlingTheExtinguisher extends CardImpl {
|
||||||
Effect effect = new SacrificeTargetEffect().setText("choose target creature that player controls. The player sacrifices that creature");
|
Effect effect = new SacrificeTargetEffect().setText("choose target creature that player controls. The player sacrifices that creature");
|
||||||
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true);
|
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true);
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster());
|
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,13 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.CardsInHandCondition;
|
import mage.abilities.condition.common.CardsInHandCondition;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.Effect;
|
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
|
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
|
||||||
import mage.abilities.keyword.MadnessAbility;
|
import mage.abilities.keyword.MadnessAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
|
@ -24,6 +23,8 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class AsylumVisitor extends CardImpl {
|
public final class AsylumVisitor extends CardImpl {
|
||||||
|
|
||||||
|
private static final Condition condition = new CardsInHandCondition(ComparisonType.EQUAL_TO, 0, TargetController.ACTIVE);
|
||||||
|
|
||||||
public AsylumVisitor(UUID ownerId, CardSetInfo setInfo) {
|
public AsylumVisitor(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
|
||||||
this.subtype.add(SubType.VAMPIRE);
|
this.subtype.add(SubType.VAMPIRE);
|
||||||
|
|
@ -32,12 +33,10 @@ public final class AsylumVisitor extends CardImpl {
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
// At the beginning of each player's upkeep, if that player has no cards in hand, you draw a card and you lose 1 life.
|
// At the beginning of each player's upkeep, if that player has no cards in hand, you draw a card and you lose 1 life.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new BeginningOfUpkeepTriggeredAbility(
|
||||||
new BeginningOfUpkeepTriggeredAbility(TargetController.ANY, new DrawCardSourceControllerEffect(1, true), false),
|
TargetController.ANY, new DrawCardSourceControllerEffect(1, true), false
|
||||||
new CardsInHandCondition(ComparisonType.EQUAL_TO, 0, TargetController.ACTIVE),
|
).withInterveningIf(condition);
|
||||||
"At the beginning of each player's upkeep, if that player has no cards in hand, you draw a card and you lose 1 life.");
|
ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and"));
|
||||||
Effect effect = new LoseLifeSourceControllerEffect(1);
|
|
||||||
ability.addEffect(effect);
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// Madness {1}{B}
|
// Madness {1}{B}
|
||||||
|
|
|
||||||
|
|
@ -2,32 +2,26 @@ package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.DiesSourceTriggeredAbility;
|
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue;
|
import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue;
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
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.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.TargetController;
|
import mage.filter.common.FilterControlledPlaneswalkerPermanent;
|
||||||
import mage.filter.FilterPermanent;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class AttendantOfVraska extends CardImpl {
|
public final class AttendantOfVraska extends CardImpl {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterPermanent("a Vraska planeswalker");
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
|
||||||
|
new FilterControlledPlaneswalkerPermanent(SubType.VRASKA, "you control a Vraska planeswalker")
|
||||||
static {
|
);
|
||||||
filter.add(TargetController.YOU.getControllerPredicate());
|
|
||||||
filter.add(CardType.PLANESWALKER.getPredicate());
|
|
||||||
filter.add(SubType.VRASKA.getPredicate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public AttendantOfVraska(UUID ownerId, CardSetInfo setInfo) {
|
public AttendantOfVraska(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}");
|
||||||
|
|
@ -38,13 +32,8 @@ public final class AttendantOfVraska extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// When Attendant of Vraska dies, if you control a Vraska planeswalker, you gain life equal to Attendant of Vraska's power.
|
// When Attendant of Vraska dies, if you control a Vraska planeswalker, you gain life equal to Attendant of Vraska's power.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new DiesSourceTriggeredAbility(new GainLifeEffect(SourcePermanentPowerValue.NOT_NEGATIVE)
|
||||||
new DiesSourceTriggeredAbility(new GainLifeEffect(
|
.setText("you gain life equal to {this}'s power"), false).withInterveningIf(condition));
|
||||||
SourcePermanentPowerValue.NOT_NEGATIVE
|
|
||||||
), false), new PermanentsOnTheBattlefieldCondition(filter),
|
|
||||||
"When {this} dies, if you control a Vraska planeswalker, "
|
|
||||||
+ "you gain life equal to {this}'s power."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AttendantOfVraska(final AttendantOfVraska card) {
|
private AttendantOfVraska(final AttendantOfVraska card) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
|
@ -18,11 +17,11 @@ import mage.game.permanent.Permanent;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author spjspj
|
* @author spjspj
|
||||||
*/
|
*/
|
||||||
public final class AuramancersGuise extends CardImpl {
|
public final class AuramancersGuise extends CardImpl {
|
||||||
|
|
@ -36,16 +35,16 @@ public final class AuramancersGuise extends CardImpl {
|
||||||
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||||
this.getSpellAbility().addTarget(auraTarget);
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||||
Ability ability = new EnchantAbility(auraTarget);
|
this.addAbility(new EnchantAbility(auraTarget));
|
||||||
this.addAbility(ability);
|
|
||||||
|
|
||||||
// Enchanted creature gets +2/+2 for each Aura attached to it and has vigilance.
|
// Enchanted creature gets +2/+2 for each Aura attached to it and has vigilance.
|
||||||
DynamicValue ptBoost = new EnchantedCreatureAurasCount();
|
Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(
|
||||||
BoostEnchantedEffect effect = new BoostEnchantedEffect(ptBoost, ptBoost, Duration.WhileOnBattlefield);
|
AuramancersGuiseValue.instance, AuramancersGuiseValue.instance, Duration.WhileOnBattlefield
|
||||||
effect.setText("Enchanted creature gets +2/+2 for each Aura attached to it");
|
));
|
||||||
SimpleStaticAbility ability2 = new SimpleStaticAbility(effect);
|
ability.addEffect(new GainAbilityAttachedEffect(
|
||||||
ability2.addEffect(new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA).setText("and has vigilance"));
|
VigilanceAbility.getInstance(), AttachmentType.AURA
|
||||||
this.addAbility(ability2);
|
).setText("and has vigilance"));
|
||||||
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AuramancersGuise(final AuramancersGuise card) {
|
private AuramancersGuise(final AuramancersGuise card) {
|
||||||
|
|
@ -58,48 +57,40 @@ public final class AuramancersGuise extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EnchantedCreatureAurasCount implements DynamicValue {
|
enum AuramancersGuiseValue implements DynamicValue {
|
||||||
|
instance;
|
||||||
public EnchantedCreatureAurasCount() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private EnchantedCreatureAurasCount(final EnchantedCreatureAurasCount dynamicValue) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||||
int count = 0;
|
Permanent permanent = Optional
|
||||||
Permanent aura = game.getPermanent(sourceAbility.getSourceId());
|
.ofNullable(sourceAbility.getSourcePermanentIfItStillExists(game))
|
||||||
if (aura != null) {
|
.map(Permanent::getAttachedTo)
|
||||||
Permanent permanent = game.getPermanent(aura.getAttachedTo());
|
.map(game::getPermanent)
|
||||||
if (permanent != null) {
|
.orElse(null);
|
||||||
List<UUID> attachments = permanent.getAttachments();
|
return permanent != null
|
||||||
for (UUID attachmentId : attachments) {
|
? 2 * permanent
|
||||||
Permanent attached = game.getPermanent(attachmentId);
|
.getAttachments()
|
||||||
if (attached != null && attached.hasSubtype(SubType.AURA, game)) {
|
.stream()
|
||||||
count++;
|
.map(game::getPermanent)
|
||||||
}
|
.filter(Objects::nonNull)
|
||||||
|
.filter(p -> p.hasSubtype(SubType.AURA, game))
|
||||||
}
|
.mapToInt(x -> 1)
|
||||||
return 2 * count;
|
.sum()
|
||||||
}
|
: 0;
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnchantedCreatureAurasCount copy() {
|
public AuramancersGuiseValue copy() {
|
||||||
return new EnchantedCreatureAurasCount(this);
|
return this;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "1";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return "of its auras";
|
return "for each Aura attached to it";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "2";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,35 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.constants.SubType;
|
|
||||||
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.SubType;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterTeamPermanent;
|
import mage.filter.common.FilterTeamPermanent;
|
||||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class AuroraChampion extends CardImpl {
|
public final class AuroraChampion extends CardImpl {
|
||||||
|
|
||||||
private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "another Warrior");
|
private static final FilterPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "your team controls another Warrior");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(AnotherPredicate.instance);
|
filter.add(AnotherPredicate.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, false);
|
||||||
|
|
||||||
public AuroraChampion(UUID ownerId, CardSetInfo setInfo) {
|
public AuroraChampion(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
|
||||||
|
|
||||||
|
|
@ -37,11 +39,7 @@ public final class AuroraChampion extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// Whenever Aurora Champion attacks, if your team controls another Warrior, tap target creature.
|
// Whenever Aurora Champion attacks, if your team controls another Warrior, tap target creature.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new AttacksTriggeredAbility(new TapTargetEffect(), false).withInterveningIf(condition);
|
||||||
new AttacksTriggeredAbility(new TapTargetEffect(), false),
|
|
||||||
new PermanentsOnTheBattlefieldCondition(filter),
|
|
||||||
"Whenever {this} attacks, if your team controls another Warrior, tap target creature."
|
|
||||||
);
|
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import mage.abilities.keyword.MenaceAbility;
|
||||||
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.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.target.common.TargetCardInLibrary;
|
import mage.target.common.TargetCardInLibrary;
|
||||||
|
|
@ -24,8 +25,8 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class AyarasOathsworn extends CardImpl {
|
public final class AyarasOathsworn extends CardImpl {
|
||||||
|
|
||||||
private static final Condition condition1 = new SourceHasCounterCondition(CounterType.P1P1, 0, 3);
|
private static final Condition condition1 = new SourceHasCounterCondition(CounterType.P1P1, ComparisonType.FEWER_THAN, 4);
|
||||||
private static final Condition condition2 = new SourceHasCounterCondition(CounterType.P1P1, 4, 4);
|
private static final Condition condition2 = new SourceHasCounterCondition(CounterType.P1P1, ComparisonType.EQUAL_TO, 4);
|
||||||
|
|
||||||
public AyarasOathsworn(UUID ownerId, CardSetInfo setInfo) {
|
public AyarasOathsworn(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,33 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
|
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
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.players.Player;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class AzorsElocutors extends CardImpl {
|
public final class AzorsElocutors extends CardImpl {
|
||||||
|
|
||||||
|
private static final Condition condition = new SourceHasCounterCondition(CounterType.FILIBUSTER, 5);
|
||||||
|
|
||||||
public AzorsElocutors(UUID ownerId, CardSetInfo setInfo) {
|
public AzorsElocutors(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/U}{W/U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/U}{W/U}");
|
||||||
this.subtype.add(SubType.HUMAN);
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
|
@ -32,7 +37,13 @@ public final class AzorsElocutors extends CardImpl {
|
||||||
this.toughness = new MageInt(5);
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
// At the beginning of your upkeep, put a filibuster counter on Azor's Elocutors. Then if Azor's Elocutors has five or more filibuster counters on it, you win the game.
|
// At the beginning of your upkeep, put a filibuster counter on Azor's Elocutors. Then if Azor's Elocutors has five or more filibuster counters on it, you win the game.
|
||||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AzorsElocutorsEffect()));
|
Ability ability = new BeginningOfUpkeepTriggeredAbility(
|
||||||
|
new AddCountersSourceEffect(CounterType.FILIBUSTER.createInstance())
|
||||||
|
);
|
||||||
|
ability.addEffect(new ConditionalOneShotEffect(
|
||||||
|
new WinGameSourceControllerEffect(), condition,
|
||||||
|
"Then if {this} has five or more filibuster counters on it, you win the game"
|
||||||
|
));
|
||||||
|
|
||||||
// Whenever a source deals damage to you, remove a filibuster counter from Azor's Elocutors.
|
// Whenever a source deals damage to you, remove a filibuster counter from Azor's Elocutors.
|
||||||
this.addAbility(new AzorsElocutorsTriggeredAbility());
|
this.addAbility(new AzorsElocutorsTriggeredAbility());
|
||||||
|
|
@ -71,39 +82,6 @@ class AzorsElocutorsTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
return event.getTargetId().equals(this.controllerId);
|
return isControlledBy(event.getTargetId());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AzorsElocutorsEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
AzorsElocutorsEffect() {
|
|
||||||
super(Outcome.Benefit);
|
|
||||||
staticText = "put a filibuster counter on Azor's Elocutors. Then if Azor's Elocutors has five or more filibuster counters on it, you win the game";
|
|
||||||
}
|
|
||||||
|
|
||||||
private AzorsElocutorsEffect(final AzorsElocutorsEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
|
||||||
if (permanent != null) {
|
|
||||||
permanent.addCounters(CounterType.FILIBUSTER.createInstance(), source.getControllerId(), source, game);
|
|
||||||
if (permanent.getCounters(game).getCount(CounterType.FILIBUSTER) > 4) {
|
|
||||||
Player player = game.getPlayer(permanent.getControllerId());
|
|
||||||
if (player != null) {
|
|
||||||
player.won(game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AzorsElocutorsEffect copy() {
|
|
||||||
return new AzorsElocutorsEffect(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
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.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.permanent.token.SpiritToken;
|
import mage.game.permanent.token.SpiritToken;
|
||||||
|
|
@ -27,7 +26,7 @@ public final class BakuAltar extends CardImpl {
|
||||||
public BakuAltar(UUID ownerId, CardSetInfo setInfo) {
|
public BakuAltar(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
||||||
// Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Baku Altar.
|
// Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Baku Altar.
|
||||||
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance(1)), StaticFilters.FILTER_SPIRIT_OR_ARCANE_CARD, true));
|
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance(1)), StaticFilters.FILTER_SPELL_SPIRIT_OR_ARCANE, true));
|
||||||
// {2}, {tap}, Remove a ki counter from Baku Altar: Create a 1/1 colorless Spirit creature token.
|
// {2}, {tap}, Remove a ki counter from Baku Altar: Create a 1/1 colorless Spirit creature token.
|
||||||
Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new SpiritToken(), 1), new GenericManaCost(2));
|
Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new SpiritToken(), 1), new GenericManaCost(2));
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,20 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||||
import mage.abilities.condition.common.KickedCondition;
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.SacrificeTargetEffect;
|
import mage.abilities.effects.common.SacrificeTargetEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
import mage.abilities.keyword.HasteAbility;
|
import mage.abilities.keyword.HasteAbility;
|
||||||
import mage.cards.Card;
|
|
||||||
import mage.constants.*;
|
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
import mage.abilities.keyword.MenaceAbility;
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.*;
|
||||||
import mage.filter.common.FilterCreatureCard;
|
import mage.filter.common.FilterCreatureCard;
|
||||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
@ -26,8 +24,9 @@ import mage.target.common.TargetCardInYourGraveyard;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author weirddan455
|
* @author weirddan455
|
||||||
*/
|
*/
|
||||||
public final class BalduvianAtrocity extends CardImpl {
|
public final class BalduvianAtrocity extends CardImpl {
|
||||||
|
|
@ -53,11 +52,7 @@ public final class BalduvianAtrocity extends CardImpl {
|
||||||
this.addAbility(new MenaceAbility(false));
|
this.addAbility(new MenaceAbility(false));
|
||||||
|
|
||||||
// When Balduvian Atrocity enters the battlefield, if it was kicked, return target creature card with mana value 3 or less from your graveyard to the battlefield. It gains haste. Sacrifice it at the beginning of the next end step.
|
// When Balduvian Atrocity enters the battlefield, if it was kicked, return target creature card with mana value 3 or less from your graveyard to the battlefield. It gains haste. Sacrifice it at the beginning of the next end step.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new BalduvianAtrocityEffect()).withInterveningIf(KickedCondition.ONCE);
|
||||||
new EntersBattlefieldTriggeredAbility(new BalduvianAtrocityEffect()),
|
|
||||||
KickedCondition.ONCE,
|
|
||||||
"When {this} enters, if it was kicked, return target creature card with mana value 3 or less from your graveyard to the battlefield. It gains haste. Sacrifice it at the beginning of the next end step."
|
|
||||||
);
|
|
||||||
ability.addTarget(new TargetCardInYourGraveyard(filter));
|
ability.addTarget(new TargetCardInYourGraveyard(filter));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +71,8 @@ class BalduvianAtrocityEffect extends OneShotEffect {
|
||||||
|
|
||||||
BalduvianAtrocityEffect() {
|
BalduvianAtrocityEffect() {
|
||||||
super(Outcome.PutCreatureInPlay);
|
super(Outcome.PutCreatureInPlay);
|
||||||
this.staticText = "return target creature card with mana value 3 or less from your graveyard to the battlefield. It gains haste. Sacrifice it at the beginning of the next end step.";
|
this.staticText = "return target creature card with mana value 3 or less from your graveyard to the battlefield. " +
|
||||||
|
"It gains haste. Sacrifice it at the beginning of the next end step.";
|
||||||
}
|
}
|
||||||
|
|
||||||
private BalduvianAtrocityEffect(final BalduvianAtrocityEffect effect) {
|
private BalduvianAtrocityEffect(final BalduvianAtrocityEffect effect) {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import mage.constants.CardType;
|
||||||
import mage.constants.SagaChapter;
|
import mage.constants.SagaChapter;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.common.FilterHistoricCard;
|
import mage.filter.predicate.mageobject.HistoricPredicate;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -18,7 +18,10 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class BalladOfTheBlackFlag extends CardImpl {
|
public final class BalladOfTheBlackFlag extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCard filter = new FilterHistoricCard();
|
private static final FilterCard filter = new FilterCard("historic card");
|
||||||
|
static {
|
||||||
|
filter.add(HistoricPredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
public BalladOfTheBlackFlag(UUID ownerId, CardSetInfo setInfo) {
|
public BalladOfTheBlackFlag(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}");
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public final class BanditsTalent extends CardImpl {
|
||||||
this.addAbility(new ClassLevelAbility(2, "{B}"));
|
this.addAbility(new ClassLevelAbility(2, "{B}"));
|
||||||
// At the beginning of each opponent's upkeep, if that player has one or fewer cards in hand, they lose 2 life.
|
// At the beginning of each opponent's upkeep, if that player has one or fewer cards in hand, they lose 2 life.
|
||||||
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(new BeginningOfUpkeepTriggeredAbility(
|
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(new BeginningOfUpkeepTriggeredAbility(
|
||||||
TargetController.OPPONENT, new ConditionalOneShotEffect(new LoseLifeTargetEffect(2), new CardsInHandCondition(ComparisonType.OR_LESS, 1, TargetController.ACTIVE)),
|
TargetController.OPPONENT, new ConditionalOneShotEffect(new LoseLifeTargetEffect(2).setText("they lose 2 life"), new CardsInHandCondition(ComparisonType.OR_LESS, 1, TargetController.ACTIVE)),
|
||||||
false), 2)));
|
false), 2)));
|
||||||
|
|
||||||
// {3}{B}: Level 3
|
// {3}{B}: Level 3
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,37 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
|
||||||
import mage.abilities.condition.CompoundCondition;
|
import mage.abilities.condition.CompoundCondition;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.CardsInHandCondition;
|
import mage.abilities.condition.common.CardsInHandCondition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
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.filter.common.FilterControlledPermanent;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author fireshoes
|
* @author fireshoes
|
||||||
*/
|
*/
|
||||||
public final class BarrenGlory extends CardImpl {
|
public final class BarrenGlory extends CardImpl {
|
||||||
|
|
||||||
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
|
private static final Condition condition = new CompoundCondition(
|
||||||
|
"you control no permanents other than this enchantment and have no cards in hand",
|
||||||
static {
|
new CardsInHandCondition(ComparisonType.EQUAL_TO, 0),
|
||||||
filter.add(AnotherPredicate.instance);
|
new PermanentsOnTheBattlefieldCondition(
|
||||||
}
|
StaticFilters.FILTER_OTHER_CONTROLLED_PERMANENTS, ComparisonType.EQUAL_TO, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
public BarrenGlory(UUID ownerId, CardSetInfo setInfo) {
|
public BarrenGlory(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}{W}");
|
||||||
|
|
||||||
// At the beginning of your upkeep, if you control no permanents other than Barren Glory and have no cards in hand, you win the game.
|
// At the beginning of your upkeep, if you control no permanents other than Barren Glory and have no cards in hand, you win the game.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect()).withInterveningIf(condition));
|
||||||
new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect()),
|
|
||||||
new CompoundCondition(
|
|
||||||
new CardsInHandCondition(ComparisonType.EQUAL_TO, 0),
|
|
||||||
new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0)
|
|
||||||
),
|
|
||||||
"At the beginning of your upkeep, if you control no permanents other than {this} and have no cards in hand, you win the game"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BarrenGlory(final BarrenGlory card) {
|
private BarrenGlory(final BarrenGlory card) {
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@ package mage.cards.b;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
|
|
@ -50,12 +49,8 @@ public final class BarrinTolarianArchmage extends CardImpl {
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// At the beginning of your end step, if a permanent was put into your hand from the battlefield this turn, draw a card.
|
// At the beginning of your end step, if a permanent was put into your hand from the battlefield this turn, draw a card.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfEndStepTriggeredAbility(new DrawCardSourceControllerEffect(1))
|
||||||
new BeginningOfEndStepTriggeredAbility(
|
.withInterveningIf(BarrinTolarianArchmageCondition.instance), new BarrinTolarianArchmageWatcher());
|
||||||
new DrawCardSourceControllerEffect(1)
|
|
||||||
), BarrinTolarianArchmageCondition.instance, "At the beginning of your end step, " +
|
|
||||||
"if a permanent was put into your hand from the battlefield this turn, draw a card."
|
|
||||||
), new BarrinTolarianArchmageWatcher());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BarrinTolarianArchmage(final BarrinTolarianArchmage card) {
|
private BarrinTolarianArchmage(final BarrinTolarianArchmage card) {
|
||||||
|
|
@ -76,6 +71,11 @@ enum BarrinTolarianArchmageCondition implements Condition {
|
||||||
BarrinTolarianArchmageWatcher watcher = game.getState().getWatcher(BarrinTolarianArchmageWatcher.class);
|
BarrinTolarianArchmageWatcher watcher = game.getState().getWatcher(BarrinTolarianArchmageWatcher.class);
|
||||||
return watcher != null && watcher.checkPlayer(source.getControllerId());
|
return watcher != null && watcher.checkPlayer(source.getControllerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "a permanent was put into your hand from the battlefield this turn";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BarrinTolarianArchmageWatcher extends Watcher {
|
class BarrinTolarianArchmageWatcher extends Watcher {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package mage.cards.b;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.OpponentsLostLifeCondition;
|
import mage.abilities.condition.common.OpponentsLostLifeCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.abilities.hint.common.OpponentsLostLifeHint;
|
import mage.abilities.hint.common.OpponentsLostLifeHint;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -27,11 +26,8 @@ public final class BatWhisperer extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// When Bat Whisperer enters the battlefield, if an opponent lost life this turn, create a 1/1 black Bat creature token with flying.
|
// When Bat Whisperer enters the battlefield, if an opponent lost life this turn, create a 1/1 black Bat creature token with flying.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BatToken()))
|
||||||
new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BatToken())),
|
.withInterveningIf(OpponentsLostLifeCondition.instance).addHint(OpponentsLostLifeHint.instance));
|
||||||
OpponentsLostLifeCondition.instance, "When {this} enters, " +
|
|
||||||
"if an opponent lost life this turn, create a 1/1 black Bat creature token with flying."
|
|
||||||
).addHint(OpponentsLostLifeHint.instance));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BatWhisperer(final BatWhisperer card) {
|
private BatWhisperer(final BatWhisperer card) {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.filter.FilterSpell;
|
import mage.filter.FilterSpell;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterArtifactSpell;
|
|
||||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||||
import mage.game.permanent.token.PowerstoneToken;
|
import mage.game.permanent.token.PowerstoneToken;
|
||||||
|
|
||||||
|
|
@ -26,9 +25,10 @@ import java.util.UUID;
|
||||||
public final class BatteryBearer extends CardImpl {
|
public final class BatteryBearer extends CardImpl {
|
||||||
|
|
||||||
private static final FilterSpell filter
|
private static final FilterSpell filter
|
||||||
= new FilterArtifactSpell("an artifact spell with mana value 6 or greater");
|
= new FilterSpell("an artifact spell with mana value 6 or greater");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
filter.add(CardType.ARTIFACT.getPredicate());
|
||||||
filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 5));
|
filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,31 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbility;
|
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
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.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.players.Library;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author North
|
* @author North
|
||||||
*/
|
*/
|
||||||
public final class BattleOfWits extends CardImpl {
|
public final class BattleOfWits extends CardImpl {
|
||||||
|
|
||||||
public BattleOfWits(UUID ownerId, CardSetInfo setInfo) {
|
public BattleOfWits(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}");
|
||||||
|
|
||||||
|
|
||||||
// At the beginning of your upkeep, if you have 200 or more cards in your library, you win the game.
|
// At the beginning of your upkeep, if you have 200 or more cards in your library, you win the game.
|
||||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect());
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect())
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new BattleOfWitsCondition(), "At the beginning of your upkeep, if you have 200 or more cards in your library, you win the game."));
|
.withInterveningIf(BattleOfWitsCondition.instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BattleOfWits(final BattleOfWits card) {
|
private BattleOfWits(final BattleOfWits card) {
|
||||||
|
|
@ -39,14 +38,22 @@ public final class BattleOfWits extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BattleOfWitsCondition implements Condition {
|
enum BattleOfWitsCondition implements Condition {
|
||||||
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
return Optional
|
||||||
if (player != null && player.getLibrary().size() >= 200) {
|
.ofNullable(source)
|
||||||
return true;
|
.map(Controllable::getControllerId)
|
||||||
}
|
.map(game::getPlayer)
|
||||||
return false;
|
.map(Player::getLibrary)
|
||||||
|
.map(Library::size)
|
||||||
|
.orElse(0) >= 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "you have 200 or more cards in your library";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.KickedCondition;
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.discard.DiscardHandControllerEffect;
|
import mage.abilities.effects.common.discard.DiscardHandControllerEffect;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.abilities.keyword.KickerAbility;
|
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.KickerAbility;
|
||||||
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.SubType;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author weirddan455
|
* @author weirddan455
|
||||||
*/
|
*/
|
||||||
public final class BattlewingMystic extends CardImpl {
|
public final class BattlewingMystic extends CardImpl {
|
||||||
|
|
@ -35,12 +35,9 @@ public final class BattlewingMystic extends CardImpl {
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// When Battlewing Mystic enters the battlefield, if it was kicked, discard your hand, then draw two cards.
|
// When Battlewing Mystic enters the battlefield, if it was kicked, discard your hand, then draw two cards.
|
||||||
EntersBattlefieldTriggeredAbility triggeredAbility = new EntersBattlefieldTriggeredAbility(new DiscardHandControllerEffect());
|
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardHandControllerEffect()).withInterveningIf(KickedCondition.ONCE);
|
||||||
triggeredAbility.addEffect(new DrawCardSourceControllerEffect(2));
|
ability.addEffect(new DrawCardSourceControllerEffect(2).concatBy(", then"));
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(ability);
|
||||||
triggeredAbility, KickedCondition.ONCE,
|
|
||||||
"When {this} enters, if it was kicked, discard your hand, then draw two cards."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BattlewingMystic(final BattlewingMystic card) {
|
private BattlewingMystic(final BattlewingMystic card) {
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@ package mage.cards.b;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
|
||||||
import mage.abilities.condition.common.CelebrationCondition;
|
import mage.abilities.condition.common.CelebrationCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
import mage.abilities.keyword.MenaceAbility;
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.AbilityWord;
|
import mage.constants.AbilityWord;
|
||||||
|
|
@ -32,16 +31,10 @@ public final class BelligerentOfTheBall extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// Celebration -- At the beginning of combat on your turn, if two or more nonland permanents entered the battlefield under your control this turn, target creature you control gets +1/+0 and gains menace until end of turn.
|
// Celebration -- At the beginning of combat on your turn, if two or more nonland permanents entered the battlefield under your control this turn, target creature you control gets +1/+0 and gains menace until end of turn.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new BeginningOfCombatTriggeredAbility(new BoostTargetEffect(1, 0)
|
||||||
new BeginningOfCombatTriggeredAbility(
|
.setText("target creature you control gets +1/+0")).withInterveningIf(CelebrationCondition.instance);
|
||||||
new BoostTargetEffect(1, 0)
|
ability.addEffect(new GainAbilityTargetEffect(new MenaceAbility(false))
|
||||||
),
|
.setText("and gains menace until end of turn"));
|
||||||
CelebrationCondition.instance, "At the beginning of combat on your turn, if two or more nonland "
|
|
||||||
+ "permanents entered the battlefield under your control this turn, target creature you control "
|
|
||||||
+ "gets +1/+0 and gains menace until end of turn."
|
|
||||||
+ " <i>(It can't be blocked except by two or more creatures.)</i>"
|
|
||||||
);
|
|
||||||
ability.addEffect(new GainAbilityTargetEffect(new MenaceAbility(false)));
|
|
||||||
ability.addTarget(new TargetControlledCreaturePermanent());
|
ability.addTarget(new TargetControlledCreaturePermanent());
|
||||||
ability.setAbilityWord(AbilityWord.CELEBRATION);
|
ability.setAbilityWord(AbilityWord.CELEBRATION);
|
||||||
ability.addHint(CelebrationCondition.getHint());
|
ability.addHint(CelebrationCondition.getHint());
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbility;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.KickedCondition;
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -15,26 +12,26 @@ import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.target.common.TargetLandPermanent;
|
import mage.target.common.TargetLandPermanent;
|
||||||
|
|
||||||
/**
|
import java.util.UUID;
|
||||||
*
|
|
||||||
* @author LoneFox
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author LoneFox
|
||||||
*/
|
*/
|
||||||
public final class BenalishEmissary extends CardImpl {
|
public final class BenalishEmissary extends CardImpl {
|
||||||
|
|
||||||
public BenalishEmissary(UUID ownerId, CardSetInfo setInfo) {
|
public BenalishEmissary(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
|
||||||
this.subtype.add(SubType.HUMAN, SubType.WIZARD);
|
this.subtype.add(SubType.HUMAN, SubType.WIZARD);
|
||||||
this.power = new MageInt(1);
|
this.power = new MageInt(1);
|
||||||
this.toughness = new MageInt(4);
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
// Kicker {1}{G}
|
// Kicker {1}{G}
|
||||||
this.addAbility(new KickerAbility("{1}{G}"));
|
this.addAbility(new KickerAbility("{1}{G}"));
|
||||||
|
|
||||||
// When Benalish Emissary enters the battlefield, if it was kicked, destroy target land.
|
// When Benalish Emissary enters the battlefield, if it was kicked, destroy target land.
|
||||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect());
|
Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()).withInterveningIf(KickedCondition.ONCE);
|
||||||
ability.addTarget(new TargetLandPermanent());
|
ability.addTarget(new TargetLandPermanent());
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, KickedCondition.ONCE,
|
this.addAbility(ability);
|
||||||
"When {this} enters, if it was kicked, destroy target land."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BenalishEmissary(final BenalishEmissary card) {
|
private BenalishEmissary(final BenalishEmissary card) {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package mage.cards.b;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.KickedCondition;
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.SacrificeAllEffect;
|
import mage.abilities.effects.common.SacrificeAllEffect;
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -32,10 +31,7 @@ public final class BenalishSleeper extends CardImpl {
|
||||||
this.addAbility(new KickerAbility("{B}"));
|
this.addAbility(new KickerAbility("{B}"));
|
||||||
|
|
||||||
// When Benalish Sleeper enters the battlefield, if it was kicked, each player sacrifices a creature.
|
// When Benalish Sleeper enters the battlefield, if it was kicked, each player sacrifices a creature.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(new EntersBattlefieldTriggeredAbility(
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeAllEffect(StaticFilters.FILTER_PERMANENT_CREATURE)).withInterveningIf(KickedCondition.ONCE));
|
||||||
new SacrificeAllEffect(StaticFilters.FILTER_PERMANENT_CREATURE)
|
|
||||||
), KickedCondition.ONCE, "When {this} enters, " +
|
|
||||||
"if it was kicked, each player sacrifices a creature."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BenalishSleeper(final BenalishSleeper card) {
|
private BenalishSleeper(final BenalishSleeper card) {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.CelebrationCondition;
|
import mage.abilities.condition.common.CelebrationCondition;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.AttachEffect;
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
|
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
|
||||||
import mage.abilities.keyword.EquipAbility;
|
import mage.abilities.keyword.EquipAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.AbilityWord;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.watchers.common.PermanentsEnteredBattlefieldWatcher;
|
import mage.watchers.common.PermanentsEnteredBattlefieldWatcher;
|
||||||
|
|
||||||
|
|
@ -28,19 +30,12 @@ public final class BespokeBattlegarb extends CardImpl {
|
||||||
this.subtype.add(SubType.EQUIPMENT);
|
this.subtype.add(SubType.EQUIPMENT);
|
||||||
|
|
||||||
// Equipped creature gets +2/+0.
|
// Equipped creature gets +2/+0.
|
||||||
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 0, Duration.WhileOnBattlefield)));
|
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 0)));
|
||||||
|
|
||||||
// Celebration -- At the beginning of combat on your turn, if two or more nonland permanents entered the battlefield under your control this turn, attach Bespoke Battlegarb to up to one target creature you control.
|
// Celebration -- At the beginning of combat on your turn, if two or more nonland permanents entered the battlefield under your control this turn, attach Bespoke Battlegarb to up to one target creature you control.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new BeginningOfCombatTriggeredAbility(new AttachEffect(
|
||||||
new BeginningOfCombatTriggeredAbility(
|
Outcome.BoostCreature, "attach {this} to up to one target creature you control"
|
||||||
new AttachEffect(
|
)).withInterveningIf(CelebrationCondition.instance);
|
||||||
Outcome.BoostCreature,
|
|
||||||
"attach {this} to up to one target creature you control"
|
|
||||||
)
|
|
||||||
), CelebrationCondition.instance, "At the beginning of combat on your turn, if two "
|
|
||||||
+ "or more nonland permanents entered the battlefield under your control this turn, "
|
|
||||||
+ "attach {this} to up to one target creature you control"
|
|
||||||
);
|
|
||||||
ability.addTarget(new TargetControlledCreaturePermanent(0, 1));
|
ability.addTarget(new TargetControlledCreaturePermanent(0, 1));
|
||||||
ability.setAbilityWord(AbilityWord.CELEBRATION);
|
ability.setAbilityWord(AbilityWord.CELEBRATION);
|
||||||
ability.addHint(CelebrationCondition.getHint());
|
ability.addHint(CelebrationCondition.getHint());
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,22 @@ import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
|
import mage.abilities.hint.ConditionHint;
|
||||||
|
import mage.abilities.hint.Hint;
|
||||||
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.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
|
import mage.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.token.FishNoAbilityToken;
|
import mage.game.permanent.token.FishNoAbilityToken;
|
||||||
import mage.game.permanent.token.TreasureToken;
|
import mage.game.permanent.token.TreasureToken;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,6 +33,13 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class BezaTheBoundingSpring extends CardImpl {
|
public final class BezaTheBoundingSpring extends CardImpl {
|
||||||
|
|
||||||
|
private static final Condition condition = new OpponentControlsMoreCondition(StaticFilters.FILTER_LANDS);
|
||||||
|
private static final Condition condition2 = new OpponentControlsMoreCondition(StaticFilters.FILTER_PERMANENT_CREATURES);
|
||||||
|
private static final Hint hint = new ConditionHint(condition);
|
||||||
|
private static final Hint hint2 = new ConditionHint(condition2);
|
||||||
|
private static final Hint hint3 = new ConditionHint(OpponentHasMoreLifeCondition.instance);
|
||||||
|
private static final Hint hint4 = new ConditionHint(BezaOpponentHasMoreCardsInHandThanYouCondition.instance);
|
||||||
|
|
||||||
public BezaTheBoundingSpring(UUID ownerId, CardSetInfo setInfo) {
|
public BezaTheBoundingSpring(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}");
|
||||||
|
|
||||||
|
|
@ -39,14 +51,23 @@ public final class BezaTheBoundingSpring extends CardImpl {
|
||||||
|
|
||||||
// When Beza, the Bounding Spring enters, create a Treasure token if an opponent controls more lands than you. You gain 4 life if an opponent has more life than you. Create two 1/1 blue Fish creature tokens if an opponent controls more creatures than you. Draw a card if an opponent has more cards in hand than you.
|
// When Beza, the Bounding Spring enters, create a Treasure token if an opponent controls more lands than you. You gain 4 life if an opponent has more life than you. Create two 1/1 blue Fish creature tokens if an opponent controls more creatures than you. Draw a card if an opponent has more cards in hand than you.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(
|
||||||
new CreateTokenEffect(new TreasureToken()), new OpponentControlsMoreCondition(StaticFilters.FILTER_LANDS)));
|
new CreateTokenEffect(new TreasureToken()), condition,
|
||||||
|
"create a Treasure token if an opponent controls more lands than you"
|
||||||
|
));
|
||||||
ability.addEffect(new ConditionalOneShotEffect(
|
ability.addEffect(new ConditionalOneShotEffect(
|
||||||
new GainLifeEffect(4), OpponentHasMoreLifeCondition.instance));
|
new GainLifeEffect(4), OpponentHasMoreLifeCondition.instance,
|
||||||
|
"you gain 4 life if an opponent has more life than you"
|
||||||
|
));
|
||||||
ability.addEffect(new ConditionalOneShotEffect(
|
ability.addEffect(new ConditionalOneShotEffect(
|
||||||
new CreateTokenEffect(new FishNoAbilityToken(), 2), new OpponentControlsMoreCondition(StaticFilters.FILTER_PERMANENT_CREATURES)));
|
new CreateTokenEffect(new FishNoAbilityToken(), 2), condition2,
|
||||||
|
"Create two 1/1 blue Fish creature tokens if an opponent controls more creatures than you"
|
||||||
|
));
|
||||||
ability.addEffect(new ConditionalOneShotEffect(
|
ability.addEffect(new ConditionalOneShotEffect(
|
||||||
new DrawCardSourceControllerEffect(1), BezaOpponentHasMoreCardsInHandThanYouCondition.instance));
|
new DrawCardSourceControllerEffect(1),
|
||||||
this.addAbility(ability);
|
BezaOpponentHasMoreCardsInHandThanYouCondition.instance,
|
||||||
|
"draw a card if an opponent has more cards in hand than you"
|
||||||
|
));
|
||||||
|
this.addAbility(ability.addHint(hint).addHint(hint2).addHint(hint3).addHint(hint4));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BezaTheBoundingSpring(final BezaTheBoundingSpring card) {
|
private BezaTheBoundingSpring(final BezaTheBoundingSpring card) {
|
||||||
|
|
@ -61,22 +82,23 @@ public final class BezaTheBoundingSpring extends CardImpl {
|
||||||
|
|
||||||
//Based on MoreCardsInHandThanOpponentsCondition
|
//Based on MoreCardsInHandThanOpponentsCondition
|
||||||
enum BezaOpponentHasMoreCardsInHandThanYouCondition implements Condition {
|
enum BezaOpponentHasMoreCardsInHandThanYouCondition implements Condition {
|
||||||
|
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
int cardsInHand = Optional
|
||||||
if (player != null) {
|
.ofNullable(source)
|
||||||
int cardsInHand = player.getHand().size();
|
.map(Controllable::getControllerId)
|
||||||
for (UUID playerId : game.getOpponents(source.getControllerId())) {
|
.map(game::getPlayer)
|
||||||
Player opponent = game.getPlayer(playerId);
|
.map(Player::getHand)
|
||||||
if (opponent != null && opponent.getHand().size() > cardsInHand) {
|
.map(Set::size)
|
||||||
return true;
|
.orElse(0);
|
||||||
}
|
return game.getOpponents(source.getControllerId())
|
||||||
}
|
.stream()
|
||||||
}
|
.map(game::getPlayer)
|
||||||
return false;
|
.map(Player::getHand)
|
||||||
|
.mapToInt(Set::size)
|
||||||
|
.anyMatch(x -> x > cardsInHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.ControlACommanderCondition;
|
import mage.abilities.condition.common.ControlACommanderCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.CreateTokenCopySourceEffect;
|
import mage.abilities.effects.CreateTokenCopySourceEffect;
|
||||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
|
@ -36,12 +35,8 @@ public final class BiowasteBlob extends CardImpl {
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// At the beginning of your upkeep, if you control a commander, create a token that's a copy of Biowaste Blob.
|
// At the beginning of your upkeep, if you control a commander, create a token that's a copy of Biowaste Blob.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenCopySourceEffect())
|
||||||
new BeginningOfUpkeepTriggeredAbility(
|
.withInterveningIf(ControlACommanderCondition.instance));
|
||||||
new CreateTokenCopySourceEffect(), false
|
|
||||||
), ControlACommanderCondition.instance, "At the beginning of your upkeep, " +
|
|
||||||
"if you control a commander, create a token that's a copy of {this}."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BiowasteBlob(final BiowasteBlob card) {
|
private BiowasteBlob(final BiowasteBlob card) {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -67,14 +68,11 @@ enum BladeOfSharedSoulsPredicate implements ObjectSourcePlayerPredicate<Permanen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||||
return input.getSource()
|
return !CardUtil
|
||||||
.getEffects()
|
.getEffectValueFromAbility(input.getSource(), "attachedPermanent", Permanent.class)
|
||||||
.stream()
|
.filter(permanent -> input.getObject().getId().equals(permanent.getId())
|
||||||
.map(effect -> effect.getValue("attachedPermanent"))
|
&& input.getObject().getZoneChangeCounter(game) == permanent.getZoneChangeCounter(game))
|
||||||
.filter(Permanent.class::isInstance)
|
.isPresent();
|
||||||
.map(Permanent.class::cast)
|
|
||||||
.noneMatch(permanent -> input.getObject().getId().equals(permanent.getId())
|
|
||||||
&& input.getObject().getZoneChangeCounter(game) == permanent.getZoneChangeCounter(game));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,4 +139,4 @@ class BladeOfSharedSoulsCopyEffect extends CopyEffect {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbility;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.MetalcraftCondition;
|
import mage.abilities.condition.common.MetalcraftCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||||
import mage.abilities.hint.common.MetalcraftHint;
|
import mage.abilities.hint.common.MetalcraftHint;
|
||||||
|
|
@ -23,8 +22,6 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class BladeTribeBerserkers extends CardImpl {
|
public final class BladeTribeBerserkers extends CardImpl {
|
||||||
|
|
||||||
private static final String effectText = "When {this} enters, if you control three or more artifacts, {this} gets +3/+3 and gains haste until end of turn.";
|
|
||||||
|
|
||||||
public BladeTribeBerserkers(UUID ownerId, CardSetInfo setInfo) {
|
public BladeTribeBerserkers(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
|
||||||
this.subtype.add(SubType.HUMAN, SubType.BERSERKER);
|
this.subtype.add(SubType.HUMAN, SubType.BERSERKER);
|
||||||
|
|
@ -33,12 +30,14 @@ public final class BladeTribeBerserkers extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
//<i>Metalcraft</i> — When Blade-Tribe Berserkers enters the battlefield, if you control three or more artifacts, Blade-Tribe Berserkers gets +3/+3 and gains haste until end of turn.
|
//<i>Metalcraft</i> — When Blade-Tribe Berserkers enters the battlefield, if you control three or more artifacts, Blade-Tribe Berserkers gets +3/+3 and gains haste until end of turn.
|
||||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new BoostSourceEffect(3, 3, Duration.EndOfTurn), false);
|
Ability ability = new EntersBattlefieldTriggeredAbility(
|
||||||
ability.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
|
new BoostSourceEffect(3, 3, Duration.EndOfTurn)
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText)
|
.setText("{this} gets +3/+3"), false
|
||||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
).withInterveningIf(MetalcraftCondition.instance);
|
||||||
.addHint(MetalcraftHint.instance)
|
ability.addEffect(new GainAbilitySourceEffect(
|
||||||
);
|
HasteAbility.getInstance(), Duration.EndOfTurn
|
||||||
|
).setText("and gains haste until end of turn"));
|
||||||
|
this.addAbility(ability.setAbilityWord(AbilityWord.METALCRAFT).addHint(MetalcraftHint.instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BladeTribeBerserkers(final BladeTribeBerserkers card) {
|
private BladeTribeBerserkers(final BladeTribeBerserkers card) {
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ public final class BlademaneBaku extends CardImpl {
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
// Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Blademane Baku.
|
// Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Blademane Baku.
|
||||||
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.FILTER_SPIRIT_OR_ARCANE_CARD, true));
|
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.FILTER_SPELL_SPIRIT_OR_ARCANE, true));
|
||||||
|
|
||||||
// {1}, Remove X ki counters from Blademane Baku: For each counter removed, Blademane Baku gets +2/+0 until end of turn.
|
// {1}, Remove X ki counters from Blademane Baku: For each counter removed, Blademane Baku gets +2/+0 until end of turn.
|
||||||
Effect effect = new BoostSourceEffect(xValue, StaticValue.get(0), Duration.EndOfTurn);
|
Effect effect = new BoostSourceEffect(xValue, StaticValue.get(0), Duration.EndOfTurn);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbility;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.MetalcraftCondition;
|
import mage.abilities.condition.common.MetalcraftCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||||
import mage.abilities.hint.common.MetalcraftHint;
|
import mage.abilities.hint.common.MetalcraftHint;
|
||||||
|
|
@ -13,7 +12,6 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.AbilityWord;
|
import mage.constants.AbilityWord;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.target.Target;
|
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -23,8 +21,6 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class BleakCovenVampires extends CardImpl {
|
public final class BleakCovenVampires extends CardImpl {
|
||||||
|
|
||||||
private static final String effectText = "When {this} enters, if you control three or more artifacts, target player loses 4 life and you gain 4 life.";
|
|
||||||
|
|
||||||
public BleakCovenVampires(UUID ownerId, CardSetInfo setInfo) {
|
public BleakCovenVampires(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
|
||||||
this.subtype.add(SubType.VAMPIRE, SubType.WARRIOR);
|
this.subtype.add(SubType.VAMPIRE, SubType.WARRIOR);
|
||||||
|
|
@ -33,15 +29,11 @@ public final class BleakCovenVampires extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
//<i>Metalcraft</i> — When Bleak Coven Vampires enters the battlefield, if you control three or more artifacts, target player loses 4 life and you gain 4 life.
|
//<i>Metalcraft</i> — When Bleak Coven Vampires enters the battlefield, if you control three or more artifacts, target player loses 4 life and you gain 4 life.
|
||||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(4), false);
|
Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(4))
|
||||||
ability.addEffect(new GainLifeEffect(4));
|
.withInterveningIf(MetalcraftCondition.instance);
|
||||||
Target target = new TargetPlayer();
|
ability.addEffect(new GainLifeEffect(4).concatBy("and"));
|
||||||
ability.addTarget(target);
|
ability.addTarget(new TargetPlayer());
|
||||||
|
this.addAbility(ability.setAbilityWord(AbilityWord.METALCRAFT).addHint(MetalcraftHint.instance));
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText)
|
|
||||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
|
||||||
.addHint(MetalcraftHint.instance)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BleakCovenVampires(final BleakCovenVampires card) {
|
private BleakCovenVampires(final BleakCovenVampires card) {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public final class BlindObedience extends CardImpl {
|
||||||
// Artifacts and creatures your opponents control enter the battlefield tapped.
|
// Artifacts and creatures your opponents control enter the battlefield tapped.
|
||||||
this.addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(
|
this.addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(
|
||||||
StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE
|
StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE
|
||||||
).setText("artifacts and creatures your opponents control enter the battlefield tapped")));
|
).setText("artifacts and creatures your opponents control enter tapped")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster;
|
import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ public final class BlindZealot extends CardImpl {
|
||||||
OneShotEffect effect = new DoIfCostPaid(new DestroyTargetEffect(), new SacrificeSourceCost());
|
OneShotEffect effect = new DoIfCostPaid(new DestroyTargetEffect(), new SacrificeSourceCost());
|
||||||
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true);
|
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true);
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster());
|
ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect;
|
import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect;
|
||||||
import mage.abilities.keyword.FlashAbility;
|
import mage.abilities.keyword.FlashAbility;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
|
@ -26,7 +25,7 @@ import java.util.UUID;
|
||||||
public final class BlizzardStrix extends CardImpl {
|
public final class BlizzardStrix extends CardImpl {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterPermanent("another target permanent");
|
private static final FilterPermanent filter = new FilterPermanent("another target permanent");
|
||||||
private static final FilterPermanent filter2 = new FilterPermanent();
|
private static final FilterPermanent filter2 = new FilterPermanent("you control another snow permanent");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(AnotherPredicate.instance);
|
filter.add(AnotherPredicate.instance);
|
||||||
|
|
@ -51,12 +50,9 @@ public final class BlizzardStrix extends CardImpl {
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// When Blizzard Strix enters the battlefield, if you control another snow permanent, exile target permanent other than Blizzard Strix. Return that card to the battlefield under its owner's control at the beginning of the next end step.
|
// When Blizzard Strix enters the battlefield, if you control another snow permanent, exile target permanent other than Blizzard Strix. Return that card to the battlefield under its owner's control at the beginning of the next end step.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect()
|
||||||
new EntersBattlefieldTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect()), condition,
|
.setText("exile target permanent other than {this}. Return that card to the " +
|
||||||
"When {this} enters, if you control another snow permanent, " +
|
"battlefield under its owner's control at the beginning of the next end step"));
|
||||||
"exile target permanent other than {this}. Return that card to the battlefield " +
|
|
||||||
"under its owner's control at the beginning of the next end step."
|
|
||||||
);
|
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility;
|
import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.OpponentLostLifeCondition;
|
import mage.abilities.condition.common.OpponentLostLifeCondition;
|
||||||
import mage.abilities.condition.common.SourceHasCounterCondition;
|
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
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;
|
||||||
|
|
@ -18,14 +16,17 @@ import mage.constants.ComparisonType;
|
||||||
import mage.constants.SetTargetPointer;
|
import mage.constants.SetTargetPointer;
|
||||||
import mage.constants.TargetController;
|
import mage.constants.TargetController;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.StaticFilters;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class BloodchiefAscension extends CardImpl {
|
public final class BloodchiefAscension extends CardImpl {
|
||||||
|
|
||||||
|
private static final Condition condition = new SourceHasCounterCondition(CounterType.QUEST, 3);
|
||||||
|
|
||||||
public BloodchiefAscension(UUID ownerId, CardSetInfo setInfo) {
|
public BloodchiefAscension(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}");
|
||||||
|
|
||||||
|
|
@ -36,14 +37,12 @@ public final class BloodchiefAscension extends CardImpl {
|
||||||
));
|
));
|
||||||
|
|
||||||
// Whenever a card is put into an opponent's graveyard from anywhere, if Bloodchief Ascension has three or more quest counters on it, you may have that player lose 2 life. If you do, you gain 2 life.
|
// Whenever a card is put into an opponent's graveyard from anywhere, if Bloodchief Ascension has three or more quest counters on it, you may have that player lose 2 life. If you do, you gain 2 life.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new PutCardIntoGraveFromAnywhereAllTriggeredAbility(
|
||||||
new PutCardIntoGraveFromAnywhereAllTriggeredAbility(
|
new LoseLifeTargetEffect(2), true, StaticFilters.FILTER_CARD_A,
|
||||||
new LoseLifeTargetEffect(2), true, new FilterCard("a card"), TargetController.OPPONENT, SetTargetPointer.PLAYER),
|
TargetController.OPPONENT, SetTargetPointer.PLAYER
|
||||||
new SourceHasCounterCondition(CounterType.QUEST, 3, Integer.MAX_VALUE),
|
).withInterveningIf(condition);
|
||||||
"Whenever a card is put into an opponent's graveyard from anywhere, if {this} has three or more quest counters on it, you may have that player lose 2 life. If you do, you gain 2 life");
|
ability.addEffect(new GainLifeEffect(2).concatBy("If you do,"));
|
||||||
ability.addEffect(new GainLifeEffect(2));
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BloodchiefAscension(final BloodchiefAscension card) {
|
private BloodchiefAscension(final BloodchiefAscension card) {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbility;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
|
||||||
import mage.abilities.condition.common.HellbentCondition;
|
import mage.abilities.condition.common.HellbentCondition;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.DamageTargetEffect;
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
import mage.abilities.keyword.MadnessAbility;
|
import mage.abilities.keyword.MadnessAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -16,8 +13,9 @@ import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.target.common.TargetAnyTarget;
|
import mage.target.common.TargetAnyTarget;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author fireshoes
|
* @author fireshoes
|
||||||
*/
|
*/
|
||||||
public final class BloodhallPriest extends CardImpl {
|
public final class BloodhallPriest extends CardImpl {
|
||||||
|
|
@ -29,13 +27,10 @@ public final class BloodhallPriest extends CardImpl {
|
||||||
this.toughness = new MageInt(4);
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
// Whenever Bloodhall Priest enters the battlefield or attacks, if you have no cards in hand, Bloodhall Priest deals 2 damage to any target.
|
// Whenever Bloodhall Priest enters the battlefield or attacks, if you have no cards in hand, Bloodhall Priest deals 2 damage to any target.
|
||||||
TriggeredAbility triggeredAbility = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DamageTargetEffect(2));
|
Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DamageTargetEffect(2))
|
||||||
triggeredAbility.addTarget(new TargetAnyTarget());
|
.withInterveningIf(HellbentCondition.instance);
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
ability.addTarget(new TargetAnyTarget());
|
||||||
triggeredAbility,
|
this.addAbility(ability);
|
||||||
HellbentCondition.instance,
|
|
||||||
"Whenever {this} enters or attacks, if you have no cards in hand, {this} deals 2 damage to any target"
|
|
||||||
));
|
|
||||||
|
|
||||||
// Madness {1}{B}{R}
|
// Madness {1}{B}{R}
|
||||||
this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{1}{B}{R}")));
|
this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{1}{B}{R}")));
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package mage.cards.b;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.OpponentsLostLifeCondition;
|
import mage.abilities.condition.common.OpponentsLostLifeCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
|
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
|
||||||
import mage.abilities.hint.common.OpponentsLostLifeHint;
|
import mage.abilities.hint.common.OpponentsLostLifeHint;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
|
@ -32,11 +31,8 @@ public final class BloodtitheCollector extends CardImpl {
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// When this creature enters, if an opponent lost life this turn, each opponent discards a card.
|
// When this creature enters, if an opponent lost life this turn, each opponent discards a card.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(TargetController.OPPONENT))
|
||||||
new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(TargetController.OPPONENT)),
|
.withInterveningIf(OpponentsLostLifeCondition.instance).addHint(OpponentsLostLifeHint.instance));
|
||||||
OpponentsLostLifeCondition.instance, "When this creature enters, " +
|
|
||||||
"if an opponent lost life this turn, each opponent discards a card."
|
|
||||||
).addHint(OpponentsLostLifeHint.instance));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BloodtitheCollector(final BloodtitheCollector card) {
|
private BloodtitheCollector(final BloodtitheCollector card) {
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,10 @@ import mage.constants.Outcome;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledCreatureOrPlaneswalkerPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.predicate.ObjectSourcePlayer;
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
@ -67,11 +68,15 @@ class BlotOutEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterControlledCreatureOrPlaneswalkerPermanent(
|
private static final FilterPermanent filter = new FilterControlledPermanent(
|
||||||
"creature or planeswalker you control with the greatest mana value"
|
"creature or planeswalker you control with the greatest mana value"
|
||||||
);
|
);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
filter.add(Predicates.or(
|
||||||
|
CardType.CREATURE.getPredicate(),
|
||||||
|
CardType.PLANESWALKER.getPredicate()
|
||||||
|
));
|
||||||
filter.add(BlotOutPredicate.instance);
|
filter.add(BlotOutPredicate.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,38 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbility;
|
|
||||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.Effect;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
|
||||||
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.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.game.Game;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class BlowflyInfestation extends CardImpl {
|
public final class BlowflyInfestation extends CardImpl {
|
||||||
|
|
||||||
private static final String rule = "Whenever a creature dies, if it had a -1/-1 counter on it, put a -1/-1 counter on target creature.";
|
private static final FilterPermanent filter = new FilterCreaturePermanent();
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(CounterType.M1M1.getPredicate());
|
||||||
|
}
|
||||||
|
|
||||||
public BlowflyInfestation(UUID ownerId, CardSetInfo setInfo) {
|
public BlowflyInfestation(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
|
||||||
|
|
||||||
//Whenever a creature dies, if it had a -1/-1 counter on it, put a -1/-1 counter on target creature.
|
// Whenever a creature dies, if it had a -1/-1 counter on it, put a -1/-1 counter on target creature.
|
||||||
Effect effect = new BlowflyInfestationEffect();
|
Ability ability = new DiesCreatureTriggeredAbility(
|
||||||
TriggeredAbility triggeredAbility = new DiesCreatureTriggeredAbility(effect, false, false, true);
|
new AddCountersTargetEffect(CounterType.M1M1.createInstance()), false, filter
|
||||||
triggeredAbility.addTarget(new TargetCreaturePermanent());
|
).setTriggerPhrase("Whenever a creature dies, if it had a -1/-1 counter on it, ");
|
||||||
Condition condition = new BlowflyInfestationCondition();
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(triggeredAbility, condition, rule));
|
this.addAbility(ability);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlowflyInfestation(final BlowflyInfestation card) {
|
private BlowflyInfestation(final BlowflyInfestation card) {
|
||||||
|
|
@ -51,47 +44,3 @@ public final class BlowflyInfestation extends CardImpl {
|
||||||
return new BlowflyInfestation(this);
|
return new BlowflyInfestation(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlowflyInfestationCondition implements Condition {
|
|
||||||
|
|
||||||
private Permanent permanent;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
for (Effect effect : source.getEffects()) {
|
|
||||||
if (effect.getTargetPointer().getFirst(game, source) != null) {
|
|
||||||
permanent = effect.getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (permanent != null) {
|
|
||||||
return permanent.getCounters(game).containsKey(CounterType.M1M1);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BlowflyInfestationEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
BlowflyInfestationEffect() {
|
|
||||||
super(Outcome.Detriment);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlowflyInfestationEffect(final BlowflyInfestationEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent creature = game.getPermanent(source.getFirstTarget());
|
|
||||||
if (creature != null) {
|
|
||||||
creature.addCounters(CounterType.M1M1.createInstance(), source.getControllerId(), source, game);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlowflyInfestationEffect copy() {
|
|
||||||
return new BlowflyInfestationEffect(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package mage.cards.b;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.KickedCondition;
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
import mage.abilities.keyword.MenaceAbility;
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
|
|
@ -32,13 +31,9 @@ public final class BogBadger extends CardImpl {
|
||||||
this.addAbility(new KickerAbility("{B}"));
|
this.addAbility(new KickerAbility("{B}"));
|
||||||
|
|
||||||
// When Bog Badger enters the battlefield, if it was kicked, creatures you control gain menace until end of turn.
|
// When Bog Badger enters the battlefield, if it was kicked, creatures you control gain menace until end of turn.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainAbilityControlledEffect(
|
||||||
new EntersBattlefieldTriggeredAbility(new GainAbilityControlledEffect(
|
new MenaceAbility(false), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES
|
||||||
new MenaceAbility(false), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES
|
)).withInterveningIf(KickedCondition.ONCE));
|
||||||
)), KickedCondition.ONCE, "When {this} enters, " +
|
|
||||||
"if it was kicked, creatures you control gain menace until end of turn. " +
|
|
||||||
"<i>(A creature with menace can't be blocked except by two or more creatures.)</i>"
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BogBadger(final BogBadger card) {
|
private BogBadger(final BogBadger card) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
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;
|
||||||
|
|
@ -35,14 +34,10 @@ public final class BorealOutrider extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// Whenever you cast a creature spell, if {S} of any of that spell's color was spent to cast it, that creature enters the battlefield with an additional +1/+1 counter on it.
|
// Whenever you cast a creature spell, if {S} of any of that spell's color was spent to cast it, that creature enters the battlefield with an additional +1/+1 counter on it.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new SpellCastControllerTriggeredAbility(
|
||||||
new SpellCastControllerTriggeredAbility(
|
new BorealOutriderEffect(), StaticFilters.FILTER_SPELL_A_CREATURE,
|
||||||
new BorealOutriderEffect(), StaticFilters.FILTER_SPELL_A_CREATURE,
|
false, SetTargetPointer.SPELL
|
||||||
false, SetTargetPointer.SPELL
|
).withInterveningIf(BorealOutriderCondition.instance));
|
||||||
), BorealOutriderCondition.instance, "Whenever you cast a creature spell, " +
|
|
||||||
"if {S} of any of that spell's colors was spent to cast it, that creature " +
|
|
||||||
"enters the battlefield with an additional +1/+1 counter on it."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BorealOutrider(final BorealOutrider card) {
|
private BorealOutrider(final BorealOutrider card) {
|
||||||
|
|
@ -63,6 +58,11 @@ enum BorealOutriderCondition implements Condition {
|
||||||
Spell spell = (Spell) source.getEffects().get(0).getValue("spellCast");
|
Spell spell = (Spell) source.getEffects().get(0).getValue("spellCast");
|
||||||
return spell != null && ManaPaidSourceWatcher.checkSnowColor(spell, game);
|
return spell != null && ManaPaidSourceWatcher.checkSnowColor(spell, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{S} of any of that spell's color was spent to cast it";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BorealOutriderEffect extends ReplacementEffectImpl {
|
class BorealOutriderEffect extends ReplacementEffectImpl {
|
||||||
|
|
|
||||||
142
Mage.Sets/src/mage/cards/b/BorosStrikeCaptain.java
Normal file
142
Mage.Sets/src/mage/cards/b/BorosStrikeCaptain.java
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
package mage.cards.b;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.MageObjectReference;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.hint.ConditionHint;
|
||||||
|
import mage.abilities.hint.Hint;
|
||||||
|
import mage.abilities.keyword.BattalionAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class BorosStrikeCaptain extends CardImpl {
|
||||||
|
|
||||||
|
public BorosStrikeCaptain(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R/W}{R/W}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.MINOTAUR);
|
||||||
|
this.subtype.add(SubType.SOLDIER);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Battalion -- Whenever Boros Strike-Captain and at least two other creatures attack, exile the top card of your library. During any turn you attacked with three or more creatures, you may play that card.
|
||||||
|
this.addAbility(new BattalionAbility(new BorosStrikeCaptainEffect())
|
||||||
|
.addHint(BorosStrikeCaptainCondition.getHint()), new BorosStrikeCaptainWatcher());
|
||||||
|
}
|
||||||
|
|
||||||
|
private BorosStrikeCaptain(final BorosStrikeCaptain card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BorosStrikeCaptain copy() {
|
||||||
|
return new BorosStrikeCaptain(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BorosStrikeCaptainEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
BorosStrikeCaptainEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "exile the top card of your library. During any turn you attacked " +
|
||||||
|
"with three or more creatures, you may play that card";
|
||||||
|
}
|
||||||
|
|
||||||
|
private BorosStrikeCaptainEffect(final BorosStrikeCaptainEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BorosStrikeCaptainEffect copy() {
|
||||||
|
return new BorosStrikeCaptainEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Card card = player.getLibrary().getFromTop(game);
|
||||||
|
if (card == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
player.moveCards(card, Zone.EXILED, source, game);
|
||||||
|
CardUtil.makeCardPlayable(
|
||||||
|
game, source, card, false, Duration.Custom, false,
|
||||||
|
player.getId(), BorosStrikeCaptainCondition.instance
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BorosStrikeCaptainCondition implements Condition {
|
||||||
|
instance;
|
||||||
|
private static final Hint hint = new ConditionHint(instance);
|
||||||
|
|
||||||
|
public static Hint getHint() {
|
||||||
|
return hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return BorosStrikeCaptainWatcher.checkPlayer(game, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "you attacked with three or more creatures this turn";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BorosStrikeCaptainWatcher extends Watcher {
|
||||||
|
|
||||||
|
private final Map<UUID, Set<MageObjectReference>> map = new HashMap<>();
|
||||||
|
|
||||||
|
BorosStrikeCaptainWatcher() {
|
||||||
|
super(WatcherScope.GAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void watch(GameEvent event, Game game) {
|
||||||
|
if (event.getType() != GameEvent.EventType.ATTACKER_DECLARED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Optional.ofNullable(event)
|
||||||
|
.map(GameEvent::getTargetId)
|
||||||
|
.map(game::getPermanent)
|
||||||
|
.ifPresent(permanent -> map
|
||||||
|
.computeIfAbsent(permanent.getControllerId(), x -> new HashSet<>())
|
||||||
|
.add(new MageObjectReference(permanent, game)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean checkPlayer(Game game, Ability source) {
|
||||||
|
return game
|
||||||
|
.getState()
|
||||||
|
.getWatcher(BorosStrikeCaptainWatcher.class)
|
||||||
|
.map
|
||||||
|
.getOrDefault(source.getControllerId(), Collections.emptySet())
|
||||||
|
.size() >= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,30 +1,29 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
|
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
import mage.abilities.dynamicvalue.common.DomainValue;
|
import mage.abilities.dynamicvalue.common.DomainValue;
|
||||||
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
|
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
|
||||||
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
||||||
import mage.abilities.hint.common.DomainHint;
|
import mage.abilities.hint.common.DomainHint;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.constants.AbilityWord;
|
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.SuperType;
|
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.AbilityWord;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.target.common.TargetCardInYourGraveyard;
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author weirddan455
|
* @author weirddan455
|
||||||
*/
|
*/
|
||||||
public final class BortukBonerattle extends CardImpl {
|
public final class BortukBonerattle extends CardImpl {
|
||||||
|
|
@ -41,18 +40,12 @@ public final class BortukBonerattle extends CardImpl {
|
||||||
// Domain — When Bortuk Bonerattle enters the battlefield, if you cast it, choose target creature card in your graveyard.
|
// Domain — When Bortuk Bonerattle enters the battlefield, if you cast it, choose target creature card in your graveyard.
|
||||||
// Return that card to the battlefield if its mana value is less than or equal to the number of basic land types among lands you control.
|
// Return that card to the battlefield if its mana value is less than or equal to the number of basic land types among lands you control.
|
||||||
// Otherwise, put it into your hand.
|
// Otherwise, put it into your hand.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(
|
||||||
new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(
|
new ReturnFromGraveyardToBattlefieldTargetEffect(), new ReturnFromGraveyardToHandTargetEffect(),
|
||||||
new ReturnFromGraveyardToBattlefieldTargetEffect(),
|
BortukBonerattleCondition.instance, "choose target creature card in your graveyard. " +
|
||||||
new ReturnFromGraveyardToHandTargetEffect(),
|
"Return that card to the battlefield if its mana value is less than or equal to " +
|
||||||
BortukBonerattleCondition.instance,
|
"the number of basic land types among lands you control. Otherwise, put it into your hand."
|
||||||
null
|
)).withInterveningIf(CastFromEverywhereSourceCondition.instance);
|
||||||
)),
|
|
||||||
CastFromEverywhereSourceCondition.instance,
|
|
||||||
"When {this} enters, if you cast it, choose target creature card in your graveyard. " +
|
|
||||||
"Return that card to the battlefield if its mana value is less than or equal to the number of basic land types among lands you control. " +
|
|
||||||
"Otherwise, put it into your hand."
|
|
||||||
);
|
|
||||||
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
|
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
|
||||||
ability.addHint(DomainHint.instance);
|
ability.addHint(DomainHint.instance);
|
||||||
ability.setAbilityWord(AbilityWord.DOMAIN);
|
ability.setAbilityWord(AbilityWord.DOMAIN);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
|
||||||
import mage.abilities.condition.common.FerociousCondition;
|
import mage.abilities.condition.common.FerociousCondition;
|
||||||
import mage.abilities.costs.common.DiscardCardCost;
|
import mage.abilities.costs.common.DiscardCardCost;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.DoIfCostPaid;
|
import mage.abilities.effects.common.DoIfCostPaid;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.abilities.hint.common.FerociousHint;
|
import mage.abilities.hint.common.FerociousHint;
|
||||||
|
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;
|
||||||
|
|
@ -29,14 +28,9 @@ public final class BoundaryLandsRanger extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// At the beginning of combat on your turn, if you control a creature with power 4 or greater, you may discard a card. If you do, draw a card.
|
// At the beginning of combat on your turn, if you control a creature with power 4 or greater, you may discard a card. If you do, draw a card.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfCombatTriggeredAbility(new DoIfCostPaid(
|
||||||
new BeginningOfCombatTriggeredAbility(
|
new DrawCardSourceControllerEffect(1), new DiscardCardCost()
|
||||||
new DoIfCostPaid(
|
)).withInterveningIf(FerociousCondition.instance).addHint(FerociousHint.instance));
|
||||||
new DrawCardSourceControllerEffect(1), new DiscardCardCost()
|
|
||||||
)
|
|
||||||
), FerociousCondition.instance, "At the beginning of combat on your turn, if you control " +
|
|
||||||
"a creature with power 4 or greater, you may discard a card. If you do, draw a card."
|
|
||||||
).addHint(FerociousHint.instance));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoundaryLandsRanger(final BoundaryLandsRanger card) {
|
private BoundaryLandsRanger(final BoundaryLandsRanger card) {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ public final class BounteousKirin extends CardImpl {
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
// Whenever you cast a Spirit or Arcane spell, you may gain life equal to that spell's converted mana cost.
|
// Whenever you cast a Spirit or Arcane spell, you may gain life equal to that spell's converted mana cost.
|
||||||
this.addAbility(new SpellCastControllerTriggeredAbility(
|
this.addAbility(new SpellCastControllerTriggeredAbility(
|
||||||
new BounteousKirinEffect(), StaticFilters.FILTER_SPIRIT_OR_ARCANE_CARD,
|
new BounteousKirinEffect(), StaticFilters.FILTER_SPELL_SPIRIT_OR_ARCANE,
|
||||||
true, SetTargetPointer.SPELL
|
true, SetTargetPointer.SPELL
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ class BountyOfSkemfarEffect extends OneShotEffect {
|
||||||
|
|
||||||
BountyOfSkemfarEffect() {
|
BountyOfSkemfarEffect() {
|
||||||
super(Outcome.Benefit);
|
super(Outcome.Benefit);
|
||||||
staticText = "reveal the top six cards of your library. You may put a land card from among them " +
|
staticText = "reveal the top six cards of your library. You may put up to one land card from among them " +
|
||||||
"onto the battlefield tapped and an Elf card from among them into your hand. " +
|
"onto the battlefield tapped and up to one Elf card from among them into your hand. " +
|
||||||
"Put the rest on the bottom of your library in a random order";
|
"Put the rest on the bottom of your library in a random order";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.ObjectSourcePlayer;
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
|
|
@ -23,10 +22,10 @@ import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.TreasureToken;
|
import mage.game.permanent.token.TreasureToken;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.util.CardUtil;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -75,19 +74,11 @@ enum BoxingRingPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||||
return input
|
return CardUtil
|
||||||
.getObject()
|
.getEffectValueFromAbility(input.getSource(), "permanentEnteringBattlefield", Permanent.class)
|
||||||
.getManaValue()
|
|
||||||
== input
|
|
||||||
.getSource()
|
|
||||||
.getEffects()
|
|
||||||
.stream()
|
|
||||||
.map(effect -> effect.getValue("permanentEnteringBattlefield"))
|
|
||||||
.map(Permanent.class::cast)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.map(MageObject::getManaValue)
|
.map(MageObject::getManaValue)
|
||||||
.findFirst()
|
.filter(x -> x == input.getObject().getManaValue())
|
||||||
.orElse(-1);
|
.isPresent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ class BraidsArisenNightmareEffect extends OneShotEffect {
|
||||||
public BraidsArisenNightmareEffect() {
|
public BraidsArisenNightmareEffect() {
|
||||||
super(Outcome.Sacrifice);
|
super(Outcome.Sacrifice);
|
||||||
this.staticText = "you may sacrifice an artifact, creature, enchantment, land, or planeswalker. " +
|
this.staticText = "you may sacrifice an artifact, creature, enchantment, land, or planeswalker. " +
|
||||||
"If you do, each opponent may sacrifice a permanent that shares a card type with it. " +
|
"If you do, each opponent may sacrifice a permanent of their choice that shares a card type with it. " +
|
||||||
"For each opponent who doesn't, that player loses 2 life and you draw a card";
|
"For each opponent who doesn't, that player loses 2 life and you draw a card";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.condition.common.DescendedThisTurnCondition;
|
import mage.abilities.condition.common.DescendedThisTurnCondition;
|
||||||
import mage.abilities.condition.common.SourceHasCounterCondition;
|
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
|
|
@ -12,6 +12,7 @@ import mage.abilities.effects.common.RemoveAllCountersSourceEffect;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
import mage.abilities.keyword.TransformAbility;
|
||||||
|
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;
|
||||||
|
|
@ -30,6 +31,8 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class BrasssTunnelGrinder extends CardImpl {
|
public final class BrasssTunnelGrinder extends CardImpl {
|
||||||
|
|
||||||
|
private static final Condition condition = new SourceHasCounterCondition(CounterType.BORE, 3);
|
||||||
|
|
||||||
public BrasssTunnelGrinder(UUID ownerId, CardSetInfo setInfo) {
|
public BrasssTunnelGrinder(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{R}");
|
||||||
this.secondSideCardClazz = mage.cards.t.TecutlanTheSearingRift.class;
|
this.secondSideCardClazz = mage.cards.t.TecutlanTheSearingRift.class;
|
||||||
|
|
@ -45,14 +48,10 @@ public final class BrasssTunnelGrinder extends CardImpl {
|
||||||
TargetController.YOU, new AddCountersSourceEffect(CounterType.BORE.createInstance()),
|
TargetController.YOU, new AddCountersSourceEffect(CounterType.BORE.createInstance()),
|
||||||
false, DescendedThisTurnCondition.instance
|
false, DescendedThisTurnCondition.instance
|
||||||
);
|
);
|
||||||
|
ability.addEffect(new ConditionalOneShotEffect(
|
||||||
ConditionalOneShotEffect secondCheck = new ConditionalOneShotEffect(
|
new RemoveAllCountersSourceEffect(CounterType.BORE), condition,
|
||||||
new RemoveAllCountersSourceEffect(CounterType.BORE),
|
|
||||||
new SourceHasCounterCondition(CounterType.BORE, 3, Integer.MAX_VALUE),
|
|
||||||
"Then if there are three or more bore counters on it, remove those counters and transform it"
|
"Then if there are three or more bore counters on it, remove those counters and transform it"
|
||||||
);
|
).addEffect(new TransformSourceEffect()));
|
||||||
secondCheck.addEffect(new TransformSourceEffect());
|
|
||||||
ability.addEffect(secondCheck);
|
|
||||||
ability.addHint(DescendedThisTurnCount.getHint());
|
ability.addHint(DescendedThisTurnCount.getHint());
|
||||||
this.addAbility(ability, new DescendedWatcher());
|
this.addAbility(ability, new DescendedWatcher());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.triggers.BeginningOfPostcombatMainTriggeredAbility;
|
|
||||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||||
import mage.abilities.condition.common.RaidCondition;
|
import mage.abilities.condition.common.RaidCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.common.DamagePlayersEffect;
|
import mage.abilities.effects.common.DamagePlayersEffect;
|
||||||
import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect;
|
import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect;
|
||||||
import mage.abilities.hint.common.RaidHint;
|
import mage.abilities.hint.common.RaidHint;
|
||||||
|
import mage.abilities.triggers.BeginningOfPostcombatMainTriggeredAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.AbilityWord;
|
import mage.constants.AbilityWord;
|
||||||
|
|
@ -42,16 +40,11 @@ public final class BrazenCannonade extends CardImpl {
|
||||||
));
|
));
|
||||||
|
|
||||||
// Raid -- At the beginning of your postcombat main phase, if you attacked with a creature this turn, exile the top card of your library. Until end of combat on your next turn, you may play that card.
|
// Raid -- At the beginning of your postcombat main phase, if you attacked with a creature this turn, exile the top card of your library. Until end of combat on your next turn, you may play that card.
|
||||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new BeginningOfPostcombatMainTriggeredAbility(
|
||||||
new BeginningOfPostcombatMainTriggeredAbility(
|
new ExileTopXMayPlayUntilEffect(1, Duration.UntilEndCombatOfYourNextTurn), false
|
||||||
new ExileTopXMayPlayUntilEffect(
|
).withInterveningIf(RaidCondition.instance)
|
||||||
1, Duration.UntilEndCombatOfYourNextTurn
|
.setAbilityWord(AbilityWord.RAID)
|
||||||
), false
|
.addHint(RaidHint.instance), new PlayerAttackedWatcher());
|
||||||
), RaidCondition.instance, "At the beginning of each of your postcombat main phases, " +
|
|
||||||
"if you attacked this turn, exile the top card of your library. " +
|
|
||||||
"Until end of combat on your next turn, you may play that card."
|
|
||||||
);
|
|
||||||
this.addAbility(ability.setAbilityWord(AbilityWord.RAID).addHint(RaidHint.instance), new PlayerAttackedWatcher());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BrazenCannonade(final BrazenCannonade card) {
|
private BrazenCannonade(final BrazenCannonade card) {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.CastFromHandSourcePermanentCondition;
|
import mage.abilities.condition.common.CastFromHandSourcePermanentCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
||||||
|
|
@ -26,25 +21,25 @@ import mage.game.permanent.Permanent;
|
||||||
import mage.target.targetpointer.FixedTargets;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
import mage.watchers.common.CastFromHandWatcher;
|
import mage.watchers.common.CastFromHandWatcher;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class BreachingLeviathan extends CardImpl {
|
public final class BreachingLeviathan extends CardImpl {
|
||||||
|
|
||||||
public BreachingLeviathan(UUID ownerId, CardSetInfo setInfo) {
|
public BreachingLeviathan(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{7}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{U}{U}");
|
||||||
this.subtype.add(SubType.LEVIATHAN);
|
this.subtype.add(SubType.LEVIATHAN);
|
||||||
|
|
||||||
this.power = new MageInt(9);
|
this.power = new MageInt(9);
|
||||||
this.toughness = new MageInt(9);
|
this.toughness = new MageInt(9);
|
||||||
|
|
||||||
// When Breaching Leviathan enters the battlefield, if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps.
|
// When Breaching Leviathan enters the battlefield, if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new BreachingLeviathanEffect(), false)
|
||||||
new EntersBattlefieldTriggeredAbility(new BreachingLeviathanEffect(), false),
|
.withInterveningIf(CastFromHandSourcePermanentCondition.instance), new CastFromHandWatcher());
|
||||||
CastFromHandSourcePermanentCondition.instance,
|
|
||||||
"When {this} enters, if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps."),
|
|
||||||
new CastFromHandWatcher());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BreachingLeviathan(final BreachingLeviathan card) {
|
private BreachingLeviathan(final BreachingLeviathan card) {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ public final class BriarknitKami extends CardImpl {
|
||||||
this.power = new MageInt(3);
|
this.power = new MageInt(3);
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
// Whenever you cast a Spirit or Arcane spell, put a +1/+1 counter on target creature.
|
// Whenever you cast a Spirit or Arcane spell, put a +1/+1 counter on target creature.
|
||||||
Ability ability = new SpellCastControllerTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), StaticFilters.FILTER_SPIRIT_OR_ARCANE_CARD, false);
|
Ability ability = new SpellCastControllerTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), StaticFilters.FILTER_SPELL_SPIRIT_OR_ARCANE, false);
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
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