mirror of
https://github.com/correl/mage.git
synced 2024-11-21 19:18:40 +00:00
Ready for Review: Implementing Battles (#10156)
* add types and subtypes * add startingDefense attribute * [MOM] Implement Invasion of Ravnica / Guildpact Paragon * fix two small errors * refactor various instances of "any target" * fully implement defense counters * battles can now be attacked * [MOM] Implement Invasion of Dominaria / Serra Faithkeeper * [MOM] Implement Invasion of Innistrad / Deluge of the Dead * [MOM] Implement Invasion of Kaladesh / Aetherwing, Golden-Scale Flagship * [MOM] Implement Invasion of Kamigawa / Rooftop Saboteurs * [MOM] Implement Invasion of Karsus / Refraction Elemental * [MOM] Implement Invasion of Tolvada / The Broken Sky * simplify battle info ability * fix verify failure * some more fixes for attacking battles * [MOM] Implement Invasion of Kaldheim / Pyre of the World Tree * [MOM] Implement Invasion of Lorwyn / Winnowing Forces * [MOM] Implement Invasion of Moag / Bloomwielder Dryads * [MOM] Implement Invasion of Shandalar / Leyline Surge * [MOM] Implement Invasion of Belenon / Belenon War Anthem * [MOM] Implement Invasion of Pyrulea / Gargantuan Slabhorn * [MOM] Implement Invasion of Vryn / Overloaded Mage-Ring * [MOM] Implement Marshal of Zhalfir * [MOM] Implement Sunfall * implement protectors for sieges * partially implement siege defeated trigger * fix verify failure * some updates to blocking * [MOM] Implement Invasion of Mercadia / Kyren Flamewright * [MOM] Implement Invasion of Theros / Ephara, Ever-Sheltering * [MOM] Implement Invasion of Ulgrotha / Grandmother Ravi Sengir * [MOM] Implement Invasion of Xerex / Vertex Paladin * add initial battle test * fix verify failure * [MOM] Implement Invasion of Amonkhet / Lazotep Convert * [MOM] update spoiler * update how protectors are chosen * update text * battles can't block * add control change test * rename battle test for duel * add multiplayer test * [MOM] Implement Invasion of Alara / Awaken the Maelstrom * [MOM] Implement Invasion of Eldraine * [MOM] Implement Invasion of Ergamon / Truga Cliffhanger * [MOM] Implement Invasion of Ixalan / Belligerent Regisaur * battles now cast transformed (this is super hacky but we need to refactor TDFCs anyway) * add TODO * add ignore for randomly failing test * a few small fixes * add defense to MtgJsonCard (unused like loyalty) * implement ProtectorIdPredicate * small fixes
This commit is contained in:
parent
edf1cff8a8
commit
947351932b
129 changed files with 4057 additions and 1087 deletions
|
@ -524,7 +524,13 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
private final CardTypeCounter planeswalkerCounter = new CardTypeCounter() {
|
||||
@Override
|
||||
protected boolean is(CardView card) {
|
||||
return card.isPlanesWalker();
|
||||
return card.isPlaneswalker();
|
||||
}
|
||||
};
|
||||
private final CardTypeCounter battleCounter = new CardTypeCounter() {
|
||||
@Override
|
||||
protected boolean is(CardView card) {
|
||||
return card.isBattle();
|
||||
}
|
||||
};
|
||||
private final CardTypeCounter tribalCounter = new CardTypeCounter() {
|
||||
|
@ -542,6 +548,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
instantCounter,
|
||||
planeswalkerCounter,
|
||||
sorceryCounter,
|
||||
battleCounter,
|
||||
tribalCounter
|
||||
};
|
||||
|
||||
|
|
|
@ -314,7 +314,7 @@ public class CardViewEDHPowerLevelComparator implements CardViewComparator {
|
|||
thisMaxPower = Math.max(thisMaxPower, 1);
|
||||
}
|
||||
|
||||
if (card.isPlanesWalker()) {
|
||||
if (card.isPlaneswalker()) {
|
||||
thisMaxPower = Math.max(thisMaxPower, 6);
|
||||
}
|
||||
|
||||
|
|
|
@ -313,11 +313,15 @@ public final class GuiDisplayUtil {
|
|||
}
|
||||
buffer.append("</td></tr></table>");
|
||||
|
||||
String pt = "";
|
||||
String pt;
|
||||
if (card.isCreature()) {
|
||||
pt = card.getPower() + '/' + card.getToughness();
|
||||
} else if (card.isPlanesWalker()) {
|
||||
} else if (card.isPlaneswalker()) {
|
||||
pt = card.getLoyalty();
|
||||
} else if (card.isBattle()) {
|
||||
pt = card.getDefense();
|
||||
} else {
|
||||
pt = "";
|
||||
}
|
||||
|
||||
buffer.append("<table cellspacing=0 cellpadding=0 border=0 width='100%' valign='bottom'><tr><td><b>");
|
||||
|
|
|
@ -797,8 +797,10 @@ public abstract class CardPanel extends MagePermanent implements ComponentListen
|
|||
}
|
||||
if (card.isCreature()) {
|
||||
sb.append('\n').append(card.getPower()).append('/').append(card.getToughness());
|
||||
} else if (card.isPlanesWalker()) {
|
||||
} else if (card.isPlaneswalker()) {
|
||||
sb.append('\n').append(card.getLoyalty());
|
||||
} else if (card.isBattle()) {
|
||||
sb.append('\n').append(card.getDefense());
|
||||
}
|
||||
if (card.getRules() == null) {
|
||||
card.overrideRules(new ArrayList<>());
|
||||
|
|
|
@ -803,10 +803,14 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
ptText1.setText(getGameCard().getPower());
|
||||
ptText2.setText("/");
|
||||
ptText3.setText(CardRendererUtils.getCardLifeWithDamage(getGameCard()));
|
||||
} else if (card.isPlanesWalker()) {
|
||||
} else if (card.isPlaneswalker()) {
|
||||
ptText1.setText("");
|
||||
ptText2.setText("");
|
||||
ptText3.setText(getGameCard().getLoyalty());
|
||||
} else if (card.isBattle()) {
|
||||
ptText1.setText("");
|
||||
ptText2.setText("");
|
||||
ptText3.setText(getGameCard().getDefense());
|
||||
} else {
|
||||
ptText1.setText("");
|
||||
ptText2.setText("");
|
||||
|
|
|
@ -62,6 +62,7 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
&& a.getPower().equals(b.getPower())
|
||||
&& a.getToughness().equals(b.getToughness())
|
||||
&& a.getLoyalty().equals(b.getLoyalty())
|
||||
&& a.getDefense().equals(b.getDefense())
|
||||
&& 0 == a.getColor().compareTo(b.getColor())
|
||||
&& a.getCardTypes().equals(b.getCardTypes())
|
||||
&& a.getSubTypes().equals(b.getSubTypes())
|
||||
|
@ -128,6 +129,7 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
sb.append(this.view.getPower());
|
||||
sb.append(this.view.getToughness());
|
||||
sb.append(this.view.getLoyalty());
|
||||
sb.append(this.view.getDefense());
|
||||
sb.append(this.view.getColor().toString());
|
||||
sb.append(this.view.getType());
|
||||
sb.append(this.view.getExpansionSetCode());
|
||||
|
|
|
@ -530,37 +530,37 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
g.setPaint(getSpiralLandTextboxColor(twoColors.get(0), twoColors.get(1), true));
|
||||
|
||||
// Horizontal bars
|
||||
g.fillRect(totalContentInset + 1 , typeLineY + boxHeight + 1 , contentWidth - 2 , height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 2*height_of_spiral, typeLineY + boxHeight + 1 + 2*height_of_spiral , contentWidth - 2 - 4*height_of_spiral , height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 4*height_of_spiral, typeLineY + boxHeight + 1 + 4*height_of_spiral , contentWidth - 2 - 8*height_of_spiral , height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 6*height_of_spiral, typeLineY + boxHeight + 1 + 6*height_of_spiral , contentWidth - 2 - 12*height_of_spiral, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1, typeLineY + boxHeight + 1, contentWidth - 2, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 2 * height_of_spiral, typeLineY + boxHeight + 1 + 2 * height_of_spiral, contentWidth - 2 - 4 * height_of_spiral, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 4 * height_of_spiral, typeLineY + boxHeight + 1 + 4 * height_of_spiral, contentWidth - 2 - 8 * height_of_spiral, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 6 * height_of_spiral, typeLineY + boxHeight + 1 + 6 * height_of_spiral, contentWidth - 2 - 12 * height_of_spiral, height_of_spiral);
|
||||
|
||||
g.fillRect(totalContentInset + 1 + 6*height_of_spiral, typeLineY + boxHeight + 1 + total_height_of_box - 7*height_of_spiral, contentWidth - 2 - 12*height_of_spiral, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 4*height_of_spiral, typeLineY + boxHeight + 1 + total_height_of_box - 5*height_of_spiral, contentWidth - 2 - 8*height_of_spiral , height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 2*height_of_spiral, typeLineY + boxHeight + 1 + total_height_of_box - 3*height_of_spiral, contentWidth - 2 - 4*height_of_spiral , height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 , typeLineY + boxHeight + 1 + total_height_of_box - height_of_spiral , contentWidth - 2 , height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 6 * height_of_spiral, typeLineY + boxHeight + 1 + total_height_of_box - 7 * height_of_spiral, contentWidth - 2 - 12 * height_of_spiral, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 4 * height_of_spiral, typeLineY + boxHeight + 1 + total_height_of_box - 5 * height_of_spiral, contentWidth - 2 - 8 * height_of_spiral, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 2 * height_of_spiral, typeLineY + boxHeight + 1 + total_height_of_box - 3 * height_of_spiral, contentWidth - 2 - 4 * height_of_spiral, height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1, typeLineY + boxHeight + 1 + total_height_of_box - height_of_spiral, contentWidth - 2, height_of_spiral);
|
||||
|
||||
// Vertical bars
|
||||
g.fillRect(totalContentInset + 1 , typeLineY + boxHeight + 1 , height_of_spiral, total_height_spiral - 1 );
|
||||
g.fillRect(totalContentInset + 1 + 2*height_of_spiral, typeLineY + boxHeight + 1 + 2*height_of_spiral, height_of_spiral, total_height_spiral - 1 - 4*height_of_spiral );
|
||||
g.fillRect(totalContentInset + 1 + 4*height_of_spiral, typeLineY + boxHeight + 1 + 4*height_of_spiral, height_of_spiral, total_height_spiral - 1 - 8*height_of_spiral );
|
||||
g.fillRect(totalContentInset + 1 + 6*height_of_spiral, typeLineY + boxHeight + 1 + 6*height_of_spiral, height_of_spiral, total_height_spiral - 1 - 12*height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1, typeLineY + boxHeight + 1, height_of_spiral, total_height_spiral - 1);
|
||||
g.fillRect(totalContentInset + 1 + 2 * height_of_spiral, typeLineY + boxHeight + 1 + 2 * height_of_spiral, height_of_spiral, total_height_spiral - 1 - 4 * height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 4 * height_of_spiral, typeLineY + boxHeight + 1 + 4 * height_of_spiral, height_of_spiral, total_height_spiral - 1 - 8 * height_of_spiral);
|
||||
g.fillRect(totalContentInset + 1 + 6 * height_of_spiral, typeLineY + boxHeight + 1 + 6 * height_of_spiral, height_of_spiral, total_height_spiral - 1 - 12 * height_of_spiral);
|
||||
|
||||
g.fillRect(totalContentInset + contentWidth - 7*height_of_spiral, typeLineY + boxHeight + 1 + 6*height_of_spiral, height_of_spiral, total_height_spiral - 1 - 12*height_of_spiral);
|
||||
g.fillRect(totalContentInset + contentWidth - 5*height_of_spiral, typeLineY + boxHeight + 1 + 4*height_of_spiral, height_of_spiral, total_height_spiral - 1 - 8*height_of_spiral );
|
||||
g.fillRect(totalContentInset + contentWidth - 3*height_of_spiral, typeLineY + boxHeight + 1 + 2*height_of_spiral, height_of_spiral, total_height_spiral - 1 - 4*height_of_spiral );
|
||||
g.fillRect(totalContentInset + contentWidth - 1*height_of_spiral, typeLineY + boxHeight + 1 + 0*height_of_spiral, height_of_spiral, total_height_spiral - 1 );
|
||||
g.fillRect(totalContentInset + contentWidth - 7 * height_of_spiral, typeLineY + boxHeight + 1 + 6 * height_of_spiral, height_of_spiral, total_height_spiral - 1 - 12 * height_of_spiral);
|
||||
g.fillRect(totalContentInset + contentWidth - 5 * height_of_spiral, typeLineY + boxHeight + 1 + 4 * height_of_spiral, height_of_spiral, total_height_spiral - 1 - 8 * height_of_spiral);
|
||||
g.fillRect(totalContentInset + contentWidth - 3 * height_of_spiral, typeLineY + boxHeight + 1 + 2 * height_of_spiral, height_of_spiral, total_height_spiral - 1 - 4 * height_of_spiral);
|
||||
g.fillRect(totalContentInset + contentWidth - 1 * height_of_spiral, typeLineY + boxHeight + 1 + 0 * height_of_spiral, height_of_spiral, total_height_spiral - 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
g.fillRect(
|
||||
totalContentInset + 1, typeLineY,
|
||||
contentWidth - 2, cardHeight - borderWidth * 3 - typeLineY - 1);
|
||||
totalContentInset + 1, typeLineY,
|
||||
contentWidth - 2, cardHeight - borderWidth * 3 - typeLineY - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// If it's a planeswalker, extend the textbox left border by some
|
||||
if (cardView.isPlanesWalker()) {
|
||||
if (cardView.isPlaneswalker()) {
|
||||
g.setPaint(borderPaint);
|
||||
g.fillRect(
|
||||
totalContentInset, typeLineY + boxHeight,
|
||||
|
@ -1116,7 +1116,7 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
|
||||
// Is it a walker? (But don't draw the box if it's a non-permanent view
|
||||
// of a walker without a starting loyalty (EG: Arlin Kord's flipped side).
|
||||
if (cardView.isPlanesWalker()
|
||||
if (cardView.isPlaneswalker()
|
||||
&& (cardView instanceof PermanentView || !cardView.getStartingLoyalty().equals("0"))) {
|
||||
// Draw the PW loyalty box
|
||||
int w = partBoxWidth;
|
||||
|
@ -1124,26 +1124,15 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
int x = cardWidth - partBoxWidth - borderWidth;
|
||||
int y = curY - h;
|
||||
|
||||
Polygon symbol = new Polygon(
|
||||
new int[]{
|
||||
x + w / 2,
|
||||
(int) (x + w * 0.9),
|
||||
x + w,
|
||||
(int) (x + w * 0.6),
|
||||
x + w / 2,
|
||||
(int) (x + w * 0.4),
|
||||
x,
|
||||
(int) (x + w * 0.1),},
|
||||
new int[]{
|
||||
y + h,
|
||||
(int) (y + 0.8 * h),
|
||||
y,
|
||||
(int) (y - 0.2 * h),
|
||||
y,
|
||||
(int) (y - 0.2 * h),
|
||||
y,
|
||||
(int) (y + 0.8 * h),},
|
||||
8);
|
||||
Polygon symbol = new Polygon();
|
||||
symbol.addPoint(x + w / 2, y + h);
|
||||
symbol.addPoint((int) (x + w * 0.9), (int) (y + 0.8 * h));
|
||||
symbol.addPoint(x + w, y);
|
||||
symbol.addPoint((int) (x + w * 0.6), (int) (y - 0.2 * h));
|
||||
symbol.addPoint(x + w / 2, y);
|
||||
symbol.addPoint((int) (x + w * 0.4), (int) (y - 0.2 * h));
|
||||
symbol.addPoint(x, y);
|
||||
symbol.addPoint((int) (x + w * 0.1), (int) (y + 0.8 * h));
|
||||
|
||||
// Draw + stroke
|
||||
g.setColor(Color.black);
|
||||
|
@ -1170,6 +1159,59 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
curY -= (int) (1.2 * y);
|
||||
}
|
||||
|
||||
// Is it a battle?
|
||||
if (cardView.isBattle()
|
||||
&& (cardView instanceof PermanentView || !cardView.getStartingDefense().equals("0"))) {
|
||||
// Draw the PW loyalty box
|
||||
int w = 3 * partBoxWidth / 4;
|
||||
int h = 3 * partBoxWidth / 4;
|
||||
int x = cardWidth - w - borderWidth;
|
||||
int y = curY - h;
|
||||
|
||||
Polygon symbol = new Polygon();
|
||||
symbol.addPoint(x + (0 * w) / 80, y + (2 * h) / 80);
|
||||
symbol.addPoint(x + (12 * w) / 80, y + (30 * h) / 80);
|
||||
symbol.addPoint(x + (3 * w) / 80, y + (40 * h) / 80);
|
||||
symbol.addPoint(x + (12 * w) / 80, y + (50 * h) / 80);
|
||||
symbol.addPoint(x + (0 * w) / 80, y + (78 * h) / 80);
|
||||
symbol.addPoint(x + (30 * w) / 80, y + (71 * h) / 80);
|
||||
symbol.addPoint(x + (40 * w) / 80, y + (80 * h) / 80);
|
||||
symbol.addPoint(x + (50 * w) / 80, y + (71 * h) / 80);
|
||||
symbol.addPoint(x + (80 * w) / 80, y + (78 * h) / 80);
|
||||
symbol.addPoint(x + (68 * w) / 80, y + (50 * h) / 80);
|
||||
symbol.addPoint(x + (77 * w) / 80, y + (40 * h) / 80);
|
||||
symbol.addPoint(x + (68 * w) / 80, y + (30 * h) / 80);
|
||||
symbol.addPoint(x + (80 * w) / 80, y + (2 * h) / 80);
|
||||
symbol.addPoint(x + (48 * w) / 80, y + (9 * h) / 80);
|
||||
symbol.addPoint(x + (40 * w) / 80, y + (0 * h) / 80);
|
||||
symbol.addPoint(x + (32 * w) / 80, y + (9 * h) / 80);
|
||||
|
||||
|
||||
// Draw + stroke
|
||||
g.setColor(Color.black);
|
||||
g.fillPolygon(symbol);
|
||||
g.setColor(new Color(200, 200, 200));
|
||||
g.setStroke(new BasicStroke(2));
|
||||
g.drawPolygon(symbol);
|
||||
g.setStroke(new BasicStroke(1));
|
||||
|
||||
// Loyalty number
|
||||
String defense;
|
||||
if (cardView instanceof PermanentView) {
|
||||
defense = cardView.getDefense();
|
||||
} else {
|
||||
defense = cardView.getStartingDefense();
|
||||
}
|
||||
|
||||
g.setFont(ptTextFont);
|
||||
g.setColor(Color.white);
|
||||
int defenseWidth = g.getFontMetrics().stringWidth(defense);
|
||||
g.drawString(defense, x + 1 + (w - defenseWidth) / 2, y - 1 + ptTextHeight + (h - ptTextHeight) / 2);
|
||||
|
||||
// Advance
|
||||
curY -= (int) (1.2 * y);
|
||||
}
|
||||
|
||||
// does it have damage on it?
|
||||
if ((cardView instanceof PermanentView) && ((PermanentView) cardView).getDamage() > 0) {
|
||||
int x = cardWidth - partBoxWidth - borderWidth;
|
||||
|
@ -1769,7 +1811,7 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
|
||||
private static Color getLessOpaqueColor(Color color, boolean lessOpaqueRulesTextBox) {
|
||||
if (lessOpaqueRulesTextBox) {
|
||||
Color lessOpaque = new Color (color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha() - 50);
|
||||
Color lessOpaque = new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha() - 50);
|
||||
return lessOpaque;
|
||||
}
|
||||
return color;
|
||||
|
|
|
@ -27,6 +27,7 @@ public class AbilityView extends CardView {
|
|||
this.power = "";
|
||||
this.toughness = "";
|
||||
this.loyalty = "";
|
||||
this.defense = "";
|
||||
this.cardTypes = new ArrayList<>();
|
||||
this.subTypes = new SubTypes();
|
||||
this.superTypes = EnumSet.noneOf(SuperType.class);
|
||||
|
|
|
@ -64,7 +64,10 @@ public class CardView extends SimpleCardView {
|
|||
protected String toughness;
|
||||
@Expose
|
||||
protected String loyalty = "";
|
||||
@Expose
|
||||
protected String defense = "";
|
||||
protected String startingLoyalty;
|
||||
protected String startingDefense;
|
||||
protected List<CardType> cardTypes;
|
||||
protected SubTypes subTypes;
|
||||
protected Set<SuperType> superTypes;
|
||||
|
@ -172,6 +175,8 @@ public class CardView extends SimpleCardView {
|
|||
this.toughness = cardView.toughness;
|
||||
this.loyalty = cardView.loyalty;
|
||||
this.startingLoyalty = cardView.startingLoyalty;
|
||||
this.defense = cardView.defense;
|
||||
this.startingDefense = cardView.startingDefense;
|
||||
this.cardTypes = new ArrayList<>(cardView.cardTypes);
|
||||
this.subTypes = new SubTypes(cardView.subTypes);
|
||||
this.superTypes = cardView.superTypes;
|
||||
|
@ -397,6 +402,7 @@ public class CardView extends SimpleCardView {
|
|||
if (game != null) {
|
||||
if (permanent.getCounters(game) != null && !permanent.getCounters(game).isEmpty()) {
|
||||
this.loyalty = Integer.toString(permanent.getCounters(game).getCount(CounterType.LOYALTY));
|
||||
this.defense = Integer.toString(permanent.getCounters(game).getCount(CounterType.DEFENSE));
|
||||
counters = new ArrayList<>();
|
||||
for (Counter counter : permanent.getCounters(game).values()) {
|
||||
counters.add(new CounterView(counter));
|
||||
|
@ -435,6 +441,7 @@ public class CardView extends SimpleCardView {
|
|||
this.mageObjectType = MageObjectType.CARD;
|
||||
}
|
||||
this.loyalty = "";
|
||||
this.defense = "";
|
||||
if (game != null && card.getCounters(game) != null && !card.getCounters(game).isEmpty()) {
|
||||
counters = new ArrayList<>();
|
||||
for (Counter counter : card.getCounters(game).values()) {
|
||||
|
@ -591,7 +598,10 @@ public class CardView extends SimpleCardView {
|
|||
this.frameStyle = card.getFrameStyle();
|
||||
|
||||
// Get starting loyalty
|
||||
this.startingLoyalty = CardUtil.convertStartingLoyalty(card.getStartingLoyalty());
|
||||
this.startingLoyalty = CardUtil.convertLoyaltyOrDefense(card.getStartingLoyalty());
|
||||
|
||||
// Get starting defense
|
||||
this.startingDefense = CardUtil.convertLoyaltyOrDefense(card.getStartingDefense());
|
||||
}
|
||||
|
||||
public CardView(MageObject object, Game game) {
|
||||
|
@ -606,10 +616,12 @@ public class CardView extends SimpleCardView {
|
|||
this.power = Integer.toString(object.getPower().getValue());
|
||||
this.toughness = Integer.toString(object.getToughness().getValue());
|
||||
this.loyalty = Integer.toString(((Permanent) object).getCounters((Game) null).getCount(CounterType.LOYALTY));
|
||||
this.defense = Integer.toString(((Permanent) object).getCounters((Game) null).getCount(CounterType.DEFENSE));
|
||||
} else {
|
||||
this.power = object.getPower().toString();
|
||||
this.toughness = object.getToughness().toString();
|
||||
this.loyalty = "";
|
||||
this.defense = "";
|
||||
}
|
||||
this.cardTypes = new ArrayList<>(object.getCardType(game));
|
||||
this.subTypes = new SubTypes(object.getSubtype(game));
|
||||
|
@ -664,8 +676,10 @@ public class CardView extends SimpleCardView {
|
|||
this.frameColor = object.getFrameColor(game).copy();
|
||||
// Frame style
|
||||
this.frameStyle = object.getFrameStyle();
|
||||
// Starting loyalty. Must be extracted from an ability
|
||||
this.startingLoyalty = CardUtil.convertStartingLoyalty(object.getStartingLoyalty());
|
||||
// Starting loyalty
|
||||
this.startingLoyalty = CardUtil.convertLoyaltyOrDefense(object.getStartingLoyalty());
|
||||
// Starting defense
|
||||
this.startingDefense = CardUtil.convertLoyaltyOrDefense(object.getStartingDefense());
|
||||
}
|
||||
|
||||
protected CardView() {
|
||||
|
@ -750,6 +764,8 @@ public class CardView extends SimpleCardView {
|
|||
this.toughness = "";
|
||||
this.loyalty = "";
|
||||
this.startingLoyalty = "";
|
||||
this.defense = "";
|
||||
this.startingDefense = "";
|
||||
this.cardTypes = new ArrayList<>();
|
||||
this.subTypes = new SubTypes();
|
||||
this.superTypes = EnumSet.noneOf(SuperType.class);
|
||||
|
@ -800,6 +816,8 @@ public class CardView extends SimpleCardView {
|
|||
this.toughness = token.getToughness().toString();
|
||||
this.loyalty = "";
|
||||
this.startingLoyalty = "";
|
||||
this.defense = "";
|
||||
this.startingDefense = "";
|
||||
this.cardTypes = new ArrayList<>(token.getCardType(game));
|
||||
this.subTypes = new SubTypes(token.getSubtype(game));
|
||||
this.superTypes = token.getSuperType();
|
||||
|
@ -891,6 +909,14 @@ public class CardView extends SimpleCardView {
|
|||
return startingLoyalty;
|
||||
}
|
||||
|
||||
public String getDefense() {
|
||||
return defense;
|
||||
}
|
||||
|
||||
public String getStartingDefense() {
|
||||
return startingDefense;
|
||||
}
|
||||
|
||||
public List<CardType> getCardTypes() {
|
||||
return cardTypes;
|
||||
}
|
||||
|
@ -1147,10 +1173,14 @@ public class CardView extends SimpleCardView {
|
|||
return cardTypes.contains(CardType.CREATURE);
|
||||
}
|
||||
|
||||
public boolean isPlanesWalker() {
|
||||
public boolean isPlaneswalker() {
|
||||
return cardTypes.contains(CardType.PLANESWALKER);
|
||||
}
|
||||
|
||||
public boolean isBattle() {
|
||||
return cardTypes.contains(CardType.BATTLE);
|
||||
}
|
||||
|
||||
public String getColorText() {
|
||||
String colorText = getColor().getDescription();
|
||||
return colorText.substring(0, 1).toUpperCase(Locale.ENGLISH) + colorText.substring(1);
|
||||
|
|
|
@ -43,6 +43,7 @@ public class StackAbilityView extends CardView {
|
|||
this.sourceCard.setMageObjectType(mageObjectType);
|
||||
this.name = "Ability";
|
||||
this.loyalty = "";
|
||||
this.defense = "";
|
||||
|
||||
this.cardTypes = ability.getCardType(game);
|
||||
this.subTypes = ability.getSubtype(game);
|
||||
|
|
|
@ -282,9 +282,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
TargetAnyTarget origTarget = (TargetAnyTarget) target.getOriginalTarget();
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(abilityControllerId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
targets = threats(abilityControllerId, source, ((FilterAnyTarget) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
} else {
|
||||
targets = threats(randomOpponentId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
targets = threats(randomOpponentId, source, ((FilterAnyTarget) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
}
|
||||
for (Permanent permanent : targets) {
|
||||
List<UUID> alreadyTargetted = target.getTargets();
|
||||
|
@ -749,9 +749,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
TargetAnyTarget origTarget = ((TargetAnyTarget) target.getOriginalTarget());
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(abilityControllerId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
targets = threats(abilityControllerId, source, ((FilterAnyTarget) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
} else {
|
||||
targets = threats(randomOpponentId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
targets = threats(randomOpponentId, source, ((FilterAnyTarget) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
}
|
||||
|
||||
if (targets.isEmpty()) {
|
||||
|
@ -765,7 +765,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
if (targets.isEmpty() && required) {
|
||||
targets = game.getBattlefield().getActivePermanents(((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), playerId, game);
|
||||
targets = game.getBattlefield().getActivePermanents(((FilterAnyTarget) origTarget.getFilter()).getPermanentFilter(), playerId, game);
|
||||
}
|
||||
for (Permanent permanent : targets) {
|
||||
List<UUID> alreadyTargeted = target.getTargets();
|
||||
|
|
|
@ -1795,7 +1795,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
declareAttacker(attackerId, possibleDefender.iterator().next(), game, true);
|
||||
return true;
|
||||
} else {
|
||||
TargetDefender target = new TargetDefender(possibleDefender, attackerId);
|
||||
TargetDefender target = new TargetDefender(possibleDefender);
|
||||
if (forcedToAttack) {
|
||||
StringBuilder sb = new StringBuilder(target.getTargetName());
|
||||
Permanent attacker = game.getPermanent(attackerId);
|
||||
|
@ -1814,7 +1814,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
}
|
||||
|
||||
protected UUID selectDefenderForAllAttack(Set<UUID> defenders, Game game) {
|
||||
TargetDefender target = new TargetDefender(defenders, null);
|
||||
TargetDefender target = new TargetDefender(defenders);
|
||||
if (chooseTarget(Outcome.Damage, target, null, game)) {
|
||||
return getFixedResponseUUID(game);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.dynamicvalue.common.ArtifactYouControlCount;
|
||||
import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect;
|
||||
import mage.abilities.keyword.CrewAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class AetherwingGoldenScaleFlagship extends CardImpl {
|
||||
|
||||
public AetherwingGoldenScaleFlagship(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.VEHICLE);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(4);
|
||||
this.color.setBlue(true);
|
||||
this.color.setRed(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Aetherwing, Golden-Scale Flagship's power is equal to the number of artifacts you control.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerSourceEffect(ArtifactYouControlCount.instance, Duration.Custom)));
|
||||
|
||||
// Crew 1
|
||||
this.addAbility(new CrewAbility(1));
|
||||
}
|
||||
|
||||
private AetherwingGoldenScaleFlagship(final AetherwingGoldenScaleFlagship card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AetherwingGoldenScaleFlagship copy() {
|
||||
return new AetherwingGoldenScaleFlagship(this);
|
||||
}
|
||||
}
|
|
@ -9,9 +9,10 @@ import mage.constants.CardType;
|
|||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -40,8 +41,8 @@ public final class AllWillBeOne extends CardImpl {
|
|||
|
||||
class AllWillBeOneTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filter =
|
||||
new FilterCreaturePlayerOrPlaneswalker("target opponent, creature an opponent controls, or planeswalker an opponent controls");
|
||||
private static final FilterPermanentOrPlayer filter
|
||||
= new FilterCreaturePlayerOrPlaneswalker("opponent, creature an opponent controls, or planeswalker an opponent controls.");
|
||||
|
||||
static {
|
||||
filter.getPermanentFilter().add(TargetController.NOT_YOU.getControllerPredicate());
|
||||
|
@ -50,7 +51,7 @@ class AllWillBeOneTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
AllWillBeOneTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new DamageTargetEffect(SavedDamageValue.MUCH));
|
||||
this.addTarget(new TargetAnyTarget(filter));
|
||||
this.addTarget(new TargetPermanentOrPlayer(filter));
|
||||
}
|
||||
|
||||
private AllWillBeOneTriggeredAbility(final AllWillBeOneTriggeredAbility ability) {
|
||||
|
|
|
@ -7,13 +7,14 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.other.AnotherTargetPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.util.UUID;
|
||||
|
@ -23,23 +24,21 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class ArcTrail extends CardImpl {
|
||||
|
||||
private static final FilterPermanentOrPlayer filter1 = new FilterAnyTarget("creature, player or planeswalker to deal 2 damage");
|
||||
private static final FilterPermanentOrPlayer filter2 = new FilterAnyTarget("another creature, player or planeswalker to deal 1 damage");
|
||||
|
||||
static {
|
||||
filter2.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
filter2.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
}
|
||||
|
||||
public ArcTrail(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}");
|
||||
|
||||
// Arc Trail deals 2 damage to any target and 1 damage to another any target
|
||||
FilterCreaturePlayerOrPlaneswalker filter1 = new FilterCreaturePlayerOrPlaneswalker("creature, player or planeswalker to deal 2 damage");
|
||||
TargetAnyTarget target1 = new TargetAnyTarget(1, 1, filter1);
|
||||
target1.setTargetTag(1);
|
||||
this.getSpellAbility().addTarget(target1);
|
||||
|
||||
FilterCreaturePlayerOrPlaneswalker filter2 = new FilterCreaturePlayerOrPlaneswalker("another creature, player or planeswalker to deal 1 damage");
|
||||
filter2.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
filter2.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
TargetAnyTarget target2 = new TargetAnyTarget(1, 1, filter2);
|
||||
target2.setTargetTag(2);
|
||||
this.getSpellAbility().addTarget(target2);
|
||||
|
||||
this.getSpellAbility().addEffect(ArcTrailEffect.getInstance());
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter1).setTargetTag(1));
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter2).setTargetTag(2));
|
||||
}
|
||||
|
||||
private ArcTrail(final ArcTrail card) {
|
||||
|
|
127
Mage.Sets/src/mage/cards/a/AwakenTheMaelstrom.java
Normal file
127
Mage.Sets/src/mage/cards/a/AwakenTheMaelstrom.java
Normal file
|
@ -0,0 +1,127 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.*;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.target.common.TargetCreaturePermanentAmount;
|
||||
import mage.target.common.TargetPermanentAmount;
|
||||
import mage.target.targetpointer.SecondTargetPointer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class AwakenTheMaelstrom extends CardImpl {
|
||||
|
||||
public AwakenTheMaelstrom(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "");
|
||||
|
||||
this.nightCard = true;
|
||||
|
||||
// Awaken the Maelstrom is all colors.
|
||||
this.color.setWhite(true);
|
||||
this.color.setBlue(true);
|
||||
this.color.setBlack(true);
|
||||
this.color.setRed(true);
|
||||
this.color.setGreen(true);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("{this} is all colors")));
|
||||
|
||||
// Target player draws two cards.
|
||||
this.getSpellAbility().addEffect(new DrawCardTargetEffect(1));
|
||||
this.getSpellAbility().addTarget(new TargetPlayer().withChooseHint("to draw two cards"));
|
||||
|
||||
// You may put an artifact card from your hand onto the battlefield.
|
||||
this.getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_ARTIFACT_AN));
|
||||
|
||||
// Create a token that's a copy of a permanent you control.
|
||||
// Distribute three +1/+1 counters among one, two, or three creatures you control.
|
||||
this.getSpellAbility().addEffect(new AwakenTheMaelstromEffect());
|
||||
|
||||
// Destroy target permanent an opponent controls.
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect().setTargetPointer(new SecondTargetPointer()));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT).withChooseHint("to destroy"));
|
||||
}
|
||||
|
||||
private AwakenTheMaelstrom(final AwakenTheMaelstrom card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AwakenTheMaelstrom copy() {
|
||||
return new AwakenTheMaelstrom(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AwakenTheMaelstromEffect extends OneShotEffect {
|
||||
|
||||
AwakenTheMaelstromEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Create a token that's a copy of a permanent you control. " +
|
||||
"Distribute three +1/+1 counters among one, two, or three creatures you control.";
|
||||
}
|
||||
|
||||
private AwakenTheMaelstromEffect(final AwakenTheMaelstromEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AwakenTheMaelstromEffect copy() {
|
||||
return new AwakenTheMaelstromEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
makeToken(player, game, source);
|
||||
distributeCounters(player, game, source);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void makeToken(Player player, Game game, Ability source) {
|
||||
TargetPermanent target = new TargetControlledCreaturePermanent();
|
||||
target.setNotTarget(true);
|
||||
target.withChooseHint("to copy");
|
||||
if (!target.canChoose(player.getId(), source, game)) {
|
||||
return;
|
||||
}
|
||||
player.choose(outcome, target, source, game);
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
new CreateTokenCopyTargetEffect().setSavedPermanent(permanent).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
||||
private void distributeCounters(Player player, Game game, Ability source) {
|
||||
if (game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game) < 1) {
|
||||
return;
|
||||
}
|
||||
TargetPermanentAmount target = new TargetCreaturePermanentAmount(3);
|
||||
target.setNotTarget(true);
|
||||
target.withChooseHint("to distribute counters");
|
||||
player.choose(outcome, target, source, game);
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(target.getTargetAmount(targetId)), source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
Mage.Sets/src/mage/cards/b/BelenonWarAnthem.java
Normal file
35
Mage.Sets/src/mage/cards/b/BelenonWarAnthem.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class BelenonWarAnthem extends CardImpl {
|
||||
|
||||
public BelenonWarAnthem(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "");
|
||||
|
||||
this.color.setWhite(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Creatures you control get +1/+1.
|
||||
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield)));
|
||||
}
|
||||
|
||||
private BelenonWarAnthem(final BelenonWarAnthem card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BelenonWarAnthem copy() {
|
||||
return new BelenonWarAnthem(this);
|
||||
}
|
||||
}
|
47
Mage.Sets/src/mage/cards/b/BelligerentRegisaur.java
Normal file
47
Mage.Sets/src/mage/cards/b/BelligerentRegisaur.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class BelligerentRegisaur extends CardImpl {
|
||||
|
||||
public BelligerentRegisaur(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.DINOSAUR);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(3);
|
||||
this.color.setGreen(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// Whenever you cast a spell, Belligerent Regisaur gains indestructible until end of turn.
|
||||
this.addAbility(new SpellCastControllerTriggeredAbility(new GainAbilitySourceEffect(
|
||||
IndestructibleAbility.getInstance(), Duration.EndOfTurn
|
||||
), false));
|
||||
}
|
||||
|
||||
private BelligerentRegisaur(final BelligerentRegisaur card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BelligerentRegisaur copy() {
|
||||
return new BelligerentRegisaur(this);
|
||||
}
|
||||
}
|
53
Mage.Sets/src/mage/cards/b/BloomwielderDryads.java
Normal file
53
Mage.Sets/src/mage/cards/b/BloomwielderDryads.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||
import mage.abilities.keyword.WardAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.counters.CounterType;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class BloomwielderDryads extends CardImpl {
|
||||
|
||||
public BloomwielderDryads(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.DRYAD);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
this.color.setWhite(true);
|
||||
this.color.setGreen(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Ward {2}
|
||||
this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}")));
|
||||
|
||||
// At the beginning of your end step, put a +1/+1 counter on target creature you control.
|
||||
Ability ability = new BeginningOfEndStepTriggeredAbility(
|
||||
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), TargetController.YOU, false
|
||||
);
|
||||
ability.addTarget(new TargetControlledCreaturePermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private BloomwielderDryads(final BloomwielderDryads card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BloomwielderDryads copy() {
|
||||
return new BloomwielderDryads(this);
|
||||
}
|
||||
}
|
|
@ -12,15 +12,15 @@ import mage.constants.CardType;
|
|||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.predicate.other.AnotherTargetPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -32,12 +32,12 @@ public final class BondOfPassion extends CardImpl {
|
|||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterCreaturePermanent();
|
||||
private static final FilterCreaturePlayerOrPlaneswalker otherFilter
|
||||
= new FilterCreaturePlayerOrPlaneswalker("any other target");
|
||||
private static final FilterAnyTarget otherFilter
|
||||
= new FilterAnyTarget("any other target");
|
||||
|
||||
static {
|
||||
otherFilter.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
otherFilter.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
otherFilter.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
}
|
||||
|
||||
public BondOfPassion(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
@ -48,7 +48,7 @@ public final class BondOfPassion extends CardImpl {
|
|||
Target target = new TargetPermanent(filter);
|
||||
target.setTargetTag(1);
|
||||
this.getSpellAbility().addTarget(target);
|
||||
target = new TargetAnyTarget(otherFilter);
|
||||
target = new TargetPermanentOrPlayer(otherFilter);
|
||||
target.setTargetTag(2);
|
||||
this.getSpellAbility().addTarget(target);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
|
@ -11,34 +9,36 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.other.AnotherTargetPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sprangg
|
||||
*/
|
||||
public final class CaptainsManeuver extends CardImpl {
|
||||
|
||||
private static final FilterPermanentOrPlayer filter
|
||||
= new FilterCreaturePlayerOrPlaneswalker("creature, planeswalker or player (damage is redirected from)");
|
||||
private static final FilterPermanentOrPlayer filter2
|
||||
= new FilterCreaturePlayerOrPlaneswalker("another creature, planeswalker or player (damage is redirected to)");
|
||||
|
||||
static {
|
||||
filter2.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
filter2.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
}
|
||||
|
||||
public CaptainsManeuver(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{W}");
|
||||
|
||||
//The next X damage that would be dealt to target creature, planeswalker, or player this turn is dealt to another target creature, planeswalker, or player instead.
|
||||
this.getSpellAbility().addEffect(new CaptainsManeuverEffect());
|
||||
|
||||
FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker("creature, planeswalker or player (damage is redirected from)");
|
||||
TargetAnyTarget target = new TargetAnyTarget(filter);
|
||||
target.setTargetTag(1);
|
||||
this.getSpellAbility().addTarget(target);
|
||||
|
||||
FilterCreaturePlayerOrPlaneswalker filter2 = new FilterCreaturePlayerOrPlaneswalker("another creature, planeswalker or player (damage is redirected to)");
|
||||
filter2.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
filter2.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
TargetAnyTarget target2 = new TargetAnyTarget(filter2);
|
||||
target2.setTargetTag(2);
|
||||
this.getSpellAbility().addTarget(target2);
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter).setTargetTag(1));
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter2).setTargetTag(2));
|
||||
}
|
||||
|
||||
private CaptainsManeuver(final CaptainsManeuver card) {
|
||||
|
|
|
@ -15,8 +15,10 @@ import mage.constants.CardType;
|
|||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -26,8 +28,18 @@ import java.util.UUID;
|
|||
public final class CauterySliver extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent(SubType.SLIVER, "All Slivers");
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filter2
|
||||
= new FilterCreaturePlayerOrPlaneswalker("player, planeswalker, or Sliver creature", SubType.SLIVER);
|
||||
private static final FilterPermanentOrPlayer filter2
|
||||
= new FilterPermanentOrPlayer("player, planeswalker, or Sliver creature");
|
||||
|
||||
static {
|
||||
filter2.getPermanentFilter().add(Predicates.or(
|
||||
CardType.PLANESWALKER.getPredicate(),
|
||||
Predicates.and(
|
||||
CardType.CREATURE.getPredicate(),
|
||||
SubType.SLIVER.getPredicate()
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
public CauterySliver(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}");
|
||||
|
@ -51,7 +63,7 @@ public final class CauterySliver extends CardImpl {
|
|||
new PreventDamageToTargetEffect(Duration.EndOfTurn, 1), new GenericManaCost(1)
|
||||
);
|
||||
ability.addCost(new SacrificeSourceCost());
|
||||
ability.addTarget(new TargetAnyTarget(filter2));
|
||||
ability.addTarget(new TargetPermanentOrPlayer(filter2));
|
||||
this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect(
|
||||
ability, Duration.WhileOnBattlefield, filter, "All Slivers have " +
|
||||
"\"{1}, Sacrifice this permanent: Prevent the next 1 damage " +
|
||||
|
|
|
@ -8,9 +8,13 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
|||
import mage.abilities.dynamicvalue.common.GetXLoyaltyValue;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.*;
|
||||
import mage.abilities.effects.common.CopyTargetSpellEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
|
||||
import mage.cards.*;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
|
@ -29,7 +33,7 @@ public class ChandraHopesBeacon extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{R}{R}");
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.addSubType(SubType.CHANDRA);
|
||||
this.startingLoyalty = 5;
|
||||
this.setStartingLoyalty(5);
|
||||
|
||||
//Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy. This ability
|
||||
//triggers only once each turn.
|
||||
|
|
|
@ -6,13 +6,14 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.other.AnotherTargetPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -21,30 +22,24 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class ConeOfFlame extends CardImpl {
|
||||
|
||||
private static final FilterPermanentOrPlayer filter1 = new FilterAnyTarget("any target to deal 1 damage");
|
||||
private static final FilterPermanentOrPlayer filter2 = new FilterAnyTarget("another target to deal 2 damage");
|
||||
private static final FilterPermanentOrPlayer filter3 = new FilterAnyTarget("third target to deal 3 damage");
|
||||
|
||||
static {
|
||||
filter2.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
filter2.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
filter3.getPermanentFilter().add(new AnotherTargetPredicate(3));
|
||||
filter3.getPlayerFilter().add(new AnotherTargetPredicate(3));
|
||||
}
|
||||
|
||||
public ConeOfFlame(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}");
|
||||
|
||||
// Cone of Flame deals 1 damage to any target, 2 damage to another target, and 3 damage to a third target.
|
||||
// 1
|
||||
FilterCreaturePlayerOrPlaneswalker filter1 = new FilterCreaturePlayerOrPlaneswalker("any target to deal 1 damage");
|
||||
TargetAnyTarget target1 = new TargetAnyTarget(1, 1, filter1);
|
||||
target1.setTargetTag(1);
|
||||
this.getSpellAbility().addTarget(target1);
|
||||
// 2
|
||||
FilterCreaturePlayerOrPlaneswalker filter2 = new FilterCreaturePlayerOrPlaneswalker("another target to deal 2 damage");
|
||||
filter2.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
filter2.getPlayerFilter().add(new AnotherTargetPredicate(2));
|
||||
TargetAnyTarget target2 = new TargetAnyTarget(1, 1, filter2);
|
||||
target2.setTargetTag(2);
|
||||
this.getSpellAbility().addTarget(target2);
|
||||
// 3
|
||||
FilterCreaturePlayerOrPlaneswalker filter3 = new FilterCreaturePlayerOrPlaneswalker("third target to deal 3 damage");
|
||||
filter3.getPermanentFilter().add(new AnotherTargetPredicate(3));
|
||||
filter3.getPlayerFilter().add(new AnotherTargetPredicate(3));
|
||||
TargetAnyTarget target3 = new TargetAnyTarget(1, 1, filter3);
|
||||
target3.setTargetTag(3);
|
||||
this.getSpellAbility().addTarget(target3);
|
||||
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter1).setTargetTag(1));
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter2).setTargetTag(2));
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter3).setTargetTag(3));
|
||||
this.getSpellAbility().addEffect(new ConeOfFlameEffect());
|
||||
}
|
||||
|
||||
|
|
82
Mage.Sets/src/mage/cards/d/DelugeOfTheDead.java
Normal file
82
Mage.Sets/src/mage/cards/d/DelugeOfTheDead.java
Normal file
|
@ -0,0 +1,82 @@
|
|||
package mage.cards.d;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.token.ZombieToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class DelugeOfTheDead extends CardImpl {
|
||||
|
||||
public DelugeOfTheDead(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "");
|
||||
|
||||
this.color.setBlack(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// When Deluge of the Dead enters the battlefield, create two 2/2 black Zombie creature tokens.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ZombieToken(), 2)));
|
||||
|
||||
// {2}{B}: Exile target card from a graveyard. If it was a creature card, create a 2/2 black Zombie creature token.
|
||||
Ability ability = new SimpleActivatedAbility(new DelugeOfTheDeadEffect(), new ManaCostsImpl<>("{2}{B}"));
|
||||
ability.addTarget(new TargetCardInGraveyard());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private DelugeOfTheDead(final DelugeOfTheDead card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelugeOfTheDead copy() {
|
||||
return new DelugeOfTheDead(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DelugeOfTheDeadEffect extends OneShotEffect {
|
||||
|
||||
DelugeOfTheDeadEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "exile target card from a graveyard. " +
|
||||
"If it was a creature card, create a 2/2 black Zombie creature token";
|
||||
}
|
||||
|
||||
private DelugeOfTheDeadEffect(final DelugeOfTheDeadEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelugeOfTheDeadEffect copy() {
|
||||
return new DelugeOfTheDeadEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (player == null || card == null) {
|
||||
return false;
|
||||
}
|
||||
player.moveCards(card, Zone.EXILED, source, game);
|
||||
if (card.isCreature(game)) {
|
||||
new ZombieToken().putOntoBattlefield(1, game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -11,13 +11,14 @@ import mage.constants.CardType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.other.AnotherTargetPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -25,6 +26,12 @@ import java.util.UUID;
|
|||
* @author TheElk801
|
||||
*/
|
||||
public final class DrakusethMawOfFlames extends CardImpl {
|
||||
private static final FilterPermanentOrPlayer filter = new FilterAnyTarget("any target");
|
||||
|
||||
static {
|
||||
filter.getPlayerFilter().add(new AnotherTargetPredicate(2, true));
|
||||
filter.getPermanentFilter().add(new AnotherTargetPredicate(2, true));
|
||||
}
|
||||
|
||||
public DrakusethMawOfFlames(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}{R}");
|
||||
|
@ -39,15 +46,10 @@ public final class DrakusethMawOfFlames extends CardImpl {
|
|||
|
||||
// Whenever Drakuseth, Maw of Flames attacks, it deals 4 damage to any target and 3 damage to each of up to two other targets.
|
||||
Ability ability = new AttacksTriggeredAbility(new DrakusethMawOfFlamesEffect(), false);
|
||||
Target target = new TargetAnyTarget().withChooseHint("to deal 4 damage");
|
||||
target.setTargetTag(1);
|
||||
ability.addTarget(target);
|
||||
FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker("any target");
|
||||
filter.getPlayerFilter().add(new AnotherTargetPredicate(2, true));
|
||||
filter.getPermanentFilter().add(new AnotherTargetPredicate(2, true));
|
||||
target = new TargetAnyTarget(0, 2, filter).withChooseHint("to deal 3 damage");
|
||||
target.setTargetTag(2);
|
||||
ability.addTarget(target);
|
||||
ability.addTarget(new TargetAnyTarget().withChooseHint("to deal 4 damage").setTargetTag(1));
|
||||
ability.addTarget(new TargetPermanentOrPlayer(
|
||||
0, 2, filter, false
|
||||
).withChooseHint("to deal 3 damage").setTargetTag(2));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -15,11 +15,11 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class Endure extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker("you and permanents you control");
|
||||
private static final FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer("you and permanents you control");
|
||||
|
||||
static {
|
||||
filter.getPermanentFilter().add(TargetController.YOU.getControllerPredicate());
|
||||
filter.getPlayerFilter().add(TargetController.YOU.getPlayerPredicate());
|
||||
filter.getPermanentFilter().add(TargetController.YOU.getControllerPredicate());
|
||||
}
|
||||
|
||||
public Endure(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
@ -27,7 +27,6 @@ public final class Endure extends CardImpl {
|
|||
|
||||
// Prevent all damage that would be dealt to you and permanents you control this turn.
|
||||
this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, filter));
|
||||
|
||||
}
|
||||
|
||||
private Endure(final Endure card) {
|
||||
|
@ -38,4 +37,4 @@ public final class Endure extends CardImpl {
|
|||
public Endure copy() {
|
||||
return new Endure(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
81
Mage.Sets/src/mage/cards/e/EpharaEverSheltering.java
Normal file
81
Mage.Sets/src/mage/cards/e/EpharaEverSheltering.java
Normal file
|
@ -0,0 +1,81 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.abilities.hint.ValueHint;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledEnchantmentPermanent;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class EpharaEverSheltering extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledEnchantmentPermanent("another enchantment");
|
||||
|
||||
static {
|
||||
filter.add(AnotherPredicate.instance);
|
||||
}
|
||||
|
||||
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
|
||||
filter, ComparisonType.MORE_THAN, 2, true
|
||||
);
|
||||
private static final Hint hint = new ValueHint(
|
||||
"Other enchantments you control", new PermanentsOnBattlefieldCount(filter)
|
||||
);
|
||||
|
||||
public EpharaEverSheltering(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.GOD);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
this.color.setWhite(true);
|
||||
this.color.setBlue(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Ephara, Ever-Sheltering has lifelink and indestructible as long as you control at least three other enchantments.
|
||||
Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect(
|
||||
new GainAbilitySourceEffect(LifelinkAbility.getInstance()),
|
||||
condition, "{this} has lifelink"
|
||||
));
|
||||
ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(
|
||||
IndestructibleAbility.getInstance()), condition,
|
||||
"and indestructible as long as you control at least three other enchantments"
|
||||
));
|
||||
this.addAbility(ability.addHint(hint));
|
||||
|
||||
// Whenever another enchantment enters the battlefield under your control, draw a card.
|
||||
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new DrawCardSourceControllerEffect(1), filter));
|
||||
}
|
||||
|
||||
private EpharaEverSheltering(final EpharaEverSheltering card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EpharaEverSheltering copy() {
|
||||
return new EpharaEverSheltering(this);
|
||||
}
|
||||
}
|
|
@ -8,10 +8,12 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ManaType;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.other.AnotherTargetPredicate;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
import mage.target.targetpointer.SecondTargetPointer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -21,7 +23,7 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class ExplosiveWelcome extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker();
|
||||
private static final FilterPermanentOrPlayer filter = new FilterAnyTarget();
|
||||
|
||||
static {
|
||||
filter.getPermanentFilter().add(new AnotherTargetPredicate(2));
|
||||
|
@ -42,7 +44,7 @@ public final class ExplosiveWelcome extends CardImpl {
|
|||
Target target = new TargetAnyTarget();
|
||||
target.setTargetTag(1);
|
||||
this.getSpellAbility().addTarget(target);
|
||||
target = new TargetAnyTarget(filter);
|
||||
target = new TargetPermanentOrPlayer(filter);
|
||||
target.setTargetTag(2);
|
||||
this.getSpellAbility().addTarget(target);
|
||||
}
|
||||
|
|
|
@ -1,41 +1,44 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.InvertCondition;
|
||||
import mage.abilities.condition.common.SourceAttackingCondition;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect;
|
||||
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
|
||||
import mage.target.common.TargetLandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author anonymous
|
||||
*/
|
||||
public final class GaeasLiege extends CardImpl {
|
||||
|
||||
static final FilterControlledPermanent filterLands = new FilterControlledPermanent("Forests you control");
|
||||
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.FOREST);
|
||||
private static final FilterPermanent filter2 = new FilterPermanent(SubType.FOREST, "");
|
||||
|
||||
static {
|
||||
filterLands.add(SubType.FOREST.getPredicate());
|
||||
filter2.add(DefendingPlayerControlsPredicate.instance);
|
||||
}
|
||||
|
||||
private static final DynamicValue xValue1 = new PermanentsOnBattlefieldCount(filter);
|
||||
private static final DynamicValue xValue2 = new PermanentsOnBattlefieldCount(filter2);
|
||||
|
||||
public GaeasLiege(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}{G}");
|
||||
|
||||
|
@ -45,12 +48,18 @@ public final class GaeasLiege extends CardImpl {
|
|||
|
||||
// As long as Gaea's Liege isn't attacking, its power and toughness are each equal to the number of Forests you control. As long as Gaea's Liege is attacking, its power and toughness are each equal to the number of Forests defending player controls.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new ConditionalContinuousEffect(
|
||||
new SetBasePowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(filterLands), Duration.EndOfGame, SubLayer.SetPT_7b),
|
||||
new SetBasePowerToughnessSourceEffect(new DefendersForestCount(), Duration.EndOfCombat, SubLayer.SetPT_7b),
|
||||
new InvertCondition(SourceAttackingCondition.instance),
|
||||
"As long as {this} isn't attacking, its power and toughness are each equal to the number of Forests you control. As long as {this} is attacking, its power and toughness are each equal to the number of Forests defending player controls.")));
|
||||
new SetBasePowerToughnessSourceEffect(xValue2, Duration.EndOfGame),
|
||||
new SetBasePowerToughnessSourceEffect(xValue1, Duration.EndOfGame),
|
||||
SourceAttackingCondition.instance, "as long as {this} isn't attacking, " +
|
||||
"its power and toughness are each equal to the number of Forests you control. " +
|
||||
"As long as {this} is attacking, its power and toughness are each equal " +
|
||||
"to the number of Forests defending player controls"
|
||||
)));
|
||||
|
||||
// {T}: Target land becomes a Forest until Gaea's Liege leaves the battlefield.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesBasicLandTargetEffect(Duration.UntilSourceLeavesBattlefield, SubType.FOREST), new TapSourceCost());
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new BecomesBasicLandTargetEffect(Duration.UntilSourceLeavesBattlefield, SubType.FOREST), new TapSourceCost()
|
||||
);
|
||||
ability.addTarget(new TargetLandPermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
@ -64,42 +73,3 @@ public final class GaeasLiege extends CardImpl {
|
|||
return new GaeasLiege(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DefendersForestCount implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
for (CombatGroup group : game.getCombat().getGroups()) {
|
||||
if (group.getAttackers().contains(sourceAbility.getSourceId())) {
|
||||
UUID defenderId = group.getDefenderId();
|
||||
if (group.isDefenderIsPlaneswalker()) {
|
||||
Permanent permanent = game.getPermanent(defenderId);
|
||||
if (permanent != null) {
|
||||
defenderId = permanent.getControllerId();
|
||||
}
|
||||
}
|
||||
|
||||
FilterLandPermanent filter = new FilterLandPermanent("forest");
|
||||
filter.add(SubType.FOREST.getPredicate());
|
||||
return game.getBattlefield().countAll(filter, defenderId, game);
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
return new DefendersForestCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "the number of Forests defending player controls";
|
||||
}
|
||||
}
|
||||
|
|
66
Mage.Sets/src/mage/cards/g/GargantuanSlabhorn.java
Normal file
66
Mage.Sets/src/mage/cards/g/GargantuanSlabhorn.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.abilities.keyword.WardAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.permanent.TransformedPredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class GargantuanSlabhorn extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("transformed permanents");
|
||||
|
||||
static {
|
||||
filter.add(TransformedPredicate.instance);
|
||||
}
|
||||
|
||||
public GargantuanSlabhorn(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.BEAST);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
this.color.setBlue(true);
|
||||
this.color.setGreen(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// Ward {2}
|
||||
this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false));
|
||||
|
||||
// Other transformed permanents you control have trample and ward {2}.
|
||||
Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect(
|
||||
TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter, true
|
||||
));
|
||||
ability.addEffect(new GainAbilityControlledEffect(
|
||||
new WardAbility(new GenericManaCost(2)), Duration.WhileOnBattlefield, filter, true
|
||||
).setText("and ward {2}"));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private GargantuanSlabhorn(final GargantuanSlabhorn card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GargantuanSlabhorn copy() {
|
||||
return new GargantuanSlabhorn(this);
|
||||
}
|
||||
}
|
55
Mage.Sets/src/mage/cards/g/GrandmotherRaviSengir.java
Normal file
55
Mage.Sets/src/mage/cards/g/GrandmotherRaviSengir.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class GrandmotherRaviSengir extends CardImpl {
|
||||
|
||||
public GrandmotherRaviSengir(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.WIZARD);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
this.color.setBlack(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Whenever a creature an opponent controls dies, put a +1/+1 counter on Grandmother Ravi Sengir and you gain 1 life.
|
||||
Ability ability = new DiesCreatureTriggeredAbility(
|
||||
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
|
||||
false, StaticFilters.FILTER_OPPONENTS_PERMANENT_A_CREATURE
|
||||
);
|
||||
ability.addEffect(new GainLifeEffect(1).concatBy("and"));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private GrandmotherRaviSengir(final GrandmotherRaviSengir card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrandmotherRaviSengir copy() {
|
||||
return new GrandmotherRaviSengir(this);
|
||||
}
|
||||
}
|
63
Mage.Sets/src/mage/cards/g/GuildpactParagon.java
Normal file
63
Mage.Sets/src/mage/cards/g/GuildpactParagon.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PutCards;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class GuildpactParagon extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("a spell that's exactly two colors");
|
||||
private static final FilterCard filter2 = new FilterCard("a card that's exactly two colors");
|
||||
|
||||
static {
|
||||
filter.add(GuildpactParagonPredicate.instance);
|
||||
filter2.add(GuildpactParagonPredicate.instance);
|
||||
}
|
||||
|
||||
public GuildpactParagon(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.CONSTRUCT);
|
||||
this.power = new MageInt(5);
|
||||
this.toughness = new MageInt(5);
|
||||
this.nightCard = true;
|
||||
|
||||
// Whenever you cast a spell that's exactly two colors, look at the top six cards of your library. You may reveal a card that's exactly two colors 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 SpellCastControllerTriggeredAbility(new LookLibraryAndPickControllerEffect(
|
||||
6, 1, filter2, PutCards.HAND, PutCards.BOTTOM_RANDOM
|
||||
), filter, false));
|
||||
}
|
||||
|
||||
private GuildpactParagon(final GuildpactParagon card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuildpactParagon copy() {
|
||||
return new GuildpactParagon(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum GuildpactParagonPredicate implements Predicate<MageObject> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(MageObject input, Game game) {
|
||||
return input.getColor(game).getColorCount() == 2;
|
||||
}
|
||||
}
|
|
@ -11,8 +11,9 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -21,8 +22,18 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class ImperialGunner extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker(
|
||||
"target player, planeswalker or Starship creature", SubType.STARSHIP);
|
||||
private static final FilterPermanentOrPlayer filter
|
||||
= new FilterPermanentOrPlayer("player, planeswalker, or Starship creature");
|
||||
|
||||
static {
|
||||
filter.getPermanentFilter().add(Predicates.or(
|
||||
CardType.PLANESWALKER.getPredicate(),
|
||||
Predicates.and(
|
||||
CardType.CREATURE.getPredicate(),
|
||||
SubType.STARSHIP.getPredicate()
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
public ImperialGunner(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
|
||||
|
@ -33,7 +44,7 @@ public final class ImperialGunner extends CardImpl {
|
|||
|
||||
// {1},{T}: Imperial Gunner deals 1 damage to target player or Starship creature.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl<>("{1}"));
|
||||
ability.addTarget(new TargetAnyTarget(filter));
|
||||
ability.addTarget(new TargetPermanentOrPlayer(filter));
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
103
Mage.Sets/src/mage/cards/i/InvasionOfAlara.java
Normal file
103
Mage.Sets/src/mage/cards/i/InvasionOfAlara.java
Normal file
|
@ -0,0 +1,103 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInExile;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfAlara extends CardImpl {
|
||||
|
||||
public InvasionOfAlara(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{W}{U}{B}{R}{G}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(7);
|
||||
this.secondSideCardClazz = mage.cards.a.AwakenTheMaelstrom.class;
|
||||
|
||||
Ability ability = new SiegeAbility();
|
||||
ability.setRuleVisible(false);
|
||||
this.addAbility(ability);
|
||||
|
||||
// When Invasion of Alara enters the battlefield, exile cards from the top of your library until you exile two nonland cards with mana value 4 or less. You may cast one of those two cards without paying its mana cost. Put one of them into your hand. Then put the other cards exiled this way on the bottom of your library in a random order.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfAlaraEffect()));
|
||||
}
|
||||
|
||||
private InvasionOfAlara(final InvasionOfAlara card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfAlara copy() {
|
||||
return new InvasionOfAlara(this);
|
||||
}
|
||||
}
|
||||
|
||||
class InvasionOfAlaraEffect extends OneShotEffect {
|
||||
|
||||
InvasionOfAlaraEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "exile cards from the top of your library until you exile two nonland cards " +
|
||||
"with mana value 4 or less. You may cast one of those two cards without paying its mana cost. " +
|
||||
"Put one of them into your hand. Then put the other cards exiled this way on the bottom of your library in a random order";
|
||||
}
|
||||
|
||||
private InvasionOfAlaraEffect(final InvasionOfAlaraEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfAlaraEffect copy() {
|
||||
return new InvasionOfAlaraEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl();
|
||||
Cards castable = new CardsImpl();
|
||||
int count = 0;
|
||||
for (Card card : player.getLibrary().getCards(game)) {
|
||||
player.moveCards(card, Zone.EXILED, source, game);
|
||||
cards.add(card);
|
||||
if (!card.isLand(game) && card.getManaValue() <= 4) {
|
||||
castable.add(card);
|
||||
count++;
|
||||
}
|
||||
if (count >= 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
CardUtil.castSpellWithAttributesForFree(player, source, game, castable, StaticFilters.FILTER_CARD);
|
||||
castable.retainZone(Zone.EXILED, game);
|
||||
if (castable.size() > 1) {
|
||||
TargetCard target = new TargetCardInExile(StaticFilters.FILTER_CARD);
|
||||
target.setNotTarget(true);
|
||||
player.choose(outcome, castable, target, game);
|
||||
player.moveCards(game.getCard(target.getFirstTarget()), Zone.HAND, source, game);
|
||||
} else {
|
||||
player.moveCards(castable, Zone.HAND, source, game);
|
||||
}
|
||||
cards.retainZone(Zone.EXILED, game);
|
||||
player.putCardsOnBottomOfLibrary(cards, game, source, false);
|
||||
return true;
|
||||
}
|
||||
}
|
49
Mage.Sets/src/mage/cards/i/InvasionOfAmonkhet.java
Normal file
49
Mage.Sets/src/mage/cards/i/InvasionOfAmonkhet.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.MillCardsEachPlayerEffect;
|
||||
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfAmonkhet extends CardImpl {
|
||||
|
||||
public InvasionOfAmonkhet(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{U}{B}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.l.LazotepConvert.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Amonkhet enters the battlefield, each player mills three cards, then each opponent discards a card and you draw a card.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(
|
||||
new MillCardsEachPlayerEffect(3, TargetController.EACH_PLAYER)
|
||||
);
|
||||
ability.addEffect(new DiscardEachPlayerEffect(TargetController.OPPONENT).concatBy(", then"));
|
||||
ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and you"));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfAmonkhet(final InvasionOfAmonkhet card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfAmonkhet copy() {
|
||||
return new InvasionOfAmonkhet(this);
|
||||
}
|
||||
}
|
41
Mage.Sets/src/mage/cards/i/InvasionOfBelenon.java
Normal file
41
Mage.Sets/src/mage/cards/i/InvasionOfBelenon.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.permanent.token.KnightWhiteBlueToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfBelenon extends CardImpl {
|
||||
|
||||
public InvasionOfBelenon(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{W}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.b.BelenonWarAnthem.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Belenon enters the battlefield, create a 2/2 white and blue Knight creature token with vigilance.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new KnightWhiteBlueToken())));
|
||||
}
|
||||
|
||||
private InvasionOfBelenon(final InvasionOfBelenon card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfBelenon copy() {
|
||||
return new InvasionOfBelenon(this);
|
||||
}
|
||||
}
|
44
Mage.Sets/src/mage/cards/i/InvasionOfDominaria.java
Normal file
44
Mage.Sets/src/mage/cards/i/InvasionOfDominaria.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfDominaria extends CardImpl {
|
||||
|
||||
public InvasionOfDominaria(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{W}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.s.SerraFaithkeeper.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Dominaria enters the battlefield, you gain 4 life and draw a card.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new GainLifeEffect(4));
|
||||
ability.addEffect(new DrawCardSourceControllerEffect(1));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfDominaria(final InvasionOfDominaria card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfDominaria copy() {
|
||||
return new InvasionOfDominaria(this);
|
||||
}
|
||||
}
|
44
Mage.Sets/src/mage/cards/i/InvasionOfEldraine.java
Normal file
44
Mage.Sets/src/mage/cards/i/InvasionOfEldraine.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfEldraine extends CardImpl {
|
||||
|
||||
public InvasionOfEldraine(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{B}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.p.PrickleFaeries.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Eldraine enters the battlefield, target opponent discards two cards.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(2));
|
||||
ability.addTarget(new TargetOpponent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfEldraine(final InvasionOfEldraine card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfEldraine copy() {
|
||||
return new InvasionOfEldraine(this);
|
||||
}
|
||||
}
|
47
Mage.Sets/src/mage/cards/i/InvasionOfErgamon.java
Normal file
47
Mage.Sets/src/mage/cards/i/InvasionOfErgamon.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.permanent.token.TreasureToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfErgamon extends CardImpl {
|
||||
|
||||
public InvasionOfErgamon(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{R}{G}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.t.TrugaCliffcharger.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Ergamon enters the battlefield, create a Treasure token. Then you may discard a card. If you do, draw a card.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken()));
|
||||
ability.addEffect(new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost()));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfErgamon(final InvasionOfErgamon card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfErgamon copy() {
|
||||
return new InvasionOfErgamon(this);
|
||||
}
|
||||
}
|
48
Mage.Sets/src/mage/cards/i/InvasionOfInnistrad.java
Normal file
48
Mage.Sets/src/mage/cards/i/InvasionOfInnistrad.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.target.common.TargetOpponentsCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfInnistrad extends CardImpl {
|
||||
|
||||
public InvasionOfInnistrad(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{B}{B}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.d.DelugeOfTheDead.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// Flash
|
||||
this.addAbility(FlashAbility.getInstance());
|
||||
|
||||
// When Invasion of Innistrad enters the battlefield, target creature an opponent controls gets -13/-13 until end of turn.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(-13, -13));
|
||||
ability.addTarget(new TargetOpponentsCreaturePermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfInnistrad(final InvasionOfInnistrad card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfInnistrad copy() {
|
||||
return new InvasionOfInnistrad(this);
|
||||
}
|
||||
}
|
45
Mage.Sets/src/mage/cards/i/InvasionOfIxalan.java
Normal file
45
Mage.Sets/src/mage/cards/i/InvasionOfIxalan.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PutCards;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfIxalan extends CardImpl {
|
||||
|
||||
public InvasionOfIxalan(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{G}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.b.BelligerentRegisaur.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Ixalan enters the battlefield, look at the top five cards of your library. You may reveal a permanent card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
|
||||
5, 1, StaticFilters.FILTER_CARD_A_PERMANENT,
|
||||
PutCards.HAND, PutCards.BOTTOM_RANDOM
|
||||
)));
|
||||
}
|
||||
|
||||
private InvasionOfIxalan(final InvasionOfIxalan card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfIxalan copy() {
|
||||
return new InvasionOfIxalan(this);
|
||||
}
|
||||
}
|
41
Mage.Sets/src/mage/cards/i/InvasionOfKaladesh.java
Normal file
41
Mage.Sets/src/mage/cards/i/InvasionOfKaladesh.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.permanent.token.ThopterColorlessToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfKaladesh extends CardImpl {
|
||||
|
||||
public InvasionOfKaladesh(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{U}{R}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.a.AetherwingGoldenScaleFlagship.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Kaladesh enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ThopterColorlessToken())));
|
||||
}
|
||||
|
||||
private InvasionOfKaladesh(final InvasionOfKaladesh card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfKaladesh copy() {
|
||||
return new InvasionOfKaladesh(this);
|
||||
}
|
||||
}
|
75
Mage.Sets/src/mage/cards/i/InvasionOfKaldheim.java
Normal file
75
Mage.Sets/src/mage/cards/i/InvasionOfKaldheim.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfKaldheim extends CardImpl {
|
||||
|
||||
public InvasionOfKaldheim(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{R}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.p.PyreOfTheWorldTree.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Kaldheim enters the battlefield, exile all cards from your hand, then draw that many cards. Until the end of your next turn, you may play cards exiled this way.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfKaldheimEffect()));
|
||||
}
|
||||
|
||||
private InvasionOfKaldheim(final InvasionOfKaldheim card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfKaldheim copy() {
|
||||
return new InvasionOfKaldheim(this);
|
||||
}
|
||||
}
|
||||
|
||||
class InvasionOfKaldheimEffect extends OneShotEffect {
|
||||
|
||||
InvasionOfKaldheimEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "exile all cards from your hand, then draw that many cards. " +
|
||||
"Until the end of your next turn, you may play cards exiled this way";
|
||||
}
|
||||
|
||||
private InvasionOfKaldheimEffect(final InvasionOfKaldheimEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfKaldheimEffect copy() {
|
||||
return new InvasionOfKaldheimEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null || player.getHand().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(player.getHand());
|
||||
player.moveCards(cards, Zone.EXILED, source, game);
|
||||
player.drawCards(cards.size(), source, game);
|
||||
for (Card card : cards.getCards(game)) {
|
||||
CardUtil.makeCardPlayable(game, source, card, Duration.UntilEndOfYourNextTurn, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
48
Mage.Sets/src/mage/cards/i/InvasionOfKamigawa.java
Normal file
48
Mage.Sets/src/mage/cards/i/InvasionOfKamigawa.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.TapTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfKamigawa extends CardImpl {
|
||||
|
||||
public InvasionOfKamigawa(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{U}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.r.RooftopSaboteurs.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Kamigawa enters the battlefield, tap target artifact or creature an opponent controls and put a stun counter on it.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect());
|
||||
ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance()).setText("and put a stun counter on it"));
|
||||
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfKamigawa(final InvasionOfKamigawa card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfKamigawa copy() {
|
||||
return new InvasionOfKamigawa(this);
|
||||
}
|
||||
}
|
47
Mage.Sets/src/mage/cards/i/InvasionOfKarsus.java
Normal file
47
Mage.Sets/src/mage/cards/i/InvasionOfKarsus.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.DamageAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfKarsus extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterCreatureOrPlaneswalkerPermanent("creature and each planeswalker");
|
||||
|
||||
public InvasionOfKarsus(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{R}{R}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.r.RefractionElemental.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Karsus enters the battlefield, it deals 3 damage to each creature and each planeswalker.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new DamageAllEffect(3, "it", filter)
|
||||
));
|
||||
}
|
||||
|
||||
private InvasionOfKarsus(final InvasionOfKarsus card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfKarsus copy() {
|
||||
return new InvasionOfKarsus(this);
|
||||
}
|
||||
}
|
74
Mage.Sets/src/mage/cards/i/InvasionOfLorwyn.java
Normal file
74
Mage.Sets/src/mage/cards/i/InvasionOfLorwyn.java
Normal file
|
@ -0,0 +1,74 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.hint.common.LandsYouControlHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterOpponentsCreaturePermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfLorwyn extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent(
|
||||
"non-Elf creature an opponent controls with power X or less, where X is the number of lands you control"
|
||||
);
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(SubType.ELF.getPredicate()));
|
||||
filter.add(InvasionOfLorwynPredicate.instance);
|
||||
}
|
||||
|
||||
public InvasionOfLorwyn(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{4}{B}{G}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.w.WinnowingForces.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Lorwyn enters the battlefield, destroy target non-Elf creature an opponent controls with power X or less, where X is the number of lands you control.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect());
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability.addHint(LandsYouControlHint.instance));
|
||||
}
|
||||
|
||||
private InvasionOfLorwyn(final InvasionOfLorwyn card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfLorwyn copy() {
|
||||
return new InvasionOfLorwyn(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum InvasionOfLorwynPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
return input.getObject().getPower().getValue() <= game.getBattlefield().count(
|
||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||
input.getSource().getControllerId(), input.getSource(), game
|
||||
);
|
||||
}
|
||||
}
|
42
Mage.Sets/src/mage/cards/i/InvasionOfMercadia.java
Normal file
42
Mage.Sets/src/mage/cards/i/InvasionOfMercadia.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfMercadia extends CardImpl {
|
||||
|
||||
public InvasionOfMercadia(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{R}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.k.KyrenFlamewright.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Mercadia enters the battlefield, you may discard a card. If you do, draw two cards.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(new DrawCardSourceControllerEffect(2), new DiscardCardCost())));
|
||||
}
|
||||
|
||||
private InvasionOfMercadia(final InvasionOfMercadia card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfMercadia copy() {
|
||||
return new InvasionOfMercadia(this);
|
||||
}
|
||||
}
|
44
Mage.Sets/src/mage/cards/i/InvasionOfMoag.java
Normal file
44
Mage.Sets/src/mage/cards/i/InvasionOfMoag.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.counter.AddCountersAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfMoag extends CardImpl {
|
||||
|
||||
public InvasionOfMoag(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{G}{W}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.b.BloomwielderDryads.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Moag enters the battlefield, put a +1/+1 counter on each creature you control.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect(
|
||||
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
|
||||
)));
|
||||
}
|
||||
|
||||
private InvasionOfMoag(final InvasionOfMoag card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfMoag copy() {
|
||||
return new InvasionOfMoag(this);
|
||||
}
|
||||
}
|
75
Mage.Sets/src/mage/cards/i/InvasionOfPyrulea.java
Normal file
75
Mage.Sets/src/mage/cards/i/InvasionOfPyrulea.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfPyrulea extends CardImpl {
|
||||
|
||||
public InvasionOfPyrulea(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{G}{U}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.g.GargantuanSlabhorn.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Pyrulea enters the battlefield, scry 3, then reveal the top card of your library. If it's a land or double-faced card, draw a card.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfPyruleaEffect()));
|
||||
}
|
||||
|
||||
private InvasionOfPyrulea(final InvasionOfPyrulea card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfPyrulea copy() {
|
||||
return new InvasionOfPyrulea(this);
|
||||
}
|
||||
}
|
||||
|
||||
class InvasionOfPyruleaEffect extends OneShotEffect {
|
||||
|
||||
InvasionOfPyruleaEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "scry 3, then reveal the top card of your library. If it's a land or double-faced card, draw a card";
|
||||
}
|
||||
|
||||
private InvasionOfPyruleaEffect(final InvasionOfPyruleaEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfPyruleaEffect copy() {
|
||||
return new InvasionOfPyruleaEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
player.scry(3, source, game);
|
||||
Card card = player.getLibrary().getFromTop(game);
|
||||
player.revealCards(source, new CardsImpl(card), game);
|
||||
if (card != null && (card.isLand(game) || card instanceof ModalDoubleFacesCard || card.getSecondCardFace() != null)) {
|
||||
player.drawCards(1, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
66
Mage.Sets/src/mage/cards/i/InvasionOfRavnica.java
Normal file
66
Mage.Sets/src/mage/cards/i/InvasionOfRavnica.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterNonlandPermanent;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfRavnica extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterNonlandPermanent("nonland permanent an opponent controls that isn't exactly two colors");
|
||||
|
||||
static {
|
||||
filter.add(TargetController.OPPONENT.getControllerPredicate());
|
||||
filter.add(InvasionOfRavnicaPredicate.instance);
|
||||
}
|
||||
|
||||
public InvasionOfRavnica(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{5}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.g.GuildpactParagon.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Ravnica enters the battlefield, exile target nonland permanent an opponent controls that isn't exactly two colors.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect());
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfRavnica(final InvasionOfRavnica card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfRavnica copy() {
|
||||
return new InvasionOfRavnica(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum InvasionOfRavnicaPredicate implements Predicate<Permanent> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Permanent input, Game game) {
|
||||
return input.getColor(game).getColorCount() != 2;
|
||||
}
|
||||
}
|
45
Mage.Sets/src/mage/cards/i/InvasionOfShandalar.java
Normal file
45
Mage.Sets/src/mage/cards/i/InvasionOfShandalar.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfShandalar extends CardImpl {
|
||||
|
||||
public InvasionOfShandalar(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{G}{G}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.l.LeylineSurge.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Shandalar enters the battlefield, return up to three target permanent cards from your graveyard to your hand.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
|
||||
ability.addTarget(new TargetCardInYourGraveyard(0, 3, StaticFilters.FILTER_CARD_PERMANENTS));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfShandalar(final InvasionOfShandalar card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfShandalar copy() {
|
||||
return new InvasionOfShandalar(this);
|
||||
}
|
||||
}
|
55
Mage.Sets/src/mage/cards/i/InvasionOfTheros.java
Normal file
55
Mage.Sets/src/mage/cards/i/InvasionOfTheros.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfTheros extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("an Aura, God, or Demigod card");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
SubType.AURA.getPredicate(),
|
||||
SubType.GOD.getPredicate(),
|
||||
SubType.DEMIGOD.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
public InvasionOfTheros(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{W}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.e.EpharaEverSheltering.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Theros enters the battlefield, search your library for an Aura, God, or Demigod card, reveal it, put it into your hand, then shuffle.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true)
|
||||
));
|
||||
}
|
||||
|
||||
private InvasionOfTheros(final InvasionOfTheros card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfTheros copy() {
|
||||
return new InvasionOfTheros(this);
|
||||
}
|
||||
}
|
53
Mage.Sets/src/mage/cards/i/InvasionOfTolvada.java
Normal file
53
Mage.Sets/src/mage/cards/i/InvasionOfTolvada.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterPermanentCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfTolvada extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterPermanentCard("nonbattle permanent card from your graveyard");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(CardType.BATTLE.getPredicate()));
|
||||
}
|
||||
|
||||
public InvasionOfTolvada(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{W}{B}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.t.TheBrokenSky.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Tolvada enters the battlefield, return target nonbattle permanent card from your graveyard to the battlefield.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
|
||||
ability.addTarget(new TargetCardInYourGraveyard(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfTolvada(final InvasionOfTolvada card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfTolvada copy() {
|
||||
return new InvasionOfTolvada(this);
|
||||
}
|
||||
}
|
55
Mage.Sets/src/mage/cards/i/InvasionOfUlgrotha.java
Normal file
55
Mage.Sets/src/mage/cards/i/InvasionOfUlgrotha.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfUlgrotha extends CardImpl {
|
||||
|
||||
private static final FilterPermanentOrPlayer filter = new FilterAnyTarget("any other target");
|
||||
|
||||
static {
|
||||
filter.getPermanentFilter().add(AnotherPredicate.instance);
|
||||
}
|
||||
|
||||
public InvasionOfUlgrotha(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{4}{B}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.g.GrandmotherRaviSengir.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Ulgrotha enters the battlefield, it deals 3 damage to any other target and you gain 3 life.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(3));
|
||||
ability.addEffect(new GainLifeEffect(3).concatBy("and"));
|
||||
ability.addTarget(new TargetPermanentOrPlayer(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfUlgrotha(final InvasionOfUlgrotha card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfUlgrotha copy() {
|
||||
return new InvasionOfUlgrotha(this);
|
||||
}
|
||||
}
|
40
Mage.Sets/src/mage/cards/i/InvasionOfVryn.java
Normal file
40
Mage.Sets/src/mage/cards/i/InvasionOfVryn.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.DrawDiscardControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfVryn extends CardImpl {
|
||||
|
||||
public InvasionOfVryn(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{U}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.o.OverloadedMageRing.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Vryn enters the battlefield, draw three cards, then discard a card.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(3, 1)));
|
||||
}
|
||||
|
||||
private InvasionOfVryn(final InvasionOfVryn card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfVryn copy() {
|
||||
return new InvasionOfVryn(this);
|
||||
}
|
||||
}
|
44
Mage.Sets/src/mage/cards/i/InvasionOfXerex.java
Normal file
44
Mage.Sets/src/mage/cards/i/InvasionOfXerex.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfXerex extends CardImpl {
|
||||
|
||||
public InvasionOfXerex(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{W}{U}");
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(4);
|
||||
this.secondSideCardClazz = mage.cards.v.VertexPaladin.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Xerex enters the battlefield, return up to one target creature to its owner's hand.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect());
|
||||
ability.addTarget(new TargetCreaturePermanent(0, 1));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private InvasionOfXerex(final InvasionOfXerex card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvasionOfXerex copy() {
|
||||
return new InvasionOfXerex(this);
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import mage.constants.SubType;
|
|||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.common.FilterBattlePermanent;
|
||||
import mage.filter.predicate.mageobject.AbilityPredicate;
|
||||
import mage.filter.predicate.permanent.ProtectedByOpponentPredicate;
|
||||
import mage.game.permanent.token.Elemental11BlueRedToken;
|
||||
|
@ -27,11 +28,10 @@ import java.util.UUID;
|
|||
public final class JoyfulStormsculptor extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("a spell that has convoke");
|
||||
private static final FilterPermanent filter2 = new FilterPermanent();
|
||||
private static final FilterPermanent filter2 = new FilterBattlePermanent();
|
||||
|
||||
static {
|
||||
filter.add(new AbilityPredicate(ConvokeAbility.class));
|
||||
filter2.add(CardType.BATTLE.getPredicate());
|
||||
filter2.add(ProtectedByOpponentPredicate.instance);
|
||||
}
|
||||
|
||||
|
|
59
Mage.Sets/src/mage/cards/k/KyrenFlamewright.java
Normal file
59
Mage.Sets/src/mage/cards/k/KyrenFlamewright.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.permanent.token.Elemental11BlueRedToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class KyrenFlamewright extends CardImpl {
|
||||
|
||||
public KyrenFlamewright(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.GOBLIN);
|
||||
this.subtype.add(SubType.SPELLSHAPER);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
this.color.setRed(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// {2}{R}, {T}, Discard a card: Create two 1/1 blue and red Elemental creature tokens. Creatures you control get +1/+0 and gain haste until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new CreateTokenEffect(new Elemental11BlueRedToken(), 2), new ManaCostsImpl<>("{2}{R}")
|
||||
);
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new DiscardCardCost());
|
||||
ability.addEffect(new BoostControlledEffect(1, 0, Duration.EndOfTurn)
|
||||
.setText("creatures you control get +1/+0"));
|
||||
ability.addEffect(new GainAbilityControlledEffect(
|
||||
HasteAbility.getInstance(), Duration.EndOfTurn
|
||||
).setText("and gain haste until end of turn"));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private KyrenFlamewright(final KyrenFlamewright card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KyrenFlamewright copy() {
|
||||
return new KyrenFlamewright(this);
|
||||
}
|
||||
}
|
106
Mage.Sets/src/mage/cards/l/LazotepConvert.java
Normal file
106
Mage.Sets/src/mage/cards/l/LazotepConvert.java
Normal file
|
@ -0,0 +1,106 @@
|
|||
package mage.cards.l;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CopyEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.util.functions.CopyApplier;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class LazotepConvert extends CardImpl {
|
||||
|
||||
public LazotepConvert(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.ZOMBIE);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
this.color.setBlue(true);
|
||||
this.color.setBlack(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// You may have Lazotep Convert enter the battlefield as a copy of any creature card in a graveyard, except it's a 4/4 black Zombie in addition to its other types.
|
||||
this.addAbility(new EntersBattlefieldAbility(new LazotepConvertCopyEffect()));
|
||||
}
|
||||
|
||||
private LazotepConvert(final LazotepConvert card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazotepConvert copy() {
|
||||
return new LazotepConvert(this);
|
||||
}
|
||||
}
|
||||
|
||||
class LazotepConvertCopyEffect extends OneShotEffect {
|
||||
|
||||
private static final CopyApplier applier = new CopyApplier() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
|
||||
blueprint.removePTCDA();
|
||||
blueprint.getPower().setModifiedBaseValue(4);
|
||||
blueprint.getToughness().setModifiedBaseValue(4);
|
||||
blueprint.addSubType(SubType.ZOMBIE);
|
||||
blueprint.getColor().setColor(ObjectColor.BLACK);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private static final FilterCard filter = new FilterCreatureCard("creature card in a graveyard");
|
||||
|
||||
public LazotepConvertCopyEffect() {
|
||||
super(Outcome.Copy);
|
||||
this.staticText = "as a copy of any creature card in a graveyard, " +
|
||||
"except it's a 4/4 black Zombie in addition to its other types";
|
||||
}
|
||||
|
||||
public LazotepConvertCopyEffect(final LazotepConvertCopyEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Target target = new TargetCardInGraveyard(0, 1, filter);
|
||||
target.setNotTarget(true);
|
||||
player.choose(outcome, target, source, game);
|
||||
Card copyFromCard = game.getCard(target.getFirstTarget());
|
||||
if (copyFromCard == null) {
|
||||
return true;
|
||||
}
|
||||
game.addEffect(new CopyEffect(
|
||||
Duration.Custom, copyFromCard, source.getSourceId()
|
||||
).setApplier(applier), source);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazotepConvertCopyEffect copy() {
|
||||
return new LazotepConvertCopyEffect(this);
|
||||
}
|
||||
}
|
39
Mage.Sets/src/mage/cards/l/LeylineSurge.java
Normal file
39
Mage.Sets/src/mage/cards/l/LeylineSurge.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package mage.cards.l;
|
||||
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class LeylineSurge extends CardImpl {
|
||||
|
||||
public LeylineSurge(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "");
|
||||
|
||||
this.color.setGreen(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// At the beginning of your upkeep, you may put a permanent card from your hand onto the battlefield.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
|
||||
new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_PERMANENT),
|
||||
TargetController.YOU, false
|
||||
));
|
||||
}
|
||||
|
||||
private LeylineSurge(final LeylineSurge card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeylineSurge copy() {
|
||||
return new LeylineSurge(this);
|
||||
}
|
||||
}
|
|
@ -11,10 +11,10 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import java.util.UUID;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
|
@ -33,7 +33,7 @@ public final class LightningCoreExcavator extends CardImpl {
|
|||
);
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new SacrificeSourceCost());
|
||||
ability.addTarget(new TargetAnyTarget(new FilterCreaturePlayerOrPlaneswalker("any target")));
|
||||
ability.addTarget(new TargetAnyTarget());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,13 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CommanderPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
@ -29,8 +30,8 @@ import java.util.UUID;
|
|||
public final class LozhanDragonsLegacy extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("an Adventure spell or Dragon spell");
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filter2
|
||||
= new FilterCreaturePlayerOrPlaneswalker("any target that isn't a commander");
|
||||
private static final FilterPermanentOrPlayer filter2
|
||||
= new FilterAnyTarget("any target that isn't a commander");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
|
@ -57,7 +58,7 @@ public final class LozhanDragonsLegacy extends CardImpl {
|
|||
new DamageTargetEffect(LozhanDragonsLegacyValue.instance)
|
||||
.setText("{this} deals damage equal to that spell's mana value to any target that isn't a commander"), filter, false
|
||||
);
|
||||
ability.addTarget(new TargetAnyTarget(filter2));
|
||||
ability.addTarget(new TargetPermanentOrPlayer(filter2));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +1,34 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.continuous.BoostAllEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.common.FilterAttackingCreature;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class MercadiasDownfall extends CardImpl {
|
||||
|
||||
private static String rule = "Each attacking creature gets +1/+0 until end of turn for each nonbasic land defending player controls";
|
||||
|
||||
public MercadiasDownfall(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
|
||||
|
||||
// Each attacking creature gets +1/+0 until end of turn for each nonbasic land defending player controls.
|
||||
this.getSpellAbility().addEffect(new BoostAllEffect(new DefendersNonBasicLandCount(), StaticValue.get(0), Duration.EndOfTurn, new FilterAttackingCreature(), true, rule));
|
||||
|
||||
this.getSpellAbility().addEffect(new MercadiasDownfallEffect());
|
||||
}
|
||||
|
||||
private MercadiasDownfall(final MercadiasDownfall card) {
|
||||
|
@ -43,42 +39,42 @@ public final class MercadiasDownfall extends CardImpl {
|
|||
public MercadiasDownfall copy() {
|
||||
return new MercadiasDownfall(this);
|
||||
}
|
||||
}
|
||||
|
||||
static class DefendersNonBasicLandCount implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
UUID defenderId;
|
||||
for (CombatGroup group : game.getCombat().getGroups()) {
|
||||
defenderId = group.getDefenderId();
|
||||
if (group.isDefenderIsPlaneswalker()) {
|
||||
Permanent permanent = game.getPermanent(defenderId);
|
||||
if (permanent != null) {
|
||||
defenderId = permanent.getControllerId();
|
||||
}
|
||||
}
|
||||
FilterLandPermanent filter = new FilterLandPermanent("nonbasic land");
|
||||
filter.add(Predicates.not(SuperType.BASIC.getPredicate()));
|
||||
System.out.println("The number of nonbasic lands is " + game.getBattlefield().countAll(filter, defenderId, game));
|
||||
return game.getBattlefield().countAll(filter, defenderId, game);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
class MercadiasDownfallEffect extends OneShotEffect {
|
||||
|
||||
@Override
|
||||
public DefendersNonBasicLandCount copy() {
|
||||
return new DefendersNonBasicLandCount();
|
||||
}
|
||||
private static final FilterPermanent filter = new FilterLandPermanent();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "the number of nonbasic lands defending player controls";
|
||||
}
|
||||
static {
|
||||
filter.add(Predicates.not(SuperType.BASIC.getPredicate()));
|
||||
}
|
||||
|
||||
MercadiasDownfallEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "each attacking creature gets +1/+0 until end of turn for each nonbasic land defending player controls";
|
||||
}
|
||||
|
||||
private MercadiasDownfallEffect(final MercadiasDownfallEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MercadiasDownfallEffect copy() {
|
||||
return new MercadiasDownfallEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||
StaticFilters.FILTER_ATTACKING_CREATURE, source.getControllerId(), source, game
|
||||
)) {
|
||||
int count = game.getBattlefield().count(
|
||||
filter, game.getCombat().getDefendingPlayerId(permanent.getId(), game), source, game
|
||||
);
|
||||
game.addEffect(new BoostTargetEffect(
|
||||
count, 0, Duration.EndOfTurn
|
||||
).setTargetPointer(new FixedTarget(permanent, game)), source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,17 @@ package mage.cards.n;
|
|||
|
||||
import mage.MageItem;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
import mage.watchers.common.DamageDoneWatcher;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -22,21 +22,19 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class NeedleDrop extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filer = new FilterCreaturePlayerOrPlaneswalker();
|
||||
private static final FilterPermanentOrPlayer filter = new FilterAnyTarget("any target that was dealt damage this turn");
|
||||
|
||||
static {
|
||||
filer.getPlayerFilter().add(new DamagedThisTurnPredicate());
|
||||
filer.getPermanentFilter().add(new DamagedThisTurnPredicate());
|
||||
filter.getPlayerFilter().add(DamagedThisTurnPredicate.instance);
|
||||
filter.getPermanentFilter().add(DamagedThisTurnPredicate.instance);
|
||||
}
|
||||
|
||||
public NeedleDrop(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
|
||||
|
||||
// Needle Drop deals 1 damage to any target that was dealt damage this turn.
|
||||
Effect effect = new DamageTargetEffect(1);
|
||||
effect.setText("{this} deals 1 damage to any target that was dealt damage this turn");
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
this.getSpellAbility().addTarget(new TargetAnyTarget(1, 1, filer));
|
||||
this.getSpellAbility().addEffect(new DamageTargetEffect(1));
|
||||
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter));
|
||||
|
||||
// Draw a card.
|
||||
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("<br>"));
|
||||
|
@ -52,20 +50,21 @@ public final class NeedleDrop extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class DamagedThisTurnPredicate implements Predicate<MageItem> {
|
||||
enum DamagedThisTurnPredicate implements Predicate<MageItem> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(MageItem input, Game game) {
|
||||
DamageDoneWatcher watcher = game.getState().getWatcher(DamageDoneWatcher.class);
|
||||
if (watcher != null) {
|
||||
if (input instanceof MageObject) {
|
||||
return watcher.isDamaged(input.getId(), ((MageObject) input).getZoneChangeCounter(game), game);
|
||||
}
|
||||
if (input instanceof Player) {
|
||||
return watcher.isDamaged(input.getId(), 0, game);
|
||||
}
|
||||
if (watcher == null) {
|
||||
return false;
|
||||
}
|
||||
if (input instanceof MageObject) {
|
||||
return watcher.isDamaged(input.getId(), ((MageObject) input).getZoneChangeCounter(game), game);
|
||||
}
|
||||
if (input instanceof Player) {
|
||||
return watcher.isDamaged(input.getId(), 0, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,13 +13,14 @@ import mage.filter.FilterCard;
|
|||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterNonlandPermanent;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.game.Game;
|
||||
import mage.players.Library;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -31,7 +32,7 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class NicolBolasGodPharaoh extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePlayerOrPlaneswalker damageFilter
|
||||
private static final FilterPermanentOrPlayer damageFilter
|
||||
= new FilterCreaturePlayerOrPlaneswalker("opponent, creature an opponent controls, or planeswalker an opponent controls.");
|
||||
private static final FilterPermanent exileFilter = new FilterNonlandPermanent();
|
||||
|
||||
|
@ -58,7 +59,7 @@ public final class NicolBolasGodPharaoh extends CardImpl {
|
|||
|
||||
// -4: Nicol Bolas, God-Pharaoh deals 7 damage to target opponent, creature an opponent controls, or planeswalker an opponent controls.
|
||||
ability = new LoyaltyAbility(new DamageTargetEffect(7), -4);
|
||||
ability.addTarget(new TargetAnyTarget(damageFilter));
|
||||
ability.addTarget(new TargetPermanentOrPlayer(damageFilter));
|
||||
this.addAbility(ability);
|
||||
|
||||
// -12: Exile each nonland permanent your opponents control.
|
||||
|
|
53
Mage.Sets/src/mage/cards/o/OverloadedMageRing.java
Normal file
53
Mage.Sets/src/mage/cards/o/OverloadedMageRing.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package mage.cards.o;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.common.CopyTargetSpellEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.target.TargetSpell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class OverloadedMageRing extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("spell you control");
|
||||
|
||||
static {
|
||||
filter.add(TargetController.YOU.getControllerPredicate());
|
||||
}
|
||||
|
||||
public OverloadedMageRing(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
|
||||
|
||||
this.color.setBlue(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// {1}, {T}, Sacrifice Overloaded Mage-Ring: Copy target spell you control.
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new CopyTargetSpellEffect(false, false, false), new GenericManaCost(1)
|
||||
);
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new SacrificeSourceCost());
|
||||
ability.addTarget(new TargetSpell(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private OverloadedMageRing(final OverloadedMageRing card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OverloadedMageRing copy() {
|
||||
return new OverloadedMageRing(this);
|
||||
}
|
||||
}
|
|
@ -13,11 +13,11 @@ import mage.constants.CardType;
|
|||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -50,6 +50,12 @@ public class PhyrexianVindicator extends CardImpl {
|
|||
|
||||
class PhyrexianVindicatorEffect extends ReplacementEffectImpl {
|
||||
|
||||
private static final FilterAnyTarget filter = new FilterAnyTarget("any other target");
|
||||
|
||||
static {
|
||||
filter.getPermanentFilter().add(AnotherPredicate.instance);
|
||||
}
|
||||
|
||||
public PhyrexianVindicatorEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.PreventDamage);
|
||||
staticText = "If damage would be dealt to {this}, prevent that damage. When damage is prevented this way, " +
|
||||
|
@ -67,16 +73,15 @@ class PhyrexianVindicatorEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
int damage = event.getAmount();
|
||||
game.preventDamage(event, source, game, Integer.MAX_VALUE);
|
||||
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
|
||||
new DamageTargetEffect(damage), false,
|
||||
"{this} deals that much damage to any other target"
|
||||
);
|
||||
FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker("any other target");
|
||||
filter.getPermanentFilter().add(AnotherPredicate.instance);
|
||||
ability.addTarget(new TargetAnyTarget(filter));
|
||||
game.fireReflexiveTriggeredAbility(ability, source);
|
||||
int damage = game.preventDamage(event, source, game, Integer.MAX_VALUE).getPreventedDamage();
|
||||
if (damage > 0) {
|
||||
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
|
||||
new DamageTargetEffect(damage), false,
|
||||
"{this} deals that much damage to any other target"
|
||||
);
|
||||
ability.addTarget(new TargetPermanentOrPlayer(filter));
|
||||
game.fireReflexiveTriggeredAbility(ability, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ class PortalMageEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
// Select the new defender
|
||||
TargetDefender target = new TargetDefender(defenders, null);
|
||||
TargetDefender target = new TargetDefender(defenders);
|
||||
if (controller.chooseTarget(Outcome.Damage, target, source, game)) {
|
||||
if (!combatGroupTarget.getDefenderId().equals(target.getFirstTarget())) {
|
||||
if (combatGroupTarget.changeDefenderPostDeclaration(target.getFirstTarget(), game)) {
|
||||
|
|
74
Mage.Sets/src/mage/cards/p/PrickleFaeries.java
Normal file
74
Mage.Sets/src/mage/cards/p/PrickleFaeries.java
Normal file
|
@ -0,0 +1,74 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class PrickleFaeries extends CardImpl {
|
||||
|
||||
public PrickleFaeries(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.FAERIE);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
this.color.setBlack(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Prickle Faeries deals 2 damage to them.
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(
|
||||
Zone.BATTLEFIELD, new DamageTargetEffect(2),
|
||||
TargetController.OPPONENT, false, true
|
||||
), PrickleFaeriesCondition.instance, "At the beginning of each opponent's upkeep, " +
|
||||
"if that player has two or fewer cards in hand, {this} deals 2 damage to them."
|
||||
));
|
||||
}
|
||||
|
||||
private PrickleFaeries(final PrickleFaeries card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrickleFaeries copy() {
|
||||
return new PrickleFaeries(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum PrickleFaeriesCondition implements Condition {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return Optional
|
||||
.ofNullable(game.getActivePlayerId())
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Player::getHand)
|
||||
.map(Set::size)
|
||||
.orElse(0) <= 2;
|
||||
}
|
||||
}
|
52
Mage.Sets/src/mage/cards/p/PyreOfTheWorldTree.java
Normal file
52
Mage.Sets/src/mage/cards/p/PyreOfTheWorldTree.java
Normal file
|
@ -0,0 +1,52 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.DiscardTargetCost;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.DiscardCardControllerTriggeredAbility;
|
||||
import mage.abilities.effects.common.ExileTopXMayPlayUntilEndOfTurnEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class PyreOfTheWorldTree extends CardImpl {
|
||||
|
||||
public PyreOfTheWorldTree(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "");
|
||||
|
||||
this.color.setRed(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Discard a land card: Pyre of the World Tree deals 2 damage to any target.
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new DamageTargetEffect(2),
|
||||
new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_LAND_A))
|
||||
);
|
||||
ability.addTarget(new TargetAnyTarget());
|
||||
this.addAbility(ability);
|
||||
|
||||
// Whenever you discard a land card, exile the top card of your library. You may play that card this turn.
|
||||
this.addAbility(new DiscardCardControllerTriggeredAbility(
|
||||
new ExileTopXMayPlayUntilEndOfTurnEffect(1),
|
||||
false, StaticFilters.FILTER_CARD_LAND_A
|
||||
));
|
||||
}
|
||||
|
||||
private PyreOfTheWorldTree(final PyreOfTheWorldTree card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyreOfTheWorldTree copy() {
|
||||
return new PyreOfTheWorldTree(this);
|
||||
}
|
||||
}
|
47
Mage.Sets/src/mage/cards/r/RefractionElemental.java
Normal file
47
Mage.Sets/src/mage/cards/r/RefractionElemental.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.effects.common.DamagePlayersEffect;
|
||||
import mage.abilities.keyword.WardAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class RefractionElemental extends CardImpl {
|
||||
|
||||
public RefractionElemental(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.ELEMENTAL);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
this.color.setRed(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Ward--Pay 2 life.
|
||||
this.addAbility(new WardAbility(new PayLifeCost(2), false));
|
||||
|
||||
// Whenever you cast a spell, Refraction Elemental deals 3 damage to each opponent.
|
||||
this.addAbility(new SpellCastControllerTriggeredAbility(
|
||||
new DamagePlayersEffect(3, TargetController.OPPONENT), false
|
||||
));
|
||||
}
|
||||
|
||||
private RefractionElemental(final RefractionElemental card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefractionElemental copy() {
|
||||
return new RefractionElemental(this);
|
||||
}
|
||||
}
|
46
Mage.Sets/src/mage/cards/r/RooftopSaboteurs.java
Normal file
46
Mage.Sets/src/mage/cards/r/RooftopSaboteurs.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class RooftopSaboteurs extends CardImpl {
|
||||
|
||||
public RooftopSaboteurs(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.MOONFOLK);
|
||||
this.subtype.add(SubType.NINJA);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(3);
|
||||
this.color.setBlue(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Whenever Rooftop Saboteurs deals combat damage to a player or battle, draw a card.
|
||||
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
|
||||
new DrawCardSourceControllerEffect(1), false
|
||||
).setOrBattle(true));
|
||||
}
|
||||
|
||||
private RooftopSaboteurs(final RooftopSaboteurs card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RooftopSaboteurs copy() {
|
||||
return new RooftopSaboteurs(this);
|
||||
}
|
||||
}
|
42
Mage.Sets/src/mage/cards/s/SerraFaithkeeper.java
Normal file
42
Mage.Sets/src/mage/cards/s/SerraFaithkeeper.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class SerraFaithkeeper extends CardImpl {
|
||||
|
||||
public SerraFaithkeeper(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.ANGEL);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
this.color.setWhite(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Vigilance
|
||||
this.addAbility(VigilanceAbility.getInstance());
|
||||
}
|
||||
|
||||
private SerraFaithkeeper(final SerraFaithkeeper card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerraFaithkeeper copy() {
|
||||
return new SerraFaithkeeper(this);
|
||||
}
|
||||
}
|
|
@ -1,32 +1,38 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class TerraRavager extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterLandPermanent("lands defending player controls");
|
||||
|
||||
static {
|
||||
filter.add(DefendingPlayerControlsPredicate.instance);
|
||||
}
|
||||
|
||||
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter, null);
|
||||
|
||||
public TerraRavager(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
|
||||
this.subtype.add(SubType.ELEMENTAL);
|
||||
this.subtype.add(SubType.BEAST);
|
||||
|
||||
|
@ -34,7 +40,9 @@ public final class TerraRavager extends CardImpl {
|
|||
this.toughness = new MageInt(4);
|
||||
|
||||
// Whenever Terra Ravager attacks, it gets +X/+0 until end of turn, where X is the number of lands defending player controls.
|
||||
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(new TerraRavagerLandCount(), StaticValue.get(0), Duration.EndOfTurn, true), false));
|
||||
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(
|
||||
xValue, StaticValue.get(0), Duration.EndOfTurn, true, "it"
|
||||
), false));
|
||||
}
|
||||
|
||||
private TerraRavager(final TerraRavager card) {
|
||||
|
@ -46,39 +54,3 @@ public final class TerraRavager extends CardImpl {
|
|||
return new TerraRavager(this);
|
||||
}
|
||||
}
|
||||
|
||||
class TerraRavagerLandCount implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
for (CombatGroup group :game.getCombat().getGroups()) {
|
||||
if (group.getAttackers().contains(sourceAbility.getSourceId())) {
|
||||
UUID defenderId = group.getDefenderId();
|
||||
if (group.isDefenderIsPlaneswalker()) {
|
||||
Permanent permanent = game.getPermanent(defenderId);
|
||||
if (permanent != null) {
|
||||
defenderId = permanent.getControllerId();
|
||||
}
|
||||
}
|
||||
return game.getBattlefield().countAll(new FilterLandPermanent(), defenderId, game);
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerraRavagerLandCount copy() {
|
||||
return new TerraRavagerLandCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "the number of lands defending player controls";
|
||||
}
|
||||
}
|
||||
|
|
63
Mage.Sets/src/mage/cards/t/TheBrokenSky.java
Normal file
63
Mage.Sets/src/mage/cards/t/TheBrokenSky.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.TokenPredicate;
|
||||
import mage.game.permanent.token.WhiteBlackSpiritToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TheBrokenSky extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature tokens");
|
||||
|
||||
static {
|
||||
filter.add(TokenPredicate.TRUE);
|
||||
}
|
||||
|
||||
public TheBrokenSky(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "");
|
||||
|
||||
this.color.setWhite(true);
|
||||
this.color.setBlack(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Creature tokens you control get +1/+0 and have lifelink.
|
||||
Ability ability = new SimpleStaticAbility(new BoostControlledEffect(
|
||||
1, 0, Duration.WhileOnBattlefield, filter
|
||||
));
|
||||
ability.addEffect(new GainAbilityControlledEffect(
|
||||
LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, filter
|
||||
).setText("and have lifelink"));
|
||||
this.addAbility(ability);
|
||||
|
||||
// At the beginning of your end step, create a 1/1 white and black Spirit creature token with flying.
|
||||
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||
new CreateTokenEffect(new WhiteBlackSpiritToken()),
|
||||
TargetController.YOU, false
|
||||
));
|
||||
}
|
||||
|
||||
private TheBrokenSky(final TheBrokenSky card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheBrokenSky copy() {
|
||||
return new TheBrokenSky(this);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
|
@ -22,7 +21,8 @@ import mage.cards.CardSetInfo;
|
|||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||
import mage.game.Game;
|
||||
|
@ -31,6 +31,7 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -118,9 +119,9 @@ class ToralfGodOfFuryTriggeredAbility extends TriggeredAbilityImpl {
|
|||
this.getTargets().clear();
|
||||
int excessDamage = dEvent.getExcess();
|
||||
this.addEffect(new DamageTargetEffect(excessDamage));
|
||||
FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker();
|
||||
filter.getPermanentFilter().add(Predicates.not(new MageObjectReferencePredicate(new MageObjectReference(event.getTargetId(), game))));
|
||||
this.addTarget(new TargetAnyTarget(filter).withChooseHint(Integer.toString(excessDamage) + " damage"));
|
||||
FilterPermanentOrPlayer filter = new FilterAnyTarget();
|
||||
filter.getPermanentFilter().add(Predicates.not(new MageObjectReferencePredicate(event.getTargetId(), game)));
|
||||
this.addTarget(new TargetPermanentOrPlayer(filter).withChooseHint(Integer.toString(excessDamage) + " damage"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
62
Mage.Sets/src/mage/cards/t/TrugaCliffcharger.java
Normal file
62
Mage.Sets/src/mage/cards/t/TrugaCliffcharger.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TrugaCliffcharger extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("a land or battle card");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
CardType.LAND.getPredicate(),
|
||||
CardType.BATTLE.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
public TrugaCliffcharger(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.RHINO);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(4);
|
||||
this.color.setRed(true);
|
||||
this.color.setGreen(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// When Truga Cliffcharger enters the battlefield, you may discard a card. If you do, search your library for a land or battle card, reveal it, put it into your hand, then shuffle.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new DoIfCostPaid(new SearchLibraryPutInHandEffect(
|
||||
new TargetCardInLibrary(filter), true, true
|
||||
), new DiscardCardCost())
|
||||
));
|
||||
}
|
||||
|
||||
private TrugaCliffcharger(final TrugaCliffcharger card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrugaCliffcharger copy() {
|
||||
return new TrugaCliffcharger(this);
|
||||
}
|
||||
}
|
48
Mage.Sets/src/mage/cards/v/VertexPaladin.java
Normal file
48
Mage.Sets/src/mage/cards/v/VertexPaladin.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package mage.cards.v;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
|
||||
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class VertexPaladin extends CardImpl {
|
||||
|
||||
public VertexPaladin(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.ANGEL);
|
||||
this.subtype.add(SubType.KNIGHT);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(0);
|
||||
this.color.setWhite(true);
|
||||
this.color.setBlue(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Vertex Paladin's power and toughness are each equal to the number of creatures you control.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CreaturesYouControlCount.instance, Duration.Custom)));
|
||||
}
|
||||
|
||||
private VertexPaladin(final VertexPaladin card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexPaladin copy() {
|
||||
return new VertexPaladin(this);
|
||||
}
|
||||
}
|
46
Mage.Sets/src/mage/cards/w/WinnowingForces.java
Normal file
46
Mage.Sets/src/mage/cards/w/WinnowingForces.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package mage.cards.w;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.dynamicvalue.common.LandsYouControlCount;
|
||||
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class WinnowingForces extends CardImpl {
|
||||
|
||||
public WinnowingForces(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
||||
|
||||
this.subtype.add(SubType.ELF);
|
||||
this.subtype.add(SubType.WARRIOR);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(0);
|
||||
this.color.setGreen(true);
|
||||
this.color.setBlack(true);
|
||||
this.nightCard = true;
|
||||
|
||||
// Winnowing Forces's power and toughness are each equal to the number of lands you control.
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL, new SetBasePowerToughnessSourceEffect(LandsYouControlCount.instance, Duration.Custom)
|
||||
));
|
||||
}
|
||||
|
||||
private WinnowingForces(final WinnowingForces card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WinnowingForces copy() {
|
||||
return new WinnowingForces(this);
|
||||
}
|
||||
}
|
|
@ -11,13 +11,14 @@ import mage.constants.CardType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
|
||||
import mage.filter.common.FilterAnyTarget;
|
||||
import mage.filter.common.FilterPermanentOrPlayer;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -52,8 +53,8 @@ public final class WrathfulRedDragon extends CardImpl {
|
|||
|
||||
class WrathfulRedDragonTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private static final FilterCreaturePlayerOrPlaneswalker filter
|
||||
= new FilterCreaturePlayerOrPlaneswalker("any target that isn't a Dragon");
|
||||
private static final FilterPermanentOrPlayer filter
|
||||
= new FilterAnyTarget("any target that isn't a Dragon");
|
||||
|
||||
static {
|
||||
filter.getPermanentFilter().add(Predicates.not(SubType.DRAGON.getPredicate()));
|
||||
|
@ -61,7 +62,7 @@ class WrathfulRedDragonTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
WrathfulRedDragonTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new WrathfulRedDragonEffect());
|
||||
this.addTarget(new TargetAnyTarget(filter));
|
||||
this.addTarget(new TargetPermanentOrPlayer(filter));
|
||||
}
|
||||
|
||||
private WrathfulRedDragonTriggeredAbility(final WrathfulRedDragonTriggeredAbility ability) {
|
||||
|
|
|
@ -27,6 +27,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
|
||||
cards.add(new SetCardInfo("Aerial Boost", 2, Rarity.COMMON, mage.cards.a.AerialBoost.class));
|
||||
cards.add(new SetCardInfo("Aetherblade Agent", 88, Rarity.COMMON, mage.cards.a.AetherbladeAgent.class));
|
||||
cards.add(new SetCardInfo("Aetherwing, Golden-Scale Flagship", 234, Rarity.UNCOMMON, mage.cards.a.AetherwingGoldenScaleFlagship.class));
|
||||
cards.add(new SetCardInfo("Akki Scrapchomper", 130, Rarity.COMMON, mage.cards.a.AkkiScrapchomper.class));
|
||||
cards.add(new SetCardInfo("Alabaster Host Intercessor", 3, Rarity.COMMON, mage.cards.a.AlabasterHostIntercessor.class));
|
||||
cards.add(new SetCardInfo("Alabaster Host Sanctifier", 4, Rarity.COMMON, mage.cards.a.AlabasterHostSanctifier.class));
|
||||
|
@ -40,12 +41,16 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Astral Wingspan", 48, Rarity.UNCOMMON, mage.cards.a.AstralWingspan.class));
|
||||
cards.add(new SetCardInfo("Atraxa's Fall", 176, Rarity.COMMON, mage.cards.a.AtraxasFall.class));
|
||||
cards.add(new SetCardInfo("Attentive Skywarden", 7, Rarity.COMMON, mage.cards.a.AttentiveSkywarden.class));
|
||||
cards.add(new SetCardInfo("Awaken the Maelstrom", 230, Rarity.RARE, mage.cards.a.AwakenTheMaelstrom.class));
|
||||
cards.add(new SetCardInfo("Baral and Kari Zev", 218, Rarity.RARE, mage.cards.b.BaralAndKariZev.class));
|
||||
cards.add(new SetCardInfo("Beamtown Beatstick", 131, Rarity.COMMON, mage.cards.b.BeamtownBeatstick.class));
|
||||
cards.add(new SetCardInfo("Belenon War Anthem", 20, Rarity.UNCOMMON, mage.cards.b.BelenonWarAnthem.class));
|
||||
cards.add(new SetCardInfo("Belligerent Regisaur", 191, Rarity.RARE, mage.cards.b.BelligerentRegisaur.class));
|
||||
cards.add(new SetCardInfo("Bladed Battle-Fan", 91, Rarity.COMMON, mage.cards.b.BladedBattleFan.class));
|
||||
cards.add(new SetCardInfo("Blighted Burgeoning", 177, Rarity.COMMON, mage.cards.b.BlightedBurgeoning.class));
|
||||
cards.add(new SetCardInfo("Bloated Processor", 93, Rarity.RARE, mage.cards.b.BloatedProcessor.class));
|
||||
cards.add(new SetCardInfo("Bloodfell Caves", 267, Rarity.COMMON, mage.cards.b.BloodfellCaves.class));
|
||||
cards.add(new SetCardInfo("Bloomwielder Dryads", 237, Rarity.UNCOMMON, mage.cards.b.BloomwielderDryads.class));
|
||||
cards.add(new SetCardInfo("Blossoming Sands", 268, Rarity.COMMON, mage.cards.b.BlossomingSands.class));
|
||||
cards.add(new SetCardInfo("Bola Slinger", 8, Rarity.COMMON, mage.cards.b.BolaSlinger.class));
|
||||
cards.add(new SetCardInfo("Bonded Herdbeast", 178, Rarity.COMMON, mage.cards.b.BondedHerdbeast.class));
|
||||
|
@ -74,6 +79,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Cut Short", 10, Rarity.COMMON, mage.cards.c.CutShort.class));
|
||||
cards.add(new SetCardInfo("Deadly Derision", 99, Rarity.COMMON, mage.cards.d.DeadlyDerision.class));
|
||||
cards.add(new SetCardInfo("Deeproot Wayfinder", 184, Rarity.RARE, mage.cards.d.DeeprootWayfinder.class));
|
||||
cards.add(new SetCardInfo("Deluge of the Dead", 115, Rarity.MYTHIC, mage.cards.d.DelugeOfTheDead.class));
|
||||
cards.add(new SetCardInfo("Dismal Backwater", 269, Rarity.COMMON, mage.cards.d.DismalBackwater.class));
|
||||
cards.add(new SetCardInfo("Disturbing Conversion", 54, Rarity.COMMON, mage.cards.d.DisturbingConversion.class));
|
||||
cards.add(new SetCardInfo("Doomskar Warrior", 185, Rarity.RARE, mage.cards.d.DoomskarWarrior.class));
|
||||
|
@ -83,6 +89,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Elvish Vatkeeper", 223, Rarity.UNCOMMON, mage.cards.e.ElvishVatkeeper.class));
|
||||
cards.add(new SetCardInfo("Enduring Bondwarden", 14, Rarity.COMMON, mage.cards.e.EnduringBondwarden.class));
|
||||
cards.add(new SetCardInfo("Ephara's Dispersal", 55, Rarity.COMMON, mage.cards.e.EpharasDispersal.class));
|
||||
cards.add(new SetCardInfo("Ephara, Ever-Sheltering", 23, Rarity.RARE, mage.cards.e.EpharaEverSheltering.class));
|
||||
cards.add(new SetCardInfo("Errant and Giada", 224, Rarity.RARE, mage.cards.e.ErrantAndGiada.class));
|
||||
cards.add(new SetCardInfo("Essence of Orthodoxy", 323, Rarity.RARE, mage.cards.e.EssenceOfOrthodoxy.class));
|
||||
cards.add(new SetCardInfo("Etali, Primal Conqueror", 137, Rarity.RARE, mage.cards.e.EtaliPrimalConqueror.class));
|
||||
|
@ -105,6 +112,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Furnace Reins", 141, Rarity.UNCOMMON, mage.cards.f.FurnaceReins.class));
|
||||
cards.add(new SetCardInfo("Furnace-Blessed Conqueror", 38, Rarity.UNCOMMON, mage.cards.f.FurnaceBlessedConqueror.class));
|
||||
cards.add(new SetCardInfo("Furtive Analyst", 59, Rarity.COMMON, mage.cards.f.FurtiveAnalyst.class));
|
||||
cards.add(new SetCardInfo("Gargantuan Slabhorn", 240, Rarity.UNCOMMON, mage.cards.g.GargantuanSlabhorn.class));
|
||||
cards.add(new SetCardInfo("Gift of Compleation", 106, Rarity.UNCOMMON, mage.cards.g.GiftOfCompleation.class));
|
||||
cards.add(new SetCardInfo("Gitaxian Mindstinger", 88, Rarity.COMMON, mage.cards.g.GitaxianMindstinger.class));
|
||||
cards.add(new SetCardInfo("Gitaxian Spellstalker", 151, Rarity.UNCOMMON, mage.cards.g.GitaxianSpellstalker.class));
|
||||
|
@ -116,6 +124,8 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Gnottvold Hermit", 188, Rarity.UNCOMMON, mage.cards.g.GnottvoldHermit.class));
|
||||
cards.add(new SetCardInfo("Golden-Scale Aeronaut", 15, Rarity.COMMON, mage.cards.g.GoldenScaleAeronaut.class));
|
||||
cards.add(new SetCardInfo("Grafted Butcher", 109, Rarity.RARE, mage.cards.g.GraftedButcher.class));
|
||||
cards.add(new SetCardInfo("Grandmother Ravi Sengir", 116, Rarity.UNCOMMON, mage.cards.g.GrandmotherRaviSengir.class));
|
||||
cards.add(new SetCardInfo("Guildpact Paragon", 1, Rarity.MYTHIC, mage.cards.g.GuildpactParagon.class));
|
||||
cards.add(new SetCardInfo("Halo Hopper", 260, Rarity.COMMON, mage.cards.h.HaloHopper.class));
|
||||
cards.add(new SetCardInfo("Halo-Charged Skaab", 60, Rarity.COMMON, mage.cards.h.HaloChargedSkaab.class));
|
||||
cards.add(new SetCardInfo("Hangar Scrounger", 142, Rarity.COMMON, mage.cards.h.HangarScrounger.class));
|
||||
|
@ -131,6 +141,29 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Inspired Charge", 19, Rarity.COMMON, mage.cards.i.InspiredCharge.class));
|
||||
cards.add(new SetCardInfo("Interdisciplinary Mascot", 326, Rarity.RARE, mage.cards.i.InterdisciplinaryMascot.class));
|
||||
cards.add(new SetCardInfo("Into the Fire", 144, Rarity.RARE, mage.cards.i.IntoTheFire.class));
|
||||
cards.add(new SetCardInfo("Invasion of Alara", 230, Rarity.RARE, mage.cards.i.InvasionOfAlara.class));
|
||||
cards.add(new SetCardInfo("Invasion of Amonkhet", 231, Rarity.UNCOMMON, mage.cards.i.InvasionOfAmonkhet.class));
|
||||
cards.add(new SetCardInfo("Invasion of Belenon", 20, Rarity.UNCOMMON, mage.cards.i.InvasionOfBelenon.class));
|
||||
cards.add(new SetCardInfo("Invasion of Dominaria", 21, Rarity.UNCOMMON, mage.cards.i.InvasionOfDominaria.class));
|
||||
cards.add(new SetCardInfo("Invasion of Eldraine", 113, Rarity.UNCOMMON, mage.cards.i.InvasionOfEldraine.class));
|
||||
cards.add(new SetCardInfo("Invasion of Ergamon", 233, Rarity.UNCOMMON, mage.cards.i.InvasionOfErgamon.class));
|
||||
cards.add(new SetCardInfo("Invasion of Innistrad", 115, Rarity.MYTHIC, mage.cards.i.InvasionOfInnistrad.class));
|
||||
cards.add(new SetCardInfo("Invasion of Ixalan", 191, Rarity.RARE, mage.cards.i.InvasionOfIxalan.class));
|
||||
cards.add(new SetCardInfo("Invasion of Kaladesh", 234, Rarity.UNCOMMON, mage.cards.i.InvasionOfKaladesh.class));
|
||||
cards.add(new SetCardInfo("Invasion of Kaldheim", 145, Rarity.RARE, mage.cards.i.InvasionOfKaldheim.class));
|
||||
cards.add(new SetCardInfo("Invasion of Kamigawa", 62, Rarity.UNCOMMON, mage.cards.i.InvasionOfKamigawa.class));
|
||||
cards.add(new SetCardInfo("Invasion of Karsus", 146, Rarity.RARE, mage.cards.i.InvasionOfKarsus.class));
|
||||
cards.add(new SetCardInfo("Invasion of Lorwyn", 236, Rarity.UNCOMMON, mage.cards.i.InvasionOfLorwyn.class));
|
||||
cards.add(new SetCardInfo("Invasion of Mercadia", 147, Rarity.UNCOMMON, mage.cards.i.InvasionOfMercadia.class));
|
||||
cards.add(new SetCardInfo("Invasion of Moag", 237, Rarity.UNCOMMON, mage.cards.i.InvasionOfMoag.class));
|
||||
cards.add(new SetCardInfo("Invasion of Pyrulea", 240, Rarity.UNCOMMON, mage.cards.i.InvasionOfPyrulea.class));
|
||||
cards.add(new SetCardInfo("Invasion of Ravnica", 1, Rarity.MYTHIC, mage.cards.i.InvasionOfRavnica.class));
|
||||
cards.add(new SetCardInfo("Invasion of Shandalar", 193, Rarity.MYTHIC, mage.cards.i.InvasionOfShandalar.class));
|
||||
cards.add(new SetCardInfo("Invasion of Theros", 23, Rarity.RARE, mage.cards.i.InvasionOfTheros.class));
|
||||
cards.add(new SetCardInfo("Invasion of Tolvada", 241, Rarity.RARE, mage.cards.i.InvasionOfTolvada.class));
|
||||
cards.add(new SetCardInfo("Invasion of Ulgrotha", 116, Rarity.UNCOMMON, mage.cards.i.InvasionOfUlgrotha.class));
|
||||
cards.add(new SetCardInfo("Invasion of Vryn", 64, Rarity.UNCOMMON, mage.cards.i.InvasionOfVryn.class));
|
||||
cards.add(new SetCardInfo("Invasion of Xerex", 242, Rarity.UNCOMMON, mage.cards.i.InvasionOfXerex.class));
|
||||
cards.add(new SetCardInfo("Iridescent Blademaster", 195, Rarity.COMMON, mage.cards.i.IridescentBlademaster.class));
|
||||
cards.add(new SetCardInfo("Island", 278, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Joyful Stormsculptor", 243, Rarity.UNCOMMON, mage.cards.j.JoyfulStormsculptor.class));
|
||||
|
@ -145,6 +178,9 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Kogla and Yidaro", 244, Rarity.RARE, mage.cards.k.KoglaAndYidaro.class));
|
||||
cards.add(new SetCardInfo("Kor Halberd", 27, Rarity.COMMON, mage.cards.k.KorHalberd.class));
|
||||
cards.add(new SetCardInfo("Kroxa and Kunoros", 245, Rarity.MYTHIC, mage.cards.k.KroxaAndKunoros.class));
|
||||
cards.add(new SetCardInfo("Kyren Flamewright", 147, Rarity.UNCOMMON, mage.cards.k.KyrenFlamewright.class));
|
||||
cards.add(new SetCardInfo("Lazotep Convert", 231, Rarity.UNCOMMON, mage.cards.l.LazotepConvert.class));
|
||||
cards.add(new SetCardInfo("Leyline Surge", 193, Rarity.MYTHIC, mage.cards.l.LeylineSurge.class));
|
||||
cards.add(new SetCardInfo("Lithomantic Barrage", 152, Rarity.UNCOMMON, mage.cards.l.LithomanticBarrage.class));
|
||||
cards.add(new SetCardInfo("Malady Invoker", 189, Rarity.UNCOMMON, mage.cards.m.MaladyInvoker.class));
|
||||
cards.add(new SetCardInfo("Marauding Dreadship", 153, Rarity.COMMON, mage.cards.m.MaraudingDreadship.class));
|
||||
|
@ -170,6 +206,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Order of the Mirror", 72, Rarity.COMMON, mage.cards.o.OrderOfTheMirror.class));
|
||||
cards.add(new SetCardInfo("Orthion, Hero of Lavabrink", 334, Rarity.RARE, mage.cards.o.OrthionHeroOfLavabrink.class));
|
||||
cards.add(new SetCardInfo("Overgrown Pest", 197, Rarity.COMMON, mage.cards.o.OvergrownPest.class));
|
||||
cards.add(new SetCardInfo("Overloaded Mage-Ring", 64, Rarity.UNCOMMON, mage.cards.o.OverloadedMageRing.class));
|
||||
cards.add(new SetCardInfo("Ozolith, the Shattered Spire", 198, Rarity.RARE, mage.cards.o.OzolithTheShatteredSpire.class));
|
||||
cards.add(new SetCardInfo("Phyrexian Archivist", 262, Rarity.COMMON, mage.cards.p.PhyrexianArchivist.class));
|
||||
cards.add(new SetCardInfo("Phyrexian Awakening", 30, Rarity.UNCOMMON, mage.cards.p.PhyrexianAwakening.class));
|
||||
|
@ -184,8 +221,10 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Polukranos, Engine of Ruin", 200, Rarity.RARE, mage.cards.p.PolukranosEngineOfRuin.class));
|
||||
cards.add(new SetCardInfo("Portent Tracker", 201, Rarity.COMMON, mage.cards.p.PortentTracker.class));
|
||||
cards.add(new SetCardInfo("Preening Champion", 73, Rarity.COMMON, mage.cards.p.PreeningChampion.class));
|
||||
cards.add(new SetCardInfo("Prickle Faeries", 113, Rarity.UNCOMMON, mage.cards.p.PrickleFaeries.class));
|
||||
cards.add(new SetCardInfo("Progenitor Exarch", 32, Rarity.RARE, mage.cards.p.ProgenitorExarch.class));
|
||||
cards.add(new SetCardInfo("Protocol Knight", 74, Rarity.COMMON, mage.cards.p.ProtocolKnight.class));
|
||||
cards.add(new SetCardInfo("Pyre of the World Tree", 145, Rarity.RARE, mage.cards.p.PyreOfTheWorldTree.class));
|
||||
cards.add(new SetCardInfo("Pyretic Prankster", 157, Rarity.COMMON, mage.cards.p.PyreticPrankster.class));
|
||||
cards.add(new SetCardInfo("Ral's Reinforcements", 158, Rarity.COMMON, mage.cards.r.RalsReinforcements.class));
|
||||
cards.add(new SetCardInfo("Ramosian Greatsword", 159, Rarity.UNCOMMON, mage.cards.r.RamosianGreatsword.class));
|
||||
|
@ -196,8 +235,10 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Realmbreaker's Grasp", 33, Rarity.COMMON, mage.cards.r.RealmbreakersGrasp.class));
|
||||
cards.add(new SetCardInfo("Redcap Heelslasher", 161, Rarity.COMMON, mage.cards.r.RedcapHeelslasher.class));
|
||||
cards.add(new SetCardInfo("Referee Squad", 327, Rarity.UNCOMMON, mage.cards.r.RefereeSquad.class));
|
||||
cards.add(new SetCardInfo("Refraction Elemental", 146, Rarity.RARE, mage.cards.r.RefractionElemental.class));
|
||||
cards.add(new SetCardInfo("Rona, Herald of Invasion", 75, Rarity.RARE, mage.cards.r.RonaHeraldOfInvasion.class));
|
||||
cards.add(new SetCardInfo("Rona, Tolarian Obliterator", 75, Rarity.RARE, mage.cards.r.RonaTolarianObliterator.class));
|
||||
cards.add(new SetCardInfo("Rooftop Saboteurs", 62, Rarity.UNCOMMON, mage.cards.r.RooftopSaboteurs.class));
|
||||
cards.add(new SetCardInfo("Rugged Highlands", 271, Rarity.COMMON, mage.cards.r.RuggedHighlands.class));
|
||||
cards.add(new SetCardInfo("Ruins Recluse", 336, Rarity.UNCOMMON, mage.cards.r.RuinsRecluse.class));
|
||||
cards.add(new SetCardInfo("Saiba Cryptomancer", 76, Rarity.COMMON, mage.cards.s.SaibaCryptomancer.class));
|
||||
|
@ -213,6 +254,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Seraph of New Capenna", 36, Rarity.UNCOMMON, mage.cards.s.SeraphOfNewCapenna.class));
|
||||
cards.add(new SetCardInfo("Seraph of New Phyrexia", 36, Rarity.UNCOMMON, mage.cards.s.SeraphOfNewPhyrexia.class));
|
||||
cards.add(new SetCardInfo("Serpent-Blade Assailant", 205, Rarity.COMMON, mage.cards.s.SerpentBladeAssailant.class));
|
||||
cards.add(new SetCardInfo("Serra Faithkeeper", 21, Rarity.UNCOMMON, mage.cards.s.SerraFaithkeeper.class));
|
||||
cards.add(new SetCardInfo("Shatter the Source", 164, Rarity.COMMON, mage.cards.s.ShatterTheSource.class));
|
||||
cards.add(new SetCardInfo("Shivan Branch-Burner", 165, Rarity.UNCOMMON, mage.cards.s.ShivanBranchBurner.class));
|
||||
cards.add(new SetCardInfo("Sigiled Sentinel", 37, Rarity.COMMON, mage.cards.s.SigiledSentinel.class));
|
||||
|
@ -235,6 +277,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Tarkir Duneshaper", 43, Rarity.COMMON, mage.cards.t.TarkirDuneshaper.class));
|
||||
cards.add(new SetCardInfo("Temporal Cleansing", 80, Rarity.COMMON, mage.cards.t.TemporalCleansing.class));
|
||||
cards.add(new SetCardInfo("Tenured Oilcaster", 126, Rarity.COMMON, mage.cards.t.TenuredOilcaster.class));
|
||||
cards.add(new SetCardInfo("The Broken Sky", 241, Rarity.RARE, mage.cards.t.TheBrokenSky.class));
|
||||
cards.add(new SetCardInfo("Thornwood Falls", 274, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class));
|
||||
cards.add(new SetCardInfo("Thrashing Frontliner", 167, Rarity.COMMON, mage.cards.t.ThrashingFrontliner.class));
|
||||
cards.add(new SetCardInfo("Thunderhead Squadron", 81, Rarity.COMMON, mage.cards.t.ThunderheadSquadron.class));
|
||||
|
@ -246,10 +289,12 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Transcendent Message", 83, Rarity.RARE, mage.cards.t.TranscendentMessage.class));
|
||||
cards.add(new SetCardInfo("Traumatic Revelation", 127, Rarity.COMMON, mage.cards.t.TraumaticRevelation.class));
|
||||
cards.add(new SetCardInfo("Tribute to the World Tree", 211, Rarity.RARE, mage.cards.t.TributeToTheWorldTree.class));
|
||||
cards.add(new SetCardInfo("Truga Cliffcharger", 233, Rarity.UNCOMMON, mage.cards.t.TrugaCliffcharger.class));
|
||||
cards.add(new SetCardInfo("Unseal the Necropolis", 128, Rarity.COMMON, mage.cards.u.UnsealTheNecropolis.class));
|
||||
cards.add(new SetCardInfo("Urn of Godfire", 266, Rarity.COMMON, mage.cards.u.UrnOfGodfire.class));
|
||||
cards.add(new SetCardInfo("Vanquish the Weak", 129, Rarity.COMMON, mage.cards.v.VanquishTheWeak.class));
|
||||
cards.add(new SetCardInfo("Vengeant Earth", 212, Rarity.COMMON, mage.cards.v.VengeantEarth.class));
|
||||
cards.add(new SetCardInfo("Vertex Paladin", 242, Rarity.UNCOMMON, mage.cards.v.VertexPaladin.class));
|
||||
cards.add(new SetCardInfo("Volcanic Spite", 170, Rarity.COMMON, mage.cards.v.VolcanicSpite.class));
|
||||
cards.add(new SetCardInfo("Voldaren Thrillseeker", 171, Rarity.RARE, mage.cards.v.VoldarenThrillseeker.class));
|
||||
cards.add(new SetCardInfo("War Historian", 214, Rarity.COMMON, mage.cards.w.WarHistorian.class));
|
||||
|
@ -258,6 +303,7 @@ public final class MarchOfTheMachine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Wicked Slumber", 84, Rarity.UNCOMMON, mage.cards.w.WickedSlumber.class));
|
||||
cards.add(new SetCardInfo("Wildwood Escort", 216, Rarity.COMMON, mage.cards.w.WildwoodEscort.class));
|
||||
cards.add(new SetCardInfo("Wind-Scarred Crag", 276, Rarity.COMMON, mage.cards.w.WindScarredCrag.class));
|
||||
cards.add(new SetCardInfo("Winnowing Forces", 236, Rarity.UNCOMMON, mage.cards.w.WinnowingForces.class));
|
||||
cards.add(new SetCardInfo("Wrenn and Realmbreaker", 217, Rarity.MYTHIC, mage.cards.w.WrennAndRealmbreaker.class));
|
||||
cards.add(new SetCardInfo("Wrenn's Resolve", 173, Rarity.COMMON, mage.cards.w.WrennsResolve.class));
|
||||
cards.add(new SetCardInfo("Xerex Strobe-Knight", 85, Rarity.UNCOMMON, mage.cards.x.XerexStrobeKnight.class));
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package org.mage.test.cards.battle;
|
||||
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class BattleBaseTest extends CardTestPlayerBase {
|
||||
|
||||
protected static final String belenon = "Invasion of Belenon";
|
||||
protected static final String warAnthem = "Belenon War Anthem";
|
||||
protected static final String kaladesh = "Invasion of Kaladesh";
|
||||
protected static final String bear = "Grizzly Bears";
|
||||
protected static final String confiscate = "Confiscate";
|
||||
protected static final String impact = "Explosive Impact";
|
||||
protected static final String stifle = "Stifle";
|
||||
|
||||
protected void assertBattle(Player controller, Player protector, String name) {
|
||||
assertPermanentCount(controller, name, 1);
|
||||
Permanent permanent = getPermanent(name);
|
||||
Assertions.assertTrue(
|
||||
permanent.isProtectedBy(protector.getId()),
|
||||
"Battle " + name + " should be protected by " + protector.getName()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
package org.mage.test.cards.battle;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class BattleDuelTest extends BattleBaseTest {
|
||||
|
||||
@Test
|
||||
public void testRegularCastAndTrigger() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertBattle(playerA, playerB, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttackBattle() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bear);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
attack(1, playerA, bear, belenon);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertBattle(playerA, playerB, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
assertTapped(bear, true);
|
||||
assertLife(playerB, 20);
|
||||
assertCounterCount(belenon, CounterType.DEFENSE, 5 - 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttackBattleBlock() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bear);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bear);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
attack(1, playerA, bear, belenon);
|
||||
block(1, playerB, bear, bear);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertBattle(playerA, playerB, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
assertPermanentCount(playerA, bear, 0);
|
||||
assertGraveyardCount(playerA, bear, 1);
|
||||
assertPermanentCount(playerB, bear, 0);
|
||||
assertGraveyardCount(playerB, bear, 1);
|
||||
assertLife(playerB, 20);
|
||||
assertCounterCount(belenon, CounterType.DEFENSE, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantAttackBattleYouProtect() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bear);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
attack(2, playerB, bear, belenon);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertBattle(playerA, playerB, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
assertTapped(bear, false);
|
||||
assertLife(playerB, 20);
|
||||
assertCounterCount(belenon, CounterType.DEFENSE, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeControl() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 6);
|
||||
addCard(Zone.HAND, playerB, confiscate);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, confiscate, belenon);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertBattle(playerB, playerA, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefeated() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plateau", 3 + 6);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
addCard(Zone.HAND, playerA, impact);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, impact, belenon);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, belenon, 0);
|
||||
assertPermanentCount(playerA, warAnthem, 1);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
assertPowerToughness(playerA, "Knight Token", 2 + 1, 2 + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefeatedStifle() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 2 + 6 + 1);
|
||||
addCard(Zone.HAND, playerA, kaladesh);
|
||||
addCard(Zone.HAND, playerA, impact);
|
||||
addCard(Zone.HAND, playerA, stifle);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, kaladesh);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, impact, kaladesh);
|
||||
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN, playerA, true);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, stifle, "stack ability");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, kaladesh, 0);
|
||||
assertGraveyardCount(playerA, kaladesh, 1);
|
||||
assertPermanentCount(playerA, "Thopter Token", 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package org.mage.test.cards.battle;
|
||||
|
||||
import mage.constants.MultiplayerAttackOption;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.RangeOfInfluence;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.FreeForAll;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameException;
|
||||
import mage.game.mulligan.MulliganType;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class BattleMultiplayerTest extends BattleBaseTest {
|
||||
|
||||
@Override
|
||||
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
|
||||
Game game = new FreeForAll(
|
||||
MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL,
|
||||
MulliganType.GAME_DEFAULT.getMulligan(0), 20
|
||||
);
|
||||
// Player order: A -> D -> C -> B
|
||||
playerA = createPlayer(game, "PlayerA");
|
||||
playerB = createPlayer(game, "PlayerB");
|
||||
playerC = createPlayer(game, "PlayerC");
|
||||
playerD = createPlayer(game, "PlayerD");
|
||||
return game;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegularCastAndTrigger() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
setChoice(playerA, playerC.getName());
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
|
||||
assertBattle(playerA, playerC, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttackBattle() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bear);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
setChoice(playerA, playerC.getName());
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
attack(1, playerA, bear, belenon);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
|
||||
assertBattle(playerA, playerC, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
assertTapped(bear, true);
|
||||
assertLife(playerC, 20);
|
||||
assertCounterCount(belenon, CounterType.DEFENSE, 5 - 2);
|
||||
}
|
||||
|
||||
@Ignore // TODO: this test fails randomly and it's not clear exactly why, it works correctly though
|
||||
@Test
|
||||
public void testAttackBattleBlock() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bear);
|
||||
addCard(Zone.BATTLEFIELD, playerC, bear);
|
||||
addCard(Zone.HAND, playerA, belenon);
|
||||
|
||||
setChoice(playerA, playerC.getName());
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, belenon);
|
||||
|
||||
attack(1, playerA, bear, belenon);
|
||||
block(1, playerC, bear, bear);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
|
||||
assertBattle(playerA, playerC, belenon);
|
||||
assertPermanentCount(playerA, "Knight Token", 1);
|
||||
assertPermanentCount(playerA, bear, 0);
|
||||
assertGraveyardCount(playerA, bear, 1);
|
||||
assertPermanentCount(playerC, bear, 0);
|
||||
assertGraveyardCount(playerC, bear, 1);
|
||||
assertLife(playerC, 20);
|
||||
assertCounterCount(belenon, CounterType.DEFENSE, 5);
|
||||
}
|
||||
}
|
|
@ -1711,15 +1711,15 @@ public class TestPlayer implements Player {
|
|||
String[] groups = command.split("\\$");
|
||||
for (int i = 1; i < groups.length; i++) {
|
||||
String group = groups[i];
|
||||
if (group.startsWith("planeswalker=")) {
|
||||
String planeswalkerName = group.substring(group.indexOf("planeswalker=") + 13);
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_PLANESWALKER, game)) {
|
||||
if (hasObjectTargetNameOrAlias(permanent, planeswalkerName)) {
|
||||
if (group.startsWith("permanent=")) {
|
||||
String permanentName = group.substring(group.indexOf("permanent=") + 10);
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT, game)) {
|
||||
if (hasObjectTargetNameOrAlias(permanent, permanentName)) {
|
||||
defenderId = permanent.getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (group.startsWith("defendingPlayer=")) {
|
||||
} else if (group.startsWith("defendingPlayer=")) {
|
||||
String defendingPlayerName = group.substring(group.indexOf("defendingPlayer=") + 16);
|
||||
for (Player defendingPlayer : game.getPlayers().values()) {
|
||||
if (defendingPlayer.getName().equals(defendingPlayerName)) {
|
||||
|
@ -2322,8 +2322,7 @@ public class TestPlayer implements Player {
|
|||
if (target.getOriginalTarget() instanceof TargetPlayer
|
||||
|| target.getOriginalTarget() instanceof TargetAnyTarget
|
||||
|| target.getOriginalTarget() instanceof TargetCreatureOrPlayer
|
||||
|| target.getOriginalTarget() instanceof TargetPermanentOrPlayer
|
||||
|| target.getOriginalTarget() instanceof TargetDefender) {
|
||||
|| target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
|
||||
for (String targetDefinition : targets) {
|
||||
if (!targetDefinition.startsWith("targetPlayer=")) {
|
||||
continue;
|
||||
|
@ -2346,7 +2345,6 @@ public class TestPlayer implements Player {
|
|||
|| (target.getOriginalTarget() instanceof TargetPermanentOrPlayer)
|
||||
|| (target.getOriginalTarget() instanceof TargetAnyTarget)
|
||||
|| (target.getOriginalTarget() instanceof TargetCreatureOrPlayer)
|
||||
|| (target.getOriginalTarget() instanceof TargetDefender)
|
||||
|| (target.getOriginalTarget() instanceof TargetPermanentOrSuspendedCard)) {
|
||||
for (String targetDefinition : targets) {
|
||||
if (targetDefinition.startsWith("targetPlayer=")) {
|
||||
|
@ -2376,9 +2374,6 @@ public class TestPlayer implements Player {
|
|||
if (filter instanceof FilterPermanentOrPlayer) {
|
||||
filter = ((FilterPermanentOrPlayer) filter).getPermanentFilter();
|
||||
}
|
||||
if (filter instanceof FilterPlaneswalkerOrPlayer) {
|
||||
filter = ((FilterPlaneswalkerOrPlayer) filter).getFilterPermanent();
|
||||
}
|
||||
if (filter instanceof FilterPermanentOrSuspendedCard) {
|
||||
filter = ((FilterPermanentOrSuspendedCard) filter).getPermanentFilter();
|
||||
}
|
||||
|
|
|
@ -1903,11 +1903,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
addPlayerAction(player, turnNum, PhaseStep.DECLARE_ATTACKERS, "attack:" + attacker + "$defendingPlayer=" + defendingPlayer.getName());
|
||||
}
|
||||
|
||||
public void attack(int turnNum, TestPlayer player, String attacker, String planeswalker) {
|
||||
public void attack(int turnNum, TestPlayer player, String attacker, String permanent) {
|
||||
//Assert.assertNotEquals("", attacker);
|
||||
assertAliaseSupportInActivateCommand(attacker, false); // it uses old special notation like card_name:index
|
||||
assertAliaseSupportInActivateCommand(planeswalker, false);
|
||||
addPlayerAction(player, turnNum, PhaseStep.DECLARE_ATTACKERS, "attack:" + attacker + "$planeswalker=" + planeswalker);
|
||||
assertAliaseSupportInActivateCommand(permanent, false);
|
||||
addPlayerAction(player, turnNum, PhaseStep.DECLARE_ATTACKERS, "attack:" + attacker + "$permanent=" + permanent);
|
||||
}
|
||||
|
||||
public void attackSkip(int turnNum, TestPlayer player) {
|
||||
|
|
|
@ -25,6 +25,7 @@ public final class MtgJsonCard {
|
|||
public String text; // rules splits by \n
|
||||
|
||||
public String loyalty;
|
||||
public String defense;
|
||||
public String power;
|
||||
public String toughness;
|
||||
|
||||
|
|
|
@ -116,6 +116,10 @@ public interface MageObject extends MageItem, Serializable, Copyable<MageObject>
|
|||
|
||||
void setStartingLoyalty(int startingLoyalty);
|
||||
|
||||
int getStartingDefense();
|
||||
|
||||
void setStartingDefense(int startingDefense);
|
||||
|
||||
// memory object copy (not mtg)
|
||||
@Override
|
||||
MageObject copy();
|
||||
|
|
|
@ -40,6 +40,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
protected MageInt power;
|
||||
protected MageInt toughness;
|
||||
protected int startingLoyalty = -1; // -2 means X, -1 means none, 0 and up is normal
|
||||
protected int startingDefense = -1; // -2 means X, -1 means none, 0 and up is normal
|
||||
protected boolean copy;
|
||||
protected MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
|
||||
|
@ -69,6 +70,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
power = object.power.copy();
|
||||
toughness = object.toughness.copy();
|
||||
startingLoyalty = object.startingLoyalty;
|
||||
startingDefense = object.startingDefense;
|
||||
abilities = object.abilities.copy();
|
||||
this.cardType.addAll(object.cardType);
|
||||
this.subtype.copyFrom(object.subtype);
|
||||
|
@ -176,6 +178,16 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
this.startingLoyalty = startingLoyalty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartingDefense() {
|
||||
return startingDefense;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartingDefense(int startingDefense) {
|
||||
this.startingDefense = startingDefense;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return color;
|
||||
|
|
|
@ -2,7 +2,6 @@ package mage.abilities;
|
|||
|
||||
import mage.MageIdentifier;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
|
@ -19,7 +18,6 @@ import mage.abilities.hint.Hint;
|
|||
import mage.abilities.icon.CardIcon;
|
||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.command.Dungeon;
|
||||
|
@ -437,7 +435,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
|
||||
case FLASHBACK:
|
||||
case MADNESS:
|
||||
case DISTURB:
|
||||
case TRANSFORMED:
|
||||
// from Snapcaster Mage:
|
||||
// If you cast a spell from a graveyard using its flashback ability, you can't pay other alternative costs
|
||||
// (such as that of Foil). (2018-12-07)
|
||||
|
|
147
Mage/src/main/java/mage/abilities/common/SiegeAbility.java
Normal file
147
Mage/src/main/java/mage/abilities/common/SiegeAbility.java
Normal file
|
@ -0,0 +1,147 @@
|
|||
package mage.abilities.common;
|
||||
|
||||
import mage.ApprovingObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class SiegeAbility extends StaticAbility {
|
||||
|
||||
public SiegeAbility() {
|
||||
super(Zone.ALL, null);
|
||||
this.addSubAbility(new TransformAbility());
|
||||
this.addSubAbility(new SiegeDefeatedTriggeredAbility());
|
||||
}
|
||||
|
||||
private SiegeAbility(final SiegeAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SiegeAbility copy() {
|
||||
return new SiegeAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "<i>(As a Siege enters, choose an opponent to protect it. You and others " +
|
||||
"can attack it. When it's defeated, exile it, then cast it transformed.)</i>";
|
||||
}
|
||||
}
|
||||
|
||||
class SiegeDefeatedTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
SiegeDefeatedTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new SiegeDefeatedEffect());
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
private SiegeDefeatedTriggeredAbility(final SiegeDefeatedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SiegeDefeatedTriggeredAbility copy() {
|
||||
return new SiegeDefeatedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.COUNTERS_REMOVED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent permanent = getSourcePermanentOrLKI(game);
|
||||
return permanent != null
|
||||
&& permanent.getCounters(game).getCount(CounterType.DEFENSE) == 0
|
||||
&& event.getTargetId().equals(this.getSourceId())
|
||||
&& event.getData().equals("defense") && event.getAmount() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When the last defense counter is removed from this permanent, exile it, " +
|
||||
"then you may cast it transformed without paying its mana cost.";
|
||||
}
|
||||
}
|
||||
|
||||
class SiegeDefeatedEffect extends OneShotEffect {
|
||||
|
||||
SiegeDefeatedEffect() {
|
||||
super(Outcome.Benefit);
|
||||
}
|
||||
|
||||
private SiegeDefeatedEffect(final SiegeDefeatedEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SiegeDefeatedEffect copy() {
|
||||
return new SiegeDefeatedEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (player == null || permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Card card = permanent.getMainCard();
|
||||
player.moveCards(permanent, Zone.EXILED, source, game);
|
||||
if (card == null || card.getSecondFaceSpellAbility() == null) {
|
||||
return true;
|
||||
}
|
||||
game.getState().setValue("PlayFromNotOwnHandZone" + card.getSecondCardFace().getId(), Boolean.TRUE);
|
||||
if (player.cast(card.getSecondFaceSpellAbility(), game, true, new ApprovingObject(source, game))) {
|
||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
||||
game.addEffect(new SiegeTransformEffect().setTargetPointer(new FixedTarget(card, game)), source);
|
||||
}
|
||||
game.getState().setValue("PlayFromNotOwnHandZone" + card.getSecondCardFace().getId(), null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class SiegeTransformEffect extends ContinuousEffectImpl {
|
||||
|
||||
public SiegeTransformEffect() {
|
||||
super(Duration.WhileOnStack, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.BecomeCreature);
|
||||
}
|
||||
|
||||
private SiegeTransformEffect(final SiegeTransformEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SiegeTransformEffect copy() {
|
||||
return new SiegeTransformEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Spell spell = game.getSpell(getTargetPointer().getFirst(game, source));
|
||||
if (spell == null || spell.getCard().getSecondCardFace() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// simulate another side as new card (another code part in spell constructor)
|
||||
TransformAbility.transformCardSpellDynamic(spell, spell.getCard().getSecondCardFace(), game);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -134,6 +134,7 @@ public class CopyEffect extends ContinuousEffectImpl {
|
|||
permanent.getPower().setModifiedBaseValue(copyFromObject.getPower().getModifiedBaseValue());
|
||||
permanent.getToughness().setModifiedBaseValue(copyFromObject.getToughness().getModifiedBaseValue());
|
||||
permanent.setStartingLoyalty(copyFromObject.getStartingLoyalty());
|
||||
permanent.setStartingDefense(copyFromObject.getStartingDefense());
|
||||
if (copyFromObject instanceof Permanent) {
|
||||
Permanent targetPermanent = (Permanent) copyFromObject;
|
||||
permanent.setTransformed(targetPermanent.isTransformed());
|
||||
|
@ -199,8 +200,9 @@ public class CopyEffect extends ContinuousEffectImpl {
|
|||
return applier;
|
||||
}
|
||||
|
||||
public void setApplier(CopyApplier applier) {
|
||||
public CopyEffect setApplier(CopyApplier applier) {
|
||||
this.applier = applier;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public class DisturbAbility extends SpellAbility {
|
|||
this.setCardName(card.getSecondCardFace().getName() + " with Disturb");
|
||||
this.zone = Zone.GRAVEYARD;
|
||||
this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
|
||||
this.spellAbilityCastMode = SpellAbilityCastMode.DISTURB;
|
||||
this.spellAbilityCastMode = SpellAbilityCastMode.TRANSFORMED;
|
||||
|
||||
this.manaCost = manaCost;
|
||||
this.getManaCosts().clear();
|
||||
|
|
|
@ -24,7 +24,7 @@ public class MoreThanMeetsTheEyeAbility extends SpellAbility {
|
|||
// getSecondFaceSpellAbility() already verified that second face exists
|
||||
this.setCardName(card.getSecondCardFace().getName() + " with Disturb");
|
||||
this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
|
||||
this.spellAbilityCastMode = SpellAbilityCastMode.DISTURB;
|
||||
this.spellAbilityCastMode = SpellAbilityCastMode.TRANSFORMED;
|
||||
|
||||
this.manaCost = manaCost;
|
||||
this.getManaCosts().clear();
|
||||
|
|
|
@ -67,6 +67,7 @@ public class TransformAbility extends SimpleStaticAbility {
|
|||
permanent.getPower().setModifiedBaseValue(sourceCard.getPower().getValue());
|
||||
permanent.getToughness().setModifiedBaseValue(sourceCard.getToughness().getValue());
|
||||
permanent.setStartingLoyalty(sourceCard.getStartingLoyalty());
|
||||
permanent.setStartingDefense(sourceCard.getStartingDefense());
|
||||
}
|
||||
|
||||
public static Card transformCardSpellStatic(Card mainSide, Card otherSide, Game game) {
|
||||
|
|
|
@ -614,12 +614,17 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
@Override
|
||||
public final Card getSecondCardFace() {
|
||||
// init card side on first call
|
||||
if (secondSideCardClazz == null && secondSideCard == null) {
|
||||
if (secondSideCardClazz == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (secondSideCard == null) {
|
||||
secondSideCard = initSecondSideCard(secondSideCardClazz);
|
||||
if (secondSideCard != null && secondSideCard.getSpellAbility() != null) {
|
||||
secondSideCard.getSpellAbility().setSourceId(this.getId());
|
||||
secondSideCard.getSpellAbility().setSpellAbilityType(SpellAbilityType.BASE_ALTERNATE);
|
||||
secondSideCard.getSpellAbility().setSpellAbilityCastMode(SpellAbilityCastMode.TRANSFORMED);
|
||||
}
|
||||
}
|
||||
|
||||
return secondSideCard;
|
||||
|
|
|
@ -52,6 +52,8 @@ public class CardInfo {
|
|||
@DatabaseField
|
||||
protected String startingLoyalty;
|
||||
@DatabaseField
|
||||
protected String startingDefense;
|
||||
@DatabaseField
|
||||
protected int manaValue;
|
||||
@DatabaseField(dataType = DataType.ENUM_STRING)
|
||||
protected Rarity rarity;
|
||||
|
@ -226,7 +228,8 @@ public class CardInfo {
|
|||
}
|
||||
|
||||
// Starting loyalty
|
||||
this.startingLoyalty = CardUtil.convertStartingLoyalty(card.getStartingLoyalty());
|
||||
this.startingLoyalty = CardUtil.convertLoyaltyOrDefense(card.getStartingLoyalty());
|
||||
this.startingDefense = CardUtil.convertLoyaltyOrDefense(card.getStartingDefense());
|
||||
}
|
||||
|
||||
public Card getCard() {
|
||||
|
|
|
@ -13,7 +13,7 @@ public enum SpellAbilityCastMode {
|
|||
MADNESS("Madness"),
|
||||
FLASHBACK("Flashback"),
|
||||
BESTOW("Bestow"),
|
||||
DISTURB("Disturb");
|
||||
TRANSFORMED("Transformed");
|
||||
|
||||
private final String text;
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@ public enum SubType {
|
|||
ARCANE("Arcane", SubTypeSet.SpellType),
|
||||
LESSON("Lesson", SubTypeSet.SpellType),
|
||||
TRAP("Trap", SubTypeSet.SpellType),
|
||||
|
||||
// Battle subtypes
|
||||
SIEGE("Siege", SubTypeSet.BattleType),
|
||||
|
||||
// 205.3i: Lands have their own unique set of subtypes; these subtypes are called land types.
|
||||
// Of that list, Forest, Island, Mountain, Plains, and Swamp are the basic land types.
|
||||
FOREST("Forest", SubTypeSet.BasicLandType),
|
||||
|
@ -623,6 +627,8 @@ public enum SubType {
|
|||
return mageObject.isPlaneswalker(game);
|
||||
case SpellType:
|
||||
return mageObject.isInstantOrSorcery(game);
|
||||
case BattleType:
|
||||
return mageObject.isBattle(game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -637,12 +643,10 @@ public enum SubType {
|
|||
|
||||
public static Set<SubType> getPlaneswalkerTypes() {
|
||||
return subTypeSetMap.get(SubTypeSet.PlaneswalkerType);
|
||||
|
||||
}
|
||||
|
||||
public static Set<SubType> getCreatureTypes() {
|
||||
return subTypeSetMap.get(SubTypeSet.CreatureType);
|
||||
|
||||
}
|
||||
|
||||
public static Set<SubType> getBasicLands() {
|
||||
|
@ -653,6 +657,10 @@ public enum SubType {
|
|||
return landTypes;
|
||||
}
|
||||
|
||||
public static Set<SubType> getBattleTypes() {
|
||||
return subTypeSetMap.get(SubTypeSet.BattleType);
|
||||
}
|
||||
|
||||
public static Set<SubType> getBySubTypeSet(SubTypeSet subTypeSet) {
|
||||
return subTypeSetMap.get(subTypeSet);
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue