Merge pull request 'master' (#48) from External/mage:master into master
All checks were successful
/ build_release (push) Successful in 18m43s

Reviewed-on: #48
This commit is contained in:
Failure 2025-11-13 21:47:46 -08:00
commit 4f714203ae
443 changed files with 15065 additions and 2504 deletions

View file

@ -2120,6 +2120,9 @@
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtBackgroundImagePath">
<Properties>
<Property name="toolTipText" type="java.lang.String" value="The selected image will be used as the background picture. Requires client restart to see changes."/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnBrowseBackgroundImage">
<Properties>
@ -2259,16 +2262,13 @@
<SubComponents>
<Component class="javax.swing.JCheckBox" name="cbUseDefaultImageFolder">
<Properties>
<Property name="text" type="java.lang.String" value="Use default location to save images"/>
<Property name="text" type="java.lang.String" value="Use default location to save card images"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseDefaultImageFolderActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtImageFolderPath">
<Properties>
<Property name="toolTipText" type="java.lang.String" value="The selected image will be used as background picture. You have to restart MAGE to view a changed background image."/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnBrowseImageLocation">
<Properties>

View file

@ -2162,6 +2162,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
});
txtBackgroundImagePath.setToolTipText("The selected image will be used as the background picture. Requires client restart to see changes.");
btnBrowseBackgroundImage.setText("Browse...");
btnBrowseBackgroundImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -2261,15 +2263,13 @@ public class PreferencesDialog extends javax.swing.JDialog {
panelCardImages.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Card images"));
cbUseDefaultImageFolder.setText("Use default location to save images");
cbUseDefaultImageFolder.setText("Use default location to save card images");
cbUseDefaultImageFolder.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseDefaultImageFolderActionPerformed(evt);
}
});
txtImageFolderPath.setToolTipText("The selected image will be used as background picture. You have to restart MAGE to view a changed background image.");
btnBrowseImageLocation.setText("Browse...");
btnBrowseImageLocation.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {

View file

@ -1700,7 +1700,7 @@ public class TablesPanel extends javax.swing.JPanel {
MatchOptions options = new MatchOptions(gameName, gameType, multiPlayer);
options.getPlayerTypes().add(PlayerType.HUMAN);
options.getPlayerTypes().add(aiType);
for (int i=2 ; i < numPlayers ; i++) {
for (int i = 2; i < numPlayers; i++) {
options.getPlayerTypes().add(aiType);
}
options.setDeckType("Variant Magic - Freeform Commander");
@ -1719,9 +1719,9 @@ public class TablesPanel extends javax.swing.JPanel {
table = SessionHandler.createTable(roomId, options);
SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, testDeck, "");
SessionHandler.joinTable(roomId, table.getTableId(), "Computer", aiType, 1, testDeck, "");
for (int i=2 ; i < numPlayers ; i++) {
SessionHandler.joinTable(roomId, table.getTableId(), "Computer" + i, aiType, 1, testDeck, "");
SessionHandler.joinTable(roomId, table.getTableId(), "Computer" + (multiPlayer ? " 2" : ""), aiType, 1, testDeck, "");
for (int i = 2; i < numPlayers; i++) {
SessionHandler.joinTable(roomId, table.getTableId(), "Computer " + (i + 1), aiType, 1, testDeck, "");
}
SessionHandler.startMatch(roomId, table.getTableId());
} catch (HeadlessException ex) {

View file

@ -618,6 +618,7 @@ public class ScryfallImageSupportCards {
add("EOS"); // Edge of Eternities: Stellar Sights
add("SPM"); // Marvel's Spider-Man
add("SPE"); // Marvel's Spider-Man Eternal
add("LMAR"); // Marvel Legends Series Inserts
add("MAR"); // Marvel Universe
add("TLA"); // Avatar: The Last Airbender
add("TLE"); // Avatar: The Last Airbender Eternal
@ -727,6 +728,7 @@ public class ScryfallImageSupportCards {
put("SLD/Sol Ring/1512b", "https://api.scryfall.com/cards/sld/1512/en?format=image&face=back");
put("SLD/Steely Resolve/1326b", "https://api.scryfall.com/cards/sld/1326/en?format=image&face=back");
put("SLD/Stitch in Time/382b", "https://api.scryfall.com/cards/sld/382/en?format=image&face=back");
put("SLD/Teferi's Ageless Insight/2214b", "https://api.scryfall.com/cards/sld/2214/en?format=image&face=back");
put("SLD/Terror/750b", "https://api.scryfall.com/cards/sld/750/en?format=image&face=back");
put("SLD/Tuvasa the Sunlit/1328b", "https://api.scryfall.com/cards/sld/1328/en?format=image&face=back");
put("SLD/Ulamog, the Ceaseless Hunger/1122b", "https://api.scryfall.com/cards/sld/1122/en?format=image&face=back");

View file

@ -817,10 +817,13 @@ public class ScryfallImageSupportTokens {
// SLD
put("SLD/Angel", "https://api.scryfall.com/cards/sld/1340?format=image");
put("SLD/Blood", "https://api.scryfall.com/cards/sld/2180?format=image");
put("SLD/Cat/1", "https://api.scryfall.com/cards/sld/1517?format=image");
put("SLD/Cat/2", "https://api.scryfall.com/cards/sld/27?format=image");
put("SLD/Cat/3", "https://api.scryfall.com/cards/sld/28?format=image");
put("SLD/Clue", "https://api.scryfall.com/cards/sld/348/en?format=image");
put("SLD/Cordyceps Infected/1", "https://api.scryfall.com/cards/sld/2201?format=image");
put("SLD/Cordyceps Infected/2", "https://api.scryfall.com/cards/sld/2206?format=image");
put("SLD/Dog", "https://api.scryfall.com/cards/sld/1516?format=image");
put("SLD/Egg", "https://api.scryfall.com/cards/sld/1398?format=image");
put("SLD/Faerie Rogue/1", "https://api.scryfall.com/cards/sld/13/en?format=image");
@ -2828,6 +2831,34 @@ public class ScryfallImageSupportTokens {
put("SPM/Spider", "https://api.scryfall.com/cards/tspm/3?format=image");
put("SPM/Treasure", "https://api.scryfall.com/cards/tspm/7?format=image");
// TLA
put("TLA/Ally/1", "https://api.scryfall.com/cards/ttla/4/?format=image");
put("TLA/Ally/2", "https://api.scryfall.com/cards/ttla/5/?format=image");
put("TLA/Ally/3", "https://api.scryfall.com/cards/ttla/6/?format=image");
put("TLA/Ally/4", "https://api.scryfall.com/cards/ttla/7/?format=image");
put("TLA/Ally/5", "https://api.scryfall.com/cards/ttla/8/?format=image");
put("TLA/Ballistic Boulder", "https://api.scryfall.com/cards/ttla/13/?format=image");
put("TLA/Bear", "https://api.scryfall.com/cards/ttla/12/?format=image");
put("TLA/Clue/1", "https://api.scryfall.com/cards/ttla/14/?format=image");
put("TLA/Clue/2", "https://api.scryfall.com/cards/ttla/15/?format=image");
put("TLA/Clue/3", "https://api.scryfall.com/cards/ttla/16/?format=image");
put("TLA/Clue/4", "https://api.scryfall.com/cards/ttla/17/?format=image");
put("TLA/Clue/5", "https://api.scryfall.com/cards/ttla/18/?format=image");
put("TLA/Food/1", "https://api.scryfall.com/cards/ttla/19/?format=image");
put("TLA/Food/2", "https://api.scryfall.com/cards/ttla/20/?format=image");
put("TLA/Food/3", "https://api.scryfall.com/cards/ttla/21/?format=image");
put("TLA/Monk", "https://api.scryfall.com/cards/ttla/10/?format=image");
put("TLA/Soldier", "https://api.scryfall.com/cards/ttla/11/?format=image");
put("TLA/Spirit", "https://api.scryfall.com/cards/ttla/3/?format=image");
put("TLA/Treasure", "https://api.scryfall.com/cards/ttla/22?format=image");
// TLE
put("TLE/Marit Lage", "https://api.scryfall.com/cards/ttle/1/?format=image");
put("TLE/Soldier", "https://api.scryfall.com/cards/ttle/2?format=image");
// TMT
put("TMT/Mutagen", "https://api.scryfall.com/cards/ttmt/9?format=image");
// JVC
put("JVC/Elemental Shaman", "https://api.scryfall.com/cards/tjvc/4?format=image");

View file

@ -82,7 +82,7 @@ public class ThemePluginImpl implements ThemePlugin {
}
if (ui.containsKey("gamePanel") && ui.containsKey("jLayeredPane")) {
ImagePanel bgPanel = new ImagePanel(backgroundImage, ImagePanelStyle.TILED);
ImagePanel bgPanel = new ImagePanel(backgroundImage, ImagePanelStyle.COVER);
// TODO: research - is all components used? And why it make transparent?
unsetOpaque(ui.get("splitChatAndLogs"));

View file

@ -78,6 +78,9 @@ public class ImagePanel extends JPanel {
case ACTUAL:
drawActual(g);
break;
case COVER:
drawCover(g);
break;
}
}
@ -99,4 +102,25 @@ public class ImagePanel extends JPanel {
float y = (d.height - image.getHeight(null)) * alignmentY;
g.drawImage(image, (int) x, (int) y, this);
}
private void drawCover(Graphics g) {
Dimension d = getSize();
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
// Calculate scale to cover the entire panel while maintaining aspect ratio
double scaleX = (double) d.width / imageWidth;
double scaleY = (double) d.height / imageHeight;
double scale = Math.max(scaleX, scaleY);
// Calculate the scaled dimensions
int scaledWidth = (int) (imageWidth * scale);
int scaledHeight = (int) (imageHeight * scale);
// Center the image
int x = (d.width - scaledWidth) / 2;
int y = (d.height - scaledHeight) / 2;
g.drawImage(image, x, y, scaledWidth, scaledHeight, null);
}
}

View file

@ -4,5 +4,5 @@ package mage.components;
* Created by IGOUDT on 7-3-2017.
*/
public enum ImagePanelStyle {
TILED, SCALED, ACTUAL
TILED, SCALED, ACTUAL, COVER
}

View file

@ -601,14 +601,13 @@ public final class SystemUtil {
continue;
}
Optional<Player> playerOptional = findPlayer(game, command.player);
if (!playerOptional.isPresent()) {
Player player = findPlayer(game, command.player, feedbackPlayer);
if (player == null) {
String mes = String.format("Unknown player: %s", line);
errorsList.add(mes);
logger.warn(mes);
continue;
}
Player player = playerOptional.get();
// SPECIAL token/emblem call (without SET name)
if ("token".equalsIgnoreCase(command.zone)) {
@ -860,17 +859,54 @@ public final class SystemUtil {
return false;
}
/**
* Find player by name.
*
* @param game
* @param name
* @return
*/
private static Optional<Player> findPlayer(Game game, String name) {
return game.getPlayers().values().stream()
.filter(player -> player.getName().equals(name)).findFirst();
private static Player findPlayer(Game game, String needName, Player feedbackPlayer) {
// real names
Player res = game.getPlayerList().stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.filter(player -> player.getName().equals(needName))
.findFirst()
.orElse(null);
// test names - cheat commands will be compatible in both modes (quick test and normal)
if (res == null) {
switch (needName.toLowerCase(Locale.ENGLISH)) {
case "me":
case "human":
case "human 1":
res = feedbackPlayer;
break;
case "opponent":
case "opponent 1":
case "computer":
case "computer 1": // multiplayer game uses Computer 2+ naming
case "ai":
case "ai 1":
// try AI
res = game.getPlayerList().stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.filter(Player::isInGame)
.filter(Player::isComputer)
.findFirst()
.orElse(null);
if (res == null) {
// try opponent (human only games)
res = game.getOpponents(feedbackPlayer.getId(), true).stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.filter(Player::isInGame)
.findFirst()
.orElse(null);
}
break;
default:
// raise error message due unknown player name
break;
}
}
return res;
}
public static String sanitize(String input) {

View file

@ -27,6 +27,7 @@ import mage.counters.Counter;
import mage.counters.CounterType;
import mage.designations.Designation;
import mage.filter.FilterMana;
import mage.game.ControllableOrOwnerable;
import mage.game.Game;
import mage.game.command.Dungeon;
import mage.game.command.Emblem;
@ -764,7 +765,11 @@ public class CardView extends SimpleCardView {
String info;
MageObject targetObject = game.getObject(t);
if (targetObject != null) {
info = targetObject.getIdName();
Player player = null;
if (targetObject instanceof ControllableOrOwnerable) {
player = game.getPlayer(((ControllableOrOwnerable) targetObject).getControllerOrOwnerId());
}
info = (player == null ? "" : player.getName() + ": ") + targetObject.getIdName();
} else {
Player targetPlayer = game.getPlayer(t);
if (targetPlayer != null) {

View file

@ -44,7 +44,6 @@ public class DuelCommander extends Commander {
banned.add("Library of Alexandria");
banned.add("Lion's Eye Diamond");
banned.add("Lotus Petal");
banned.add("Loyal Retainers");
banned.add("Lutri, the Spellchaser");
banned.add("Maddening Hex");
banned.add("Mana Crypt");
@ -93,8 +92,6 @@ public class DuelCommander extends Commander {
bannedCommander.add("Ajani, Nacatl Pariah");
bannedCommander.add("Arahbo, Roar of the World");
bannedCommander.add("Asmoranomardicadaistinaculdacar");
bannedCommander.add("Baral, Chief of Compliance");
bannedCommander.add("Breya, Etherium Shaper");
bannedCommander.add("Derevi, Empyrial Tactician");
bannedCommander.add("Dihada, Binder of Wills");
@ -102,7 +99,6 @@ public class DuelCommander extends Commander {
bannedCommander.add("Edric, Spymaster of Trest");
bannedCommander.add("Emry, Lurker of the Loch");
bannedCommander.add("Eris, Roar of the Storm");
bannedCommander.add("Esior, Wardwing Familiar");
bannedCommander.add("Ezio Auditore da Firenze");
bannedCommander.add("Geist of Saint Traft");
bannedCommander.add("Inalla, Archmage Ritualist");
@ -116,7 +112,6 @@ public class DuelCommander extends Commander {
bannedCommander.add("Omnath, Locus of Creation");
bannedCommander.add("Prime Speaker Vannifar");
bannedCommander.add("Raffine, Scheming Seer");
bannedCommander.add("Rofellos, Llanowar Emissary");
bannedCommander.add("Shorikai, Genesis Engine");
bannedCommander.add("Tamiyo, Inquisitive Student");
bannedCommander.add("Tasigur, the Golden Fang");

View file

@ -32,6 +32,7 @@ public class Legacy extends Constructed {
banned.add("Dig Through Time");
banned.add("Dreadhorde Arcanist");
banned.add("Earthcraft");
banned.add("Entomb");
banned.add("Fastbond");
banned.add("Flash");
banned.add("Frantic Search");
@ -56,6 +57,7 @@ public class Legacy extends Constructed {
banned.add("Mox Ruby");
banned.add("Mox Sapphire");
banned.add("Mystical Tutor");
banned.add("Nadu, Winged Wisdom");
banned.add("Necropotence");
banned.add("Oath of Druids");
banned.add("Oko, Thief of Crowns");

View file

@ -46,6 +46,7 @@ public class Pauper extends Constructed {
banned.add("Gitaxian Probe");
banned.add("Grapeshot");
banned.add("Gush");
banned.add("High Tide");
banned.add("Hymn to Tourach");
banned.add("Invigorate");
banned.add("Kuldotha Rebirth");

View file

@ -30,6 +30,7 @@ public class Pioneer extends Constructed {
banned.add("Field of the Dead");
banned.add("Flooded Strand");
banned.add("Geological Appraiser");
banned.add("Heartfire Hero");
banned.add("Inverter of Truth");
banned.add("Jegantha, the Wellspring");
banned.add("Karn, the Great Creator");

View file

@ -24,8 +24,11 @@ public class Standard extends Constructed {
banned.add("Heartfire Hero");
banned.add("Hopeless Nightmare");
banned.add("Monstrous Rage");
banned.add("Proft's Eidetic Memory");
banned.add("Screaming Nemesis");
banned.add("This Town Ain't Big Enough");
banned.add("Up the Beanstalk");
banned.add("Vivi Ornitier");
}
static List<String> makeLegalSets() {

View file

@ -0,0 +1,58 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.LessonsInGraveCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
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 AangALotToLearn extends CardImpl {
public AangALotToLearn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G/W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.AVATAR);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Aang has vigilance as long as there's a Lesson card in your graveyard.
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield),
LessonsInGraveCondition.ONE, "{this} has vigilance as long as there's a Lesson card in your graveyard"
)).addHint(LessonsInGraveCondition.getHint()));
// Whenever another creature you control dies, put a +1/+1 counter on Aang.
this.addAbility(new DiesCreatureTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
false, StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL
));
}
private AangALotToLearn(final AangALotToLearn card) {
super(card);
}
@Override
public AangALotToLearn copy() {
return new AangALotToLearn(this);
}
}

View file

@ -0,0 +1,60 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.TrampleAbility;
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.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AangAndLaOceansFury extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("tapped creature you control");
static {
filter.add(TappedPredicate.TAPPED);
}
public AangAndLaOceansFury(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.AVATAR);
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
this.nightCard = true;
// Reach
this.addAbility(ReachAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever Aang and La attack, put a +1/+1 counter on each tapped creature you control.
this.addAbility(new AttacksTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter)));
}
private AangAndLaOceansFury(final AangAndLaOceansFury card) {
super(card);
}
@Override
public AangAndLaOceansFury copy() {
return new AangAndLaOceansFury(this);
}
}

View file

@ -0,0 +1,67 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AangAtTheCrossroads extends CardImpl {
private static final FilterCard filter = new FilterCreatureCard("creature card with mana value 4 or less");
static {
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 5));
}
public AangAtTheCrossroads(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{W}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.AVATAR);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.secondSideCardClazz = mage.cards.a.AangDestinedSavior.class;
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Aang enters, look at the top five cards of your library. You may put a creature card with mana value 4 or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
5, 1, filter, PutCards.BATTLEFIELD, PutCards.BOTTOM_RANDOM
)));
// When another creature you control leaves the battlefield, transform Aang at the beginning of the next upkeep.
this.addAbility(new TransformAbility());
this.addAbility(new LeavesBattlefieldAllTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(
new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new TransformSourceEffect())
).setText("transform {this} at the beginning of the next upkeep"), StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL));
}
private AangAtTheCrossroads(final AangAtTheCrossroads card) {
super(card);
}
@Override
public AangAtTheCrossroads copy() {
return new AangAtTheCrossroads(this);
}
}

View file

@ -0,0 +1,66 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.target.common.TargetControlledLandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AangDestinedSavior extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("land creatures");
static {
filter.add(CardType.LAND.getPredicate());
filter.add(CardType.CREATURE.getPredicate());
}
public AangDestinedSavior(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.AVATAR);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Land creatures you control have vigilance.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, filter
)));
// At the beginning of combat on your turn, earthbend 2.
Ability ability = new BeginningOfCombatTriggeredAbility(new EarthbendTargetEffect(2));
ability.addTarget(new TargetControlledLandPermanent());
this.addAbility(ability);
}
private AangDestinedSavior(final AangDestinedSavior card) {
super(card);
}
@Override
public AangDestinedSavior copy() {
return new AangDestinedSavior(this);
}
}

View file

@ -0,0 +1,71 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.WaterbendCost;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.keyword.AirbendTargetEffect;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.common.FilterSpellOrPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetSpellOrPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AangSwiftSavior extends CardImpl {
private static final FilterSpellOrPermanent filter = new FilterSpellOrPermanent("other target creature or spell");
static {
filter.getPermanentFilter().add(CardType.CREATURE.getPredicate());
filter.getPermanentFilter().add(AnotherPredicate.instance);
}
public AangSwiftSavior(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.AVATAR);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
this.secondSideCardClazz = mage.cards.a.AangAndLaOceansFury.class;
// Flash
this.addAbility(FlashAbility.getInstance());
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Aang enters, airbend up to one other target creature or spell.
Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect());
ability.addTarget(new TargetSpellOrPermanent(0, 1, filter, false));
this.addAbility(ability);
// Waterbend {8}: Transform Aang.
this.addAbility(new TransformAbility());
this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new WaterbendCost(8)));
}
private AangSwiftSavior(final AangSwiftSavior card) {
super(card);
}
@Override
public AangSwiftSavior copy() {
return new AangSwiftSavior(this);
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedUnlessAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.YouControlABasicLandCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AbandonedAirTemple extends CardImpl {
public AbandonedAirTemple(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// This land enters tapped unless you control a basic land.
this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlABasicLandCondition.instance)
.addHint(YouControlABasicLandCondition.getHint()));
// {T}: Add {W}.
this.addAbility(new WhiteManaAbility());
// {3}{W}, {T}: Put a +1/+1 counter on each creature you control.
Ability ability = new SimpleActivatedAbility(new AddCountersAllEffect(
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
), new ManaCostsImpl<>("{3}{W}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private AbandonedAirTemple(final AbandonedAirTemple card) {
super(card);
}
@Override
public AbandonedAirTemple copy() {
return new AbandonedAirTemple(this);
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.a;
import mage.abilities.condition.common.LessonsInGraveCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
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 java.util.UUID;
/**
* @author TheElk801
*/
public final class AccumulateWisdom extends CardImpl {
public AccumulateWisdom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
this.subtype.add(SubType.LESSON);
// Look at the top three cards of your library. Put one of those cards into your hand and the rest on the bottom of your library in any order. Put each of those cards into your hand instead if there are three or more Lesson cards in your graveyard.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new LookLibraryAndPickControllerEffect(3, 3, PutCards.HAND, PutCards.BOTTOM_ANY),
new LookLibraryAndPickControllerEffect(3, 1, PutCards.HAND, PutCards.BOTTOM_ANY),
LessonsInGraveCondition.THREE, "look at the top three cards of your library. " +
"Put one of those cards into your hand and the rest on the bottom of your library in any order. " +
"Put each of those cards into your hand instead if there are three or more Lesson cards in your graveyard"
));
this.getSpellAbility().addHint(LessonsInGraveCondition.getHint());
}
private AccumulateWisdom(final AccumulateWisdom card) {
super(card);
}
@Override
public AccumulateWisdom copy() {
return new AccumulateWisdom(this);
}
}

View file

@ -2,16 +2,14 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.PreventionEffectData;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.PreventDamageEvent;
import mage.game.events.PreventedDamageEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
@ -46,16 +44,14 @@ public final class AcolytesReward extends CardImpl {
class AcolytesRewardEffect extends PreventionEffectImpl {
protected int amount = 0;
AcolytesRewardEffect() {
super(Duration.EndOfTurn);
super(Duration.EndOfTurn, 0, false, true, DevotionCount.W);
staticText = "Prevent the next X damage that would be dealt to target creature this turn, where X is your devotion to white. If damage is prevented this way, {this} deals that much damage to any target";
}
private AcolytesRewardEffect(final AcolytesRewardEffect effect) {
super(effect);
this.amount = effect.amount;
}
@Override
@ -63,64 +59,25 @@ class AcolytesRewardEffect extends PreventionEffectImpl {
return new AcolytesRewardEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
amount = DevotionCount.W.calculate(game, source, this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
boolean result = false;
int toPrevent = amount;
if (event.getAmount() < this.amount) {
toPrevent = event.getAmount();
amount -= event.getAmount();
} else {
amount = 0;
PreventionEffectData preventionData = preventDamageAction(event, source, game);
if (preventionData.getPreventedDamage() > 0) {
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
if (targetCreature != null) {
targetCreature.damage(preventionData.getPreventedDamage(), source.getSourceId(), source, game, false, true);
}
GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), toPrevent, ((DamageEvent) event).isCombatDamage());
if (game.replaceEvent(preventEvent)) {
return result;
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetCreature != null) {
targetPlayer.damage(preventionData.getPreventedDamage(), source.getSourceId(), source, game, false, true);
}
Permanent targetCreature = game.getPermanent(event.getTargetId());
if (targetCreature == null) {
return result;
}
if (amount == 0) {
this.used = true;
this.discard();
}
if (event.getAmount() >= toPrevent) {
event.setAmount(event.getAmount() - toPrevent);
} else {
event.setAmount(0);
result = true;
}
if (toPrevent == 0) {
return result;
}
game.informPlayers("Acolyte's Reward prevented " + toPrevent + " to " + targetCreature.getName());
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), toPrevent));
Player targetPlayer = game.getPlayer(source.getTargets().get(1).getFirstTarget());
if (targetPlayer != null) {
targetPlayer.damage(toPrevent, source.getSourceId(), source, game);
game.informPlayers("Acolyte's Reward deals " + toPrevent + " damage to " + targetPlayer.getLogName());
return result;
}
Permanent targetDamageCreature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (targetDamageCreature == null) {
return result;
}
targetDamageCreature.damage(toPrevent, source.getSourceId(), source, game, false, true);
game.informPlayers("Acolyte's Reward deals " + toPrevent + " damage to " + targetDamageCreature.getName());
return result;
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return !this.used && super.applies(event, source, game) && event.getTargetId().equals(source.getFirstTarget());
return super.applies(event, source, game) && event.getTargetId().equals(source.getFirstTarget());
}
}

View file

@ -0,0 +1,48 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedUnlessAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.YouControlABasicLandCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AgnaQela extends CardImpl {
public AgnaQela(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// This land enters tapped unless you control a basic land.
this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlABasicLandCondition.instance)
.addHint(YouControlABasicLandCondition.getHint()));
// {T}: Add {U}.
this.addAbility(new BlueManaAbility());
// {2}{U}, {T}: Draw a card, then discard a card.
Ability ability = new SimpleActivatedAbility(
new DrawDiscardControllerEffect(1, 1), new ManaCostsImpl<>("{2}{U}")
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private AgnaQela(final AgnaQela card) {
super(card);
}
@Override
public AgnaQela copy() {
return new AgnaQela(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.a;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.StaticFilters;
import mage.game.permanent.token.ClueArtifactToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AirNomadLegacy extends CardImpl {
public AirNomadLegacy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{U}");
// When this enchantment enters, create a Clue token.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ClueArtifactToken())));
// Creatures you control with flying get +1/+1.
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
1, 1, Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURE_FLYING
).setText("creatures you control with flying get +1/+1")));
}
private AirNomadLegacy(final AirNomadLegacy card) {
super(card);
}
@Override
public AirNomadLegacy copy() {
return new AirNomadLegacy(this);
}
}

View file

@ -0,0 +1,51 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.condition.Condition;
import mage.abilities.condition.InvertCondition;
import mage.abilities.condition.common.AttackedThisTurnSourceCondition;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AirNomadStudent extends CardImpl {
private static final Condition condition = new InvertCondition(
AttackedThisTurnSourceCondition.instance, "{this} didn't attack this turn"
);
public AirNomadStudent(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MONK);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// At the beginning of your end step, if this creature didn't attack this turn, put a +1/+1 counter on it.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())
.setText("put a +1/+1 counter on it")).withInterveningIf(condition));
}
private AirNomadStudent(final AirNomadStudent card) {
super(card);
}
@Override
public AirNomadStudent copy() {
return new AirNomadStudent(this);
}
}

View file

@ -0,0 +1,59 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.effects.common.ExileThenReturnTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.keyword.AirbendTargetEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AirbenderAscension extends CardImpl {
private static final Condition condition = new SourceHasCounterCondition(CounterType.QUEST, 4);
public AirbenderAscension(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
// When this enchantment enters, airbend up to one target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect());
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability);
// Whenever a creature you control enters, put a quest counter on this enchantment.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
new AddCountersSourceEffect(CounterType.QUEST.createInstance()),
StaticFilters.FILTER_CONTROLLED_CREATURE
));
// At the beginning of your end step, if this enchantment has four or more quest counters on it, exile up to one target creature you control, then return it to the battlefield under its owner's control.
ability = new BeginningOfEndStepTriggeredAbility(
new ExileThenReturnTargetEffect(false, false)
).withInterveningIf(condition);
ability.addTarget(new TargetControlledCreaturePermanent(0, 1));
this.addAbility(ability);
}
private AirbenderAscension(final AirbenderAscension card) {
super(card);
}
@Override
public AirbenderAscension copy() {
return new AirbenderAscension(this);
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.a;
import mage.abilities.Mode;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.keyword.AirbendTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetAttackingCreature;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AirbendersReversal extends CardImpl {
public AirbendersReversal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
this.subtype.add(SubType.LESSON);
// Choose one --
// * Destroy target attacking creature.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetAttackingCreature());
// * Airbend target creature you control.
this.getSpellAbility().addMode(new Mode(new AirbendTargetEffect())
.addTarget(new TargetControlledCreaturePermanent()));
}
private AirbendersReversal(final AirbendersReversal card) {
super(card);
}
@Override
public AirbendersReversal copy() {
return new AirbendersReversal(this);
}
}

View file

@ -0,0 +1,48 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AirshipEngineRoom extends CardImpl {
public AirshipEngineRoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// This land enters tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {U} or {R}.
this.addAbility(new BlueManaAbility());
this.addAbility(new RedManaAbility());
// {4}, {T}, Sacrifice this land: Draw a card.
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(4));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
}
private AirshipEngineRoom(final AirshipEngineRoom card) {
super(card);
}
@Override
public AirshipEngineRoom copy() {
return new AirshipEngineRoom(this);
}
}

View file

@ -0,0 +1,39 @@
package mage.cards.a;
import mage.abilities.effects.common.TargetsDamageTargetsEffect;
import mage.abilities.keyword.AffinityAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AffinityType;
import mage.constants.CardType;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AlliesAtLast extends CardImpl {
public AlliesAtLast(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
// Affinity for Allies
this.addAbility(new AffinityAbility(AffinityType.ALLIES));
// Up to two target creatures you control each deal damage equal to their power to target creature an opponent controls.
this.getSpellAbility().addEffect(new TargetsDamageTargetsEffect(true));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, 2).setTargetTag(1));
this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent().setTargetTag(3));
}
private AlliesAtLast(final AlliesAtLast card) {
super(card);
}
@Override
public AlliesAtLast copy() {
return new AlliesAtLast(this);
}
}

View file

@ -10,8 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -23,12 +22,6 @@ import java.util.UUID;
*/
public final class AmarethTheLustrous extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another permanent");
static {
filter.add(AnotherPredicate.instance);
}
public AmarethTheLustrous(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{W}{U}");
@ -41,7 +34,9 @@ public final class AmarethTheLustrous extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever another permanent you control enters, look at the top card of your library. If it shares a card type with that permanent, you may reveal that card and put it into your hand.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new AmarethTheLustrousEffect(), filter));
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
new AmarethTheLustrousEffect(), StaticFilters.FILTER_ANOTHER_PERMANENT
));
}
private AmarethTheLustrous(final AmarethTheLustrous card) {

View file

@ -2,17 +2,15 @@ package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.OneShotNonTargetEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
@ -26,7 +24,9 @@ public final class AnotherChance extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}");
// You may mill two cards. Then return up to two creature cards from your graveyard to your hand.
this.getSpellAbility().addEffect(new AnotherChanceEffect());
this.getSpellAbility().addEffect(new AnotherChanceMillEffect());
this.getSpellAbility().addEffect(new OneShotNonTargetEffect(new ReturnFromGraveyardToHandTargetEffect().setText("Then return up to two creature cards from your graveyard to your hand."),
new TargetCardInYourGraveyard(0, 2, StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD, true)).withTargetDescription("up to two creature cards").concatBy("Then "));
}
private AnotherChance(final AnotherChance card) {
@ -39,23 +39,20 @@ public final class AnotherChance extends CardImpl {
}
}
/**
* Inspired by {@link mage.cards.u.UnsealTheNecropolis}
*/
class AnotherChanceEffect extends OneShotEffect {
class AnotherChanceMillEffect extends OneShotEffect {
AnotherChanceEffect() {
AnotherChanceMillEffect() {
super(Outcome.Benefit);
staticText = "You may mill two cards. Then return up to two creature cards from your graveyard to your hand";
staticText = "You may mill two cards.";
}
private AnotherChanceEffect(final AnotherChanceEffect effect) {
private AnotherChanceMillEffect(final AnotherChanceMillEffect effect) {
super(effect);
}
@Override
public AnotherChanceEffect copy() {
return new AnotherChanceEffect(this);
public AnotherChanceMillEffect copy() {
return new AnotherChanceMillEffect(this);
}
@Override
@ -68,18 +65,6 @@ class AnotherChanceEffect extends OneShotEffect {
if (player.chooseUse(outcome, "Mill two cards?", source, game)) {
player.millCards(2, source, game);
}
// Make sure the mill has been processed.
game.processAction();
TargetCard target = new TargetCardInYourGraveyard(
0, 2, StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD, true
);
player.choose(outcome, target, source, game);
Cards cards = new CardsImpl(target.getTargets());
if (!cards.isEmpty()) {
player.moveCards(cards, Zone.HAND, source, game);
}
return true;
}
}

View file

@ -0,0 +1,55 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.keyword.AirbendTargetEffect;
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.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AppaLoyalSkyBison extends CardImpl {
public AppaLoyalSkyBison(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.BISON);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Appa enters or attacks, choose one --
// * Target creature you control gains flying until end of turn.
Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance()));
ability.addTarget(new TargetControlledCreaturePermanent());
// * Airbend another target nonland permanent you control..
ability.addMode(new Mode(new AirbendTargetEffect()).addTarget(new TargetNonlandPermanent()));
this.addAbility(ability);
}
private AppaLoyalSkyBison(final AppaLoyalSkyBison card) {
super(card);
}
@Override
public AppaLoyalSkyBison copy() {
return new AppaLoyalSkyBison(this);
}
}

View file

@ -1,21 +1,14 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
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.TargetPermanentOrPlayer;
import java.io.ObjectStreamException;
import java.util.UUID;
/**
@ -34,10 +27,12 @@ public final class ArcTrail extends CardImpl {
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
this.getSpellAbility().addEffect(ArcTrailEffect.getInstance());
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter1).setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter2).setTargetTag(2));
// Arc Trail deals 2 damage to any target and 1 damage to another target
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(2, 1));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter1)
.withChooseHint("to deal 2 damage").setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanentOrPlayer(filter2)
.withChooseHint("to deal 1 damage").setTargetTag(2));
}
private ArcTrail(final ArcTrail card) {
@ -50,54 +45,3 @@ public final class ArcTrail extends CardImpl {
}
}
class ArcTrailEffect extends OneShotEffect {
private static final ArcTrailEffect instance = new ArcTrailEffect();
private Object readResolve() throws ObjectStreamException {
return instance;
}
public static ArcTrailEffect getInstance() {
return instance;
}
private ArcTrailEffect() {
super(Outcome.Damage);
staticText = "{this} deals 2 damage to any target and 1 damage to another target";
}
@Override
public boolean apply(Game game, Ability source) {
boolean applied = false;
boolean twoDamageDone = false;
int damage = 2;
for (Target target : source.getTargets()) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (twoDamageDone) {
damage = 1;
}
if (permanent != null) {
applied |= (permanent.damage(damage, source.getSourceId(), source, game, false, true) > 0);
}
Player player = game.getPlayer(target.getFirstTarget());
if (player != null) {
applied |= (player.damage(damage, source.getSourceId(), source, game) > 0);
}
twoDamageDone = true;
}
return applied;
}
@Override
public ArcTrailEffect copy() {
return instance;
}
}

View file

@ -1,16 +1,14 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BlocksOrBlockedByCreatureSourceTriggeredAbility;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
@ -25,9 +23,8 @@ public final class AssembledAlphas extends CardImpl {
this.toughness = new MageInt(5);
// Whenever Assembled Alphas blocks or becomes blocked by a creature, Assembled Alphas deals 3 damage to that creature and 3 damage to that creature's controller.
Ability ability = new BlocksOrBlockedByCreatureSourceTriggeredAbility(new DamageTargetEffect(3, true, "that creature"));
ability.addEffect(new DamageTargetControllerEffect(3).setText("and 3 damage to that creature's controller"));
this.addAbility(ability);
this.addAbility(new BlocksOrBlockedByCreatureSourceTriggeredAbility(
new DamageTargetAndTargetControllerEffect(3, 3)));
}
private AssembledAlphas(final AssembledAlphas card) {

View file

@ -65,7 +65,7 @@ public final class AvalancheOfSector7 extends CardImpl {
class AvalancheOfSector7TriggeredAbility extends TriggeredAbilityImpl {
AvalancheOfSector7TriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(1, true, "that player", true));
super(Zone.BATTLEFIELD, new DamageTargetEffect(1, true, "that player"));
setTriggerPhrase("Whenever an opponent activates an ability of an artifact they control, ");
}

View file

@ -0,0 +1,108 @@
package mage.cards.a;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AvatarRokuFirebender extends CardImpl {
public AvatarRokuFirebender(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Whenever a player attacks, add six {R}. Until end of combat, you don't lose this mana as steps end.
this.addAbility(new AvatarRokuFirebenderTriggeredAbility());
// {R}{R}{R}: Target creature gets +3/+0 until end of turn.
Ability ability = new SimpleActivatedAbility(
new BoostTargetEffect(3, 0), new ManaCostsImpl<>("{R}{R}{R}")
);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
private AvatarRokuFirebender(final AvatarRokuFirebender card) {
super(card);
}
@Override
public AvatarRokuFirebender copy() {
return new AvatarRokuFirebender(this);
}
}
class AvatarRokuFirebenderTriggeredAbility extends TriggeredAbilityImpl {
AvatarRokuFirebenderTriggeredAbility() {
super(Zone.BATTLEFIELD, new AvatarRokuFirebenderEffect());
setTriggerPhrase("Whenever a player attacks, ");
}
private AvatarRokuFirebenderTriggeredAbility(final AvatarRokuFirebenderTriggeredAbility ability) {
super(ability);
}
@Override
public AvatarRokuFirebenderTriggeredAbility copy() {
return new AvatarRokuFirebenderTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return !game.getCombat().getAttackers().isEmpty();
}
}
class AvatarRokuFirebenderEffect extends OneShotEffect {
AvatarRokuFirebenderEffect() {
super(Outcome.Benefit);
staticText = "add six {R}. Until end of combat, you don't lose this mana as steps end";
}
private AvatarRokuFirebenderEffect(final AvatarRokuFirebenderEffect effect) {
super(effect);
}
@Override
public AvatarRokuFirebenderEffect copy() {
return new AvatarRokuFirebenderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
player.getManaPool().addMana(Mana.RedMana(6), game, source, Duration.EndOfCombat);
return true;
}
}

View file

@ -0,0 +1,114 @@
package mage.cards.a;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileSpellEffect;
import mage.abilities.effects.keyword.AirbendTargetEffect;
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.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTargets;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AvatarsWrath extends CardImpl {
public AvatarsWrath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}{W}");
// Choose up to one target creature, then airbend all other creatures.
this.getSpellAbility().addEffect(new AvatarsWrathAirbendEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1));
// Until your next turn, your opponents can't cast spells from anywhere other than their hand.
this.getSpellAbility().addEffect(new AvatarsWrathRuleEffect());
// Exile Avatar's Wrath.
this.getSpellAbility().addEffect(new ExileSpellEffect().concatBy("<br>"));
}
private AvatarsWrath(final AvatarsWrath card) {
super(card);
}
@Override
public AvatarsWrath copy() {
return new AvatarsWrath(this);
}
}
class AvatarsWrathAirbendEffect extends OneShotEffect {
AvatarsWrathAirbendEffect() {
super(Outcome.Benefit);
staticText = "choose up to one target creature, then airbend all other creatures";
}
private AvatarsWrathAirbendEffect(final AvatarsWrathAirbendEffect effect) {
super(effect);
}
@Override
public AvatarsWrathAirbendEffect copy() {
return new AvatarsWrathAirbendEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
List<Permanent> permanents = game
.getBattlefield()
.getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source, game);
Optional.ofNullable(game.getPermanent(getTargetPointer().getFirst(game, source)))
.ifPresent(permanents::remove);
return !permanents.isEmpty()
&& new AirbendTargetEffect()
.setTargetPointer(new FixedTargets(permanents, game))
.apply(game, source);
}
}
class AvatarsWrathRuleEffect extends ContinuousRuleModifyingEffectImpl {
AvatarsWrathRuleEffect() {
super(Duration.UntilYourNextTurn, Outcome.Benefit);
staticText = "<br>Until your next turn, your opponents can't cast spells from anywhere other than their hand.";
}
private AvatarsWrathRuleEffect(final AvatarsWrathRuleEffect effect) {
super(effect);
}
@Override
public AvatarsWrathRuleEffect copy() {
return new AvatarsWrathRuleEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CAST_SPELL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
return false;
}
Card card = game.getCard(event.getSourceId());
return card != null && game.getState().getZone(card.getId()) != Zone.HAND;
}
}

View file

@ -16,7 +16,7 @@ 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.TargetControlledPermanent;
import mage.target.common.TargetCreaturePermanentAmount;
import mage.target.common.TargetPermanentAmount;
import mage.target.targetpointer.SecondTargetPointer;
@ -97,7 +97,7 @@ class AwakenTheMaelstromEffect extends OneShotEffect {
}
private void makeToken(Player player, Game game, Ability source) {
TargetPermanent target = new TargetControlledCreaturePermanent();
TargetPermanent target = new TargetControlledPermanent();
target.withNotTarget(true);
target.withChooseHint("to copy");
if (!target.canChoose(player.getId(), source, game)) {

View file

@ -57,14 +57,13 @@ class AweStrikeEffect extends PreventionEffectImpl {
if (player != null) {
player.gainLife(preventionData.getPreventedDamage(), game, source);
}
this.used = true;
this.discard();
return true;
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
if (super.applies(event, source, game)) {
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
return targetCreature != null && targetCreature.getId().equals(event.getSourceId());
}

View file

@ -44,6 +44,7 @@ public final class AzorsElocutors extends CardImpl {
new WinGameSourceControllerEffect(), condition,
"Then if {this} has five or more filibuster counters on it, you win the game"
));
this.addAbility(ability);
// Whenever a source deals damage to you, remove a filibuster counter from Azor's Elocutors.
this.addAbility(new AzorsElocutorsTriggeredAbility());

View file

@ -0,0 +1,93 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.OptionalOneShotEffect;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.SourceControllerCountersCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersPlayersEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.constants.*;
import mage.abilities.keyword.FirebendingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.counters.CounterType;
import mage.game.Game;
import mage.watchers.common.DiscardedCardWatcher;
/**
*
* @author anonymous
*/
public final class AzulaRuthlessFirebender extends CardImpl {
public AzulaRuthlessFirebender(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.NOBLE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Firebending 1
this.addAbility(new FirebendingAbility(1));
// Whenever Azula attacks, you may discard a card. Then you get an experience counter for each player who discarded a card this turn.
Ability ability = new AttacksTriggeredAbility(new OptionalOneShotEffect(new DiscardControllerEffect(1)));
ability.addEffect(new AddCountersPlayersEffect(CounterType.EXPERIENCE.createInstance(), AzulaRuthlessFirebenderValue.instance, TargetController.YOU).setText("Then you get an experience counter for each player who discarded a card this turn."));
this.addAbility(ability, new DiscardedCardWatcher());
// {2}{B}: Until end of turn, Azula gets +1/+1 for each experience counter you have and gains menace.
ability = new SimpleActivatedAbility(new BoostSourceEffect(SourceControllerCountersCount.EXPERIENCE, SourceControllerCountersCount.EXPERIENCE, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{B}"));
ability.addEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn).setText("and gains menace"));
this.addAbility(ability);
}
private AzulaRuthlessFirebender(final AzulaRuthlessFirebender card) {
super(card);
}
@Override
public AzulaRuthlessFirebender copy() {
return new AzulaRuthlessFirebender(this);
}
}
enum AzulaRuthlessFirebenderValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int playersDiscardedThisTurn = 0;
for (UUID playerId : game.getState().getPlayersInRange(sourceAbility.getControllerId(), game)) {
if (DiscardedCardWatcher.checkPlayerDiscarded(playerId, game)) {
playersDiscardedThisTurn += 1;
}
}
return playersDiscardedThisTurn;
}
@Override
public AzulaRuthlessFirebenderValue copy() {
return this;
}
@Override
public String getMessage() {
return "for each player who discarded a card this turn";
}
@Override
public String toString() {
return "X";
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.EntersBattlefieldTappedUnlessAbility;
import mage.abilities.condition.common.YouControlABasicLandCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetControlledLandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BaSingSe extends CardImpl {
public BaSingSe(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// This land enters tapped unless you control a basic land.
this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlABasicLandCondition.instance)
.addHint(YouControlABasicLandCondition.getHint()));
// {T}: Add {G}.
this.addAbility(new GreenManaAbility());
// {2}{G}, {T}: Earthbend 2. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(
new EarthbendTargetEffect(2), new ManaCostsImpl<>("{2}{G}")
);
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetControlledLandPermanent());
this.addAbility(ability);
}
private BaSingSe(final BaSingSe card) {
super(card);
}
@Override
public BaSingSe copy() {
return new BaSingSe(this);
}
}

View file

@ -0,0 +1,64 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect;
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.FilterControlledPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.permanent.token.SpiritWorldToken;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BaboonSpirit extends CardImpl {
private static final FilterPermanent filter
= new FilterControlledPermanent(SubType.SPIRIT, "another nontoken Spirit you control");
static {
filter.add(AnotherPredicate.instance);
filter.add(TokenPredicate.FALSE);
}
public BaboonSpirit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.MONKEY);
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// Whenever another nontoken Spirit you control enters, create a 1/1 colorless Spirit creature token with "This token can't block or be blocked by non-Spirit creatures."
this.addAbility(new EntersBattlefieldAllTriggeredAbility(new CreateTokenEffect(new SpiritWorldToken()), filter));
// {3}{U}: Exile another target creature you control. Return it to the battlefield under its owner's control at the beginning of the next end step.
Ability ability = new SimpleActivatedAbility(
new ExileReturnBattlefieldNextEndStepTargetEffect(), new ManaCostsImpl<>("{3}{U}")
);
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL));
this.addAbility(ability);
}
private BaboonSpirit(final BaboonSpirit card) {
super(card);
}
@Override
public BaboonSpirit copy() {
return new BaboonSpirit(this);
}
}

View file

@ -0,0 +1,53 @@
package mage.cards.b;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.TapForManaAllTriggeredManaAbility;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SetTargetPointer;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetControlledLandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BadgermoleCub extends CardImpl {
public BadgermoleCub(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.BADGER);
this.subtype.add(SubType.MOLE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When this creature enters, earthbend 1.
Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(1));
ability.addTarget(new TargetControlledLandPermanent());
this.addAbility(ability);
// Whenever you tap a creature for mana, add an additional {G}.
this.addAbility(new TapForManaAllTriggeredManaAbility(
new BasicManaEffect(Mana.GreenMana(1)).setText("add an additional {G}"),
StaticFilters.FILTER_CONTROLLED_CREATURE, SetTargetPointer.NONE
).setTriggerPhrase("Whenever you tap a creature for mana, "));
}
private BadgermoleCub(final BadgermoleCub card) {
super(card);
}
@Override
public BadgermoleCub copy() {
return new BadgermoleCub(this);
}
}

View file

@ -49,7 +49,7 @@ public final class BarretWallace extends CardImpl {
// Whenever Barret Wallace attacks, it deals damage equal to the number of equipped creatures you control to defending player.
this.addAbility(new AttacksTriggeredAbility(
new DamageTargetEffect(xValue, true, "it", true)
new DamageTargetEffect(xValue, true, "it")
.setText("it deals damage equal to the number of equipped creatures you control to defending player"),
false, null, SetTargetPointer.PLAYER
).withRuleTextReplacement(true).addHint(hint));

View file

@ -7,13 +7,13 @@ import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.PreventDamageEvent;
import mage.game.events.PreventedDamageEvent;
import mage.players.Player;
import java.util.UUID;
@ -46,7 +46,7 @@ public final class BattletideAlchemist extends CardImpl {
class BattletideAlchemistEffect extends PreventionEffectImpl {
BattletideAlchemistEffect() {
super(Duration.WhileOnBattlefield);
super(Duration.WhileOnBattlefield, 0, false, false, new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.CLERIC, "Clerics")));
this.staticText = "If a source would deal damage to a player, you may prevent X of that damage, where X is the number of Clerics you control";
}
@ -61,27 +61,14 @@ class BattletideAlchemistEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
boolean result = false;
Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(event.getTargetId());
if (controller != null && targetPlayer != null) {
int numberOfClericsControlled = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.CLERIC, "Clerics")).calculate(game, source, this);
int toPrevent = Math.min(numberOfClericsControlled, event.getAmount());
if (toPrevent > 0 && controller.chooseUse(Outcome.PreventDamage, "Prevent " + toPrevent + " damage to " + targetPlayer.getName() + '?', source, game)) {
GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), toPrevent, ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
if (event.getAmount() >= toPrevent) {
event.setAmount(event.getAmount() - toPrevent);
} else {
event.setAmount(0);
result = true;
}
game.informPlayers("Battletide Alchemist prevented " + toPrevent + " damage to " + targetPlayer.getName());
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), toPrevent));
if (amountToPrevent > 0 && controller.chooseUse(Outcome.PreventDamage, "Prevent " + amountToPrevent + " damage to " + targetPlayer.getName() + '?', source, game)) {
preventDamageAction(event, source, game);
}
}
}
return result;
return false;
}
@Override

View file

@ -32,7 +32,7 @@ public final class BebopAndRocksteady extends CardImpl {
// Whenever Bebop & Rocksteady attacks or blocks, sacrifice a permanent unless you discard a card.
this.addAbility(new AttacksOrBlocksTriggeredAbility(new DoIfCostPaid(
null, new SacrificeControllerEffect(StaticFilters.FILTER_PERMANENT, 1, null),
new DiscardCardCost(), false), false
new DiscardCardCost(), true), false
));
}

View file

@ -1,7 +1,6 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@ -75,7 +74,7 @@ class BedazzleEffect extends OneShotEffect {
if (permanent != null) {
permanent.destroy(source, game, false);
}
Effect effect = new DamageTargetEffect(StaticValue.get(2), true, "", true);
Effect effect = new DamageTargetEffect(2);
effect.setTargetPointer(new FixedTarget(source.getTargets().get(1).getFirstTarget(), game));
effect.apply(game, source);
return true;

View file

@ -0,0 +1,87 @@
package mage.cards.b;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledLandPermanent;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BeifongsBountyHunters extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("nonland creature you control");
static {
filter.add(Predicates.not(CardType.LAND.getPredicate()));
}
public BeifongsBountyHunters(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MERCENARY);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Whenever a nonland creature you control dies, earthbend X, where X is that creature's power.
Ability ability = new DiesCreatureTriggeredAbility(
new EarthbendTargetEffect(BeifongsBountyHuntersValue.instance), false, filter
);
ability.addTarget(new TargetControlledLandPermanent());
this.addAbility(ability);
}
private BeifongsBountyHunters(final BeifongsBountyHunters card) {
super(card);
}
@Override
public BeifongsBountyHunters copy() {
return new BeifongsBountyHunters(this);
}
}
enum BeifongsBountyHuntersValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return Optional
.ofNullable((Permanent) effect.getValue("creatureDied"))
.map(MageObject::getPower)
.map(MageInt::getValue)
.orElse(0);
}
@Override
public BeifongsBountyHuntersValue copy() {
return this;
}
@Override
public String getMessage() {
return "that creature's power";
}
@Override
public String toString() {
return "X";
}
}

View file

@ -3,9 +3,7 @@ package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToACreatureTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -31,12 +29,10 @@ public final class BellowingFiend extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Bellowing Fiend deals damage to a creature, Bellowing Fiend deals 3 damage to that creature's controller and 3 damage to you.
Ability ability = new DealsDamageToACreatureTriggeredAbility(new BellowingFiendEffect(), false, false, true);
Effect effect = new DamageControllerEffect(3);
effect.setText("and 3 damage to you");
ability.addEffect(effect);
this.addAbility(ability);
this.addAbility(new DealsDamageToACreatureTriggeredAbility(
new BellowingFiendEffect(), false, false, true));
}
private BellowingFiend(final BellowingFiend card) {
@ -53,7 +49,7 @@ class BellowingFiendEffect extends OneShotEffect {
BellowingFiendEffect() {
super(Outcome.Detriment);
this.staticText = "{this} deals 3 damage to that creature's controller";
this.staticText = "{this} deals 3 damage to that creature's controller and 3 damage to you";
}
private BellowingFiendEffect(final BellowingFiendEffect effect) {
@ -67,15 +63,17 @@ class BellowingFiendEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
boolean applied = false;
Permanent damagedCreature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (damagedCreature != null) {
Player controller = game.getPlayer(damagedCreature.getControllerId());
if (controller != null) {
controller.damage(3, source.getSourceId(), source, game);
applied = true;
}
}
return applied;
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
you.damage(3, source.getSourceId(), source, game);
}
return true;
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.WaterbendCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.WardAbility;
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 BenevolentRiverSpirit extends CardImpl {
public BenevolentRiverSpirit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
// As an additional cost to cast this spell, waterbend {5}.
this.getSpellAbility().addCost(new WaterbendCost(5));
// Flying
this.addAbility(FlyingAbility.getInstance());
// Ward {2}
this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}")));
// When this creature enters, scry 2.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2)));
}
private BenevolentRiverSpirit(final BenevolentRiverSpirit card) {
super(card);
}
@Override
public BenevolentRiverSpirit copy() {
return new BenevolentRiverSpirit(this);
}
}

View file

@ -0,0 +1,93 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BisonWhistle extends CardImpl {
public BisonWhistle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{G}");
// {1}, {T}: Look at the top card of your library. If it's a Bison card, you may put it onto the battlefield. If it's a creature card, you may reveal it and put it into your hand. Otherwise, you may put it into your graveyard.
Ability ability = new SimpleActivatedAbility(new BisonWhistleEffect(), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private BisonWhistle(final BisonWhistle card) {
super(card);
}
@Override
public BisonWhistle copy() {
return new BisonWhistle(this);
}
}
class BisonWhistleEffect extends OneShotEffect {
BisonWhistleEffect() {
super(Outcome.Benefit);
staticText = "look at the top card of your library. If it's a Bison card, you may put it onto the battlefield. " +
"If it's a creature card, you may reveal it and put it into your hand. Otherwise, you may put it into your graveyard";
}
private BisonWhistleEffect(final BisonWhistleEffect effect) {
super(effect);
}
@Override
public BisonWhistleEffect copy() {
return new BisonWhistleEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Card card = player.getLibrary().getFromTop(game);
if (card == null) {
return false;
}
player.lookAtCards("Top of library", card, game);
if (card.hasSubtype(SubType.BISON, game) && player.chooseUse(
Outcome.PutCardInPlay, "Put " + card.getIdName() + " onto the battlefield?", source, game
)) {
player.moveCards(card, Zone.BATTLEFIELD, source, game);
// cards like Crib Swap and Containment Priest make it possible for the card
// to either stay in the library or go to a different zone, so we only exit if it's not still on top
if (!Zone.LIBRARY.match(game.getState().getZone(card.getId()))) {
return true;
}
}
if (card.isCreature(game) && player.chooseUse(
Outcome.DrawCard, "Put " + card.getIdName() + " into your hand?", source, game
)) {
player.revealCards(source, new CardsImpl(card), game);
return player.moveCards(card, Zone.HAND, source, game);
}
return player.chooseUse(
Outcome.Discard, "Put " + card.getIdName() + " into your graveyard?", source, game
) && player.moveCards(card, Zone.GRAVEYARD, source, game);
}
}

View file

@ -0,0 +1,58 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.abilities.keyword.ExhaustAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SetTargetPointer;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.target.common.TargetControlledLandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BitterWork extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent();
static {
filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3));
}
public BitterWork(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{G}");
// Whenever you attack a player with one or more creatures with power 4 or greater, draw a card.
this.addAbility(new AttacksPlayerWithCreaturesTriggeredAbility(
new DrawCardSourceControllerEffect(1), filter, SetTargetPointer.NONE
).setTriggerPhrase("Whenever you attack a player with one or more creatures with power 4 or greater, "));
// Exhaust -- {4}: Earthbend 4. Activate only during your turn.
Ability ability = new ExhaustAbility(new EarthbendTargetEffect(4), new GenericManaCost(4))
.setCondition(MyTurnCondition.instance);
ability.addTarget(new TargetControlledLandPermanent());
ability.addEffect(new InfoEffect("Activate only during your turn"));
this.addAbility(ability);
}
private BitterWork(final BitterWork card) {
super(card);
}
@Override
public BitterWork copy() {
return new BitterWork(this);
}
}

View file

@ -1,16 +1,10 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.effects.common.continuous.NonbasicLandsAreMountainsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.constants.CardType;
import java.util.UUID;
@ -23,7 +17,7 @@ public final class BloodMoon extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
// Nonbasic lands are Mountains.
this.addAbility(new SimpleStaticAbility(new BloodMoonEffect()));
this.addAbility(new SimpleStaticAbility(new NonbasicLandsAreMountainsEffect()));
}
private BloodMoon(final BloodMoon card) {
@ -34,57 +28,4 @@ public final class BloodMoon extends CardImpl {
public BloodMoon copy() {
return new BloodMoon(this);
}
static class BloodMoonEffect extends ContinuousEffectImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent();
static {
filter.add(Predicates.not(SuperType.BASIC.getPredicate()));
}
BloodMoonEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "Nonbasic lands are Mountains";
this.dependencyTypes.add(DependencyType.BecomeMountain);
this.dependendToTypes.add(DependencyType.BecomeNonbasicLand);
}
private BloodMoonEffect(final BloodMoonEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public BloodMoonEffect copy() {
return new BloodMoonEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (Permanent land : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
switch (layer) {
case TypeChangingEffects_4:
// 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects
// So the ability removing has to be done before Layer 6
// Lands have their mana ability intrinsically, so that is added in layer 4
land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, SubType.MOUNTAIN);
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
}
}
return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
}
}
}

View file

@ -9,32 +9,24 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class Bloodbriar extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another permanent");
static {
filter.add(AnotherPredicate.instance);
}
public Bloodbriar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.PLANT, SubType.ELEMENTAL);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Whenever you sacrifice another permanent, put a +1/+1 counter on Bloodbriar.
this.addAbility(new SacrificePermanentTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), StaticFilters.FILTER_ANOTHER_PERMANENT
));
}

View file

@ -0,0 +1,43 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BoarQPine extends CardImpl {
public BoarQPine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.BOAR);
this.subtype.add(SubType.PORCUPINE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever you cast a noncreature spell, put a +1/+1 counter on this creature.
this.addAbility(new SpellCastControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
StaticFilters.FILTER_SPELL_A_NON_CREATURE, false
));
}
private BoarQPine(final BoarQPine card) {
super(card);
}
@Override
public BoarQPine copy() {
return new BoarQPine(this);
}
}

View file

@ -0,0 +1,48 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BoilingRockPrison extends CardImpl {
public BoilingRockPrison(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// This land enters tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add {B} or {R}.
this.addAbility(new BlackManaAbility());
this.addAbility(new RedManaAbility());
// {4}, {T}, Sacrifice this land: Draw a card.
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(4));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
}
private BoilingRockPrison(final BoilingRockPrison card) {
super(card);
}
@Override
public BoilingRockPrison copy() {
return new BoilingRockPrison(this);
}
}

View file

@ -0,0 +1,104 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.abilities.keyword.FirebendingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyard;
import mage.util.CardUtil;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BoilingRockRioter extends CardImpl {
private static final FilterControlledPermanent filter
= new FilterControlledPermanent(SubType.ALLY, "untaped Ally you control");
static {
filter.add(TappedPredicate.UNTAPPED);
}
public BoilingRockRioter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Firebending 1
this.addAbility(new FirebendingAbility(1));
// Tap an untapped Ally you control: Exile target card from a graveyard.
Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new TapTargetCost(filter));
ability.addTarget(new TargetCardInGraveyard());
this.addAbility(ability);
// Whenever this creature attacks, you may cast an Ally spell from among cards you own exiled with this creature.
this.addAbility(new AttacksTriggeredAbility(new BoilingRockRioterEffect()));
}
private BoilingRockRioter(final BoilingRockRioter card) {
super(card);
}
@Override
public BoilingRockRioter copy() {
return new BoilingRockRioter(this);
}
}
class BoilingRockRioterEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard(SubType.ALLY);
BoilingRockRioterEffect() {
super(Outcome.Benefit);
staticText = "you may cast an Ally spell from among cards you own exiled with this creature";
}
private BoilingRockRioterEffect(final BoilingRockRioterEffect effect) {
super(effect);
}
@Override
public BoilingRockRioterEffect copy() {
return new BoilingRockRioterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = Optional
.ofNullable(CardUtil.getExileZoneId(game, source))
.map(game.getExile()::getExileZone)
.map(CardsImpl::new)
.orElseGet(CardsImpl::new);
cards.removeIf(uuid -> !source.isControlledBy(game.getOwnerId(uuid)));
return CardUtil.castSpellWithAttributesForFree(player, source, game, cards, filter);
}
}

View file

@ -1,28 +1,29 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CantAttackAloneAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CantAttackAloneSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public final class BondedConstruct extends CardImpl {
public BondedConstruct(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}");
this.subtype.add(SubType.CONSTRUCT);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Bonded Construct can't attack alone.
this.addAbility(new CantAttackAloneAbility());
this.addAbility(new SimpleStaticAbility(new CantAttackAloneSourceEffect()));
}
private BondedConstruct(final BondedConstruct card) {

View file

@ -1,14 +1,14 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CantAttackAloneAbility;
import mage.abilities.keyword.CantBlockAloneAbility;
import mage.constants.SubType;
import mage.abilities.keyword.CantAttackOrBlockAloneAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -24,8 +24,7 @@ public final class BondedHorncrest extends CardImpl {
this.toughness = new MageInt(5);
// Bonded Horncrest can't attack or block alone.
this.addAbility(new CantAttackAloneAbility());
this.addAbility(CantBlockAloneAbility.getInstance());
this.addAbility(new CantAttackOrBlockAloneAbility());
}
private BondedHorncrest(final BondedHorncrest card) {

View file

@ -0,0 +1,74 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BoomerangBasics extends CardImpl {
public BoomerangBasics(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}");
this.subtype.add(SubType.LESSON);
// Return target nonland permanent to its owner's hand. If you controlled that permanent, draw a card.
this.getSpellAbility().addEffect(new BoomerangBasicsEffect());
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
}
private BoomerangBasics(final BoomerangBasics card) {
super(card);
}
@Override
public BoomerangBasics copy() {
return new BoomerangBasics(this);
}
}
class BoomerangBasicsEffect extends OneShotEffect {
BoomerangBasicsEffect() {
super(Outcome.Benefit);
staticText = "return target nonland permanent to its owner's hand. If you controlled that permanent, draw a card";
}
private BoomerangBasicsEffect(final BoomerangBasicsEffect effect) {
super(effect);
}
@Override
public BoomerangBasicsEffect copy() {
return new BoomerangBasicsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (player == null || permanent == null) {
return false;
}
boolean flag = permanent.isControlledBy(player.getId());
player.moveCards(permanent, Zone.HAND, source, game);
if (flag) {
game.processAction();
player.drawCards(1, source, game);
}
return true;
}
}

View file

@ -0,0 +1,67 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
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 mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.permanent.token.FoodToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BoscoJustABear extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_CREATURE_LEGENDARY);
private static final Hint hint = new ValueHint("Legendary creatures you control", xValue);
public BoscoJustABear(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.BEAR);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When Bosco enters, create a Food token for each legendary creature you control.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken(), xValue)).addHint(hint));
// {2}{G}, Sacrifice a Food: Put two +1/+1 counters on Bosco. He gains trample until end of turn.
Ability ability = new SimpleActivatedAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{2}{G}")
);
ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD));
ability.addEffect(new GainAbilitySourceEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn
).setText("He gains trample until end of turn"));
this.addAbility(ability);
}
private BoscoJustABear(final BoscoJustABear card) {
super(card);
}
@Override
public BoscoJustABear copy() {
return new BoscoJustABear(this);
}
}

View file

@ -1,6 +1,7 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectData;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -10,13 +11,9 @@ import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.MulticoloredPredicate;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.PreventDamageEvent;
import mage.game.events.PreventedDamageEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -67,26 +64,15 @@ class BraceForImpactPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (game.replaceEvent(preventEvent)) {
return false;
}
int prevented;
int damage = event.getAmount();
event.setAmount(0);
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
prevented = damage;
// add counters now
if (prevented > 0) {
PreventionEffectData preventionEffectData = preventDamageAction(event, source, game);
if (preventionEffectData.getPreventedDamage() > 0) {
Permanent targetPermanent = game.getPermanent(source.getTargets().getFirstTarget());
if (targetPermanent != null) {
targetPermanent.addCounters(CounterType.P1P1.createInstance(prevented), source.getControllerId(), source, game);
game.informPlayers("Brace for Impact: Prevented " + prevented + " damage ");
game.informPlayers("Brace for Impact: Adding " + prevented + " +1/+1 counters to " + targetPermanent.getName());
targetPermanent.addCounters(CounterType.P1P1.createInstance(preventionEffectData.getPreventedDamage()), source.getControllerId(), source, game);
}
return false;
}
return true;
return false;
}
@Override

View file

@ -1,21 +1,18 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author LoneFox
@ -29,10 +26,7 @@ public final class BrothersOfFire extends CardImpl {
this.toughness = new MageInt(2);
// {1}{R}{R}: Brothers of Fire deals 1 damage to any target and 1 damage to you.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new ManaCostsImpl<>("{1}{R}{R}"));
Effect effect = new DamageControllerEffect(1);
effect.setText("and 1 damage to you");
ability.addEffect(effect);
Ability ability = new SimpleActivatedAbility(new DamageTargetAndYouEffect(1), new ManaCostsImpl<>("{1}{R}{R}"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -0,0 +1,56 @@
package mage.cards.b;
import mage.abilities.Mode;
import mage.abilities.dynamicvalue.common.LandsYouControlCount;
import mage.abilities.effects.common.DamageTargetEffect;
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.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicates;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BumiBash extends CardImpl {
private static final FilterPermanent filter = new FilterLandPermanent("land creature or nonbasic land");
static {
filter.add(Predicates.or(
CardType.CREATURE.getPredicate(),
Predicates.not(SuperType.BASIC.getPredicate())
));
}
public BumiBash(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Choose one --
// * Bumi Bash deals damage equal to the number of lands you control to target creature.
this.getSpellAbility().addEffect(new DamageTargetEffect(LandsYouControlCount.instance)
.setText("{this} deals damage equal to the number of lands you control to target creature"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addHint(LandsYouControlHint.instance);
// * Destroy target land creature or nonbasic land.
this.getSpellAbility().addMode(new Mode(new DestroyTargetEffect()).addTarget(new TargetPermanent(filter)));
}
private BumiBash(final BumiBash card) {
super(card);
}
@Override
public BumiBash copy() {
return new BumiBash(this);
}
}

View file

@ -0,0 +1,131 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.UntapAllLandsControllerEffect;
import mage.abilities.effects.common.combat.CantAttackAllEffect;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.constants.*;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.turn.TurnMod;
import mage.target.common.TargetControlledLandPermanent;
/**
*
* @author Grath
*/
public final class BumiUnleashed extends CardImpl {
public BumiUnleashed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.NOBLE);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
// Trample
this.addAbility(TrampleAbility.getInstance());
// When Bumi enters, earthbend 4.
Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(4));
ability.addTarget(new TargetControlledLandPermanent());
this.addAbility(ability);
// Whenever Bumi deals combat damage to a player, untap all lands you control. After this phase, there is an additional combat phase. Only land creatures can attack during that combat phase.
ability = new DealsCombatDamageToAPlayerTriggeredAbility(new UntapAllLandsControllerEffect(), false);
ability.addEffect(new BumiUnleashedEffect());
this.addAbility(ability);
}
private BumiUnleashed(final BumiUnleashed card) {
super(card);
}
@Override
public BumiUnleashed copy() {
return new BumiUnleashed(this);
}
}
//Based on LastNightTogetherEffect
class BumiUnleashedEffect extends OneShotEffect {
BumiUnleashedEffect() {
super(Outcome.Benefit);
staticText = "After this main phase, there is an additional combat phase. Only land creatures can attack during that combat phase";
}
private BumiUnleashedEffect(final BumiUnleashedEffect effect) {
super(effect);
}
@Override
public BumiUnleashedEffect copy() {
return new BumiUnleashedEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
// At the start of that combat, add a restriction effect preventing other creatures from attacking.
TurnMod combat = new TurnMod(game.getState().getActivePlayerId()).withExtraPhase(TurnPhase.COMBAT);
game.getState().getTurnMods().add(combat);
BumiUnleashedDelayedCantAttackAbility delayedTriggeredAbility = new BumiUnleashedDelayedCantAttackAbility(combat.getId());
game.addDelayedTriggeredAbility(delayedTriggeredAbility, source);
return true;
}
}
class BumiUnleashedDelayedCantAttackAbility extends DelayedTriggeredAbility {
private final UUID connectedTurnMod;
BumiUnleashedDelayedCantAttackAbility(UUID connectedTurnMod) {
super(null, Duration.EndOfTurn);
FilterCreaturePermanent filterRestriction = new FilterCreaturePermanent();
filterRestriction.add(Predicates.not(CardType.LAND.getPredicate()));
this.addEffect(new CantAttackAllEffect(Duration.EndOfCombat, filterRestriction));
this.usesStack = false; // don't show this to the user
this.connectedTurnMod = connectedTurnMod;
}
BumiUnleashedDelayedCantAttackAbility(BumiUnleashedDelayedCantAttackAbility ability) {
super(ability);
this.connectedTurnMod = ability.connectedTurnMod;
}
@Override
public BumiUnleashedDelayedCantAttackAbility copy() {
return new BumiUnleashedDelayedCantAttackAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.PHASE_CHANGED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return (event.getType() == GameEvent.EventType.PHASE_CHANGED && this.connectedTurnMod.equals(event.getSourceId()));
}
@Override
public String getRule() {
return "Only land creatures can attack during that combat phase";
}
}

View file

@ -1,12 +1,9 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -14,6 +11,8 @@ import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponentOrPlaneswalker;
import java.util.UUID;
/**
*
* @author TheElk801
@ -29,11 +28,9 @@ public final class BurningSunsAvatar extends CardImpl {
this.toughness = new MageInt(6);
// When Burning Sun's Avatar enters the battlefield, it deals 3 damage to target opponent and 3 damage to up to one target creature.
Effect effect = new DamageTargetEffect(3);
effect.setText("it deals 3 damage to target opponent or planeswalker and 3 damage to up to one target creature");
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
ability.addTarget(new TargetOpponentOrPlaneswalker());
ability.addTarget(new TargetCreaturePermanent(0, 1));
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetAndTargetEffect(3, 3));
ability.addTarget(new TargetOpponentOrPlaneswalker().setTargetTag(1));
ability.addTarget(new TargetCreaturePermanent(0, 1).setTargetTag(2));
this.addAbility(ability);
}

View file

@ -46,7 +46,7 @@ public final class BurningTreeShaman extends CardImpl {
class BurningTreeShamanTriggeredAbility extends TriggeredAbilityImpl {
BurningTreeShamanTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player", true));
super(Zone.BATTLEFIELD, new DamageTargetEffect(StaticValue.get(1), true, "that player"));
}
private BurningTreeShamanTriggeredAbility(final BurningTreeShamanTriggeredAbility ability) {

View file

@ -1,7 +1,6 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -9,12 +8,13 @@ import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
/**
*
* @author LoneFox
@ -63,7 +63,6 @@ class CallousGiantEffect extends PreventionEffectImpl {
if(event.getAmount() <= 3)
{
preventDamageAction(event, source, game);
return true;
}
return false;
}

View file

@ -0,0 +1,47 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.game.permanent.token.ClueArtifactToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CallousInspector extends CardImpl {
public CallousInspector(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Menace
this.addAbility(new MenaceAbility());
// When this creature dies, it deals 1 damage to you. Create a Clue token.
Ability ability = new DiesSourceTriggeredAbility(new DamageControllerEffect(1, "it"));
ability.addEffect(new CreateTokenEffect(new ClueArtifactToken()));
this.addAbility(ability);
}
private CallousInspector(final CallousInspector card) {
super(card);
}
@Override
public CallousInspector copy() {
return new CallousInspector(this);
}
}

View file

@ -1,6 +1,7 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectData;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.keyword.SpliceAbility;
import mage.cards.CardImpl;
@ -9,10 +10,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.PreventDamageEvent;
import mage.game.events.PreventedDamageEvent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
@ -50,7 +48,7 @@ class CandlesGlowPreventDamageTargetEffect extends PreventionEffectImpl {
private int amount = 3;
public CandlesGlowPreventDamageTargetEffect(Duration duration) {
super(duration);
super(duration, 3, false);
staticText = "Prevent the next 3 damage that would be dealt to any target this turn. You gain life equal to the damage prevented this way";
}
@ -66,39 +64,17 @@ class CandlesGlowPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int prevented;
if (event.getAmount() >= this.amount) {
int damage = amount;
event.setAmount(event.getAmount() - amount);
this.used = true;
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
prevented = damage;
} else {
int damage = event.getAmount();
event.setAmount(0);
amount -= damage;
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
prevented = damage;
}
// add live now
if (prevented > 0) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.gainLife(prevented, game, source);
game.informPlayers("Candles' Glow: Prevented " + prevented + " damage ");
game.informPlayers("Candles' Glow: " + controller.getLogName() + " gained " + prevented + "life");
}
}
PreventionEffectData preventionData = preventDamageAction(event, source, game);
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
player.gainLife(preventionData.getPreventedDamage(), game, source);
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
if (super.applies(event, source, game)) {
return source.getTargets().getFirstTarget().equals(event.getTargetId());
}
return false;

View file

@ -0,0 +1,48 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.SwampcyclingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.game.permanent.token.FoodToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CanyonCrawler extends CardImpl {
public CanyonCrawler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
this.subtype.add(SubType.SPIDER);
this.subtype.add(SubType.BEAST);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// When this creature enters, create a Food token.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken())));
// Swampcycling {2}
this.addAbility(new SwampcyclingAbility(new ManaCostsImpl<>("{2}")));
}
private CanyonCrawler(final CanyonCrawler card) {
super(card);
}
@Override
public CanyonCrawler copy() {
return new CanyonCrawler(this);
}
}

View file

@ -16,6 +16,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -32,7 +33,7 @@ import java.util.UUID;
*/
public final class CarnageCrimsonChaos extends CardImpl {
private static final FilterCard filter = new FilterCard("creature card with mana value 3 or less");
private static final FilterCard filter = new FilterCreatureCard("creature card with mana value 3 or less");
static {
filter.add(new ManaValuePredicate(ComparisonType.OR_LESS, 3));

View file

@ -1,6 +1,6 @@
package mage.cards.c;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.cards.CardSetInfo;
@ -22,8 +22,7 @@ public final class CarnivalCarnage extends SplitCard {
// Carnival
// Carnival deals 1 damage to target creature or planeswalker and 1 damage to that permanent's controller.
this.getLeftHalfCard().getSpellAbility().addEffect(new DamageTargetEffect(1));
this.getLeftHalfCard().getSpellAbility().addEffect(new DamageTargetControllerEffect(1).setText("and 1 damage to that permanent's controller"));
this.getLeftHalfCard().getSpellAbility().addEffect(new DamageTargetAndTargetControllerEffect(1, 1));
this.getLeftHalfCard().getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
// Carnage

View file

@ -0,0 +1,52 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.LessonsInGraveCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ChakraMeditation extends CardImpl {
public ChakraMeditation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
// When this enchantment enters, return up to one target instant or sorcery card from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
ability.addTarget(new TargetCardInYourGraveyard(0, 1, StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
// Whenever you cast an instant or sorcery spell, draw a card. Then discard a card unless there are three or more Lesson cards in your graveyard.
ability = new SpellCastControllerTriggeredAbility(
new DrawCardSourceControllerEffect(1),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
);
ability.addEffect(new ConditionalOneShotEffect(
null, new DiscardControllerEffect(1), LessonsInGraveCondition.THREE,
"Then discard a card unless there are three or more Lesson cards in your graveyard"
));
this.addAbility(ability.addHint(LessonsInGraveCondition.getHint()));
}
private ChakraMeditation(final ChakraMeditation card) {
super(card);
}
@Override
public ChakraMeditation copy() {
return new ChakraMeditation(this);
}
}

View file

@ -2,19 +2,14 @@ package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetAndAllControlledEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
@ -39,15 +34,12 @@ public final class ChandraFlamesFury extends CardImpl {
this.addAbility(ability);
// 2: Chandra, Flame's Fury deals 4 damage to target creature and 2 damage to that creature's controller.
ability = new LoyaltyAbility(new ChandraFlamesFuryEffect(), -2);
ability = new LoyaltyAbility(new DamageTargetAndTargetControllerEffect(4, 2), -2);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// 8: Chandra, Flame's Fury deals 10 damage to target player and each creature that player controls.
ability = new LoyaltyAbility(new DamageTargetEffect(10), -8);
ability.addEffect(new DamageAllControlledTargetEffect(
10, StaticFilters.FILTER_PERMANENT_CREATURE
).setText("and each creature that player controls"));
ability = new LoyaltyAbility(new DamageTargetAndAllControlledEffect(10), -8);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
@ -61,35 +53,3 @@ public final class ChandraFlamesFury extends CardImpl {
return new ChandraFlamesFury(this);
}
}
class ChandraFlamesFuryEffect extends OneShotEffect {
ChandraFlamesFuryEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 4 damage to target creature and 2 damage to that creature's controller.";
}
private ChandraFlamesFuryEffect(final ChandraFlamesFuryEffect effect) {
super(effect);
}
@Override
public ChandraFlamesFuryEffect copy() {
return new ChandraFlamesFuryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent == null) {
return false;
}
Player player = game.getPlayer(permanent.getControllerId());
if (player == null) {
return false;
}
permanent.damage(4, source.getSourceId(), source, game);
player.damage(2, source.getSourceId(), source, game);
return true;
}
}

View file

@ -36,8 +36,7 @@ public final class ChandraPyromaster extends CardImpl {
this.setStartingLoyalty(4);
// +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to
// up to one target creature that player controls. That creature can't block this turn.
// +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to up to one target creature that player controls. That creature can't block this turn.
LoyaltyAbility ability1 = new LoyaltyAbility(new ChandraPyromasterEffect1(), 1);
Target target1 = new TargetPlayerOrPlaneswalker();
ability1.addTarget(target1);
@ -68,7 +67,7 @@ public final class ChandraPyromaster extends CardImpl {
class ChandraPyromasterEffect1 extends OneShotEffect {
public ChandraPyromasterEffect1() {
ChandraPyromasterEffect1() {
super(Outcome.Damage);
staticText = "{this} deals 1 damage to target player or planeswalker "
+ "and 1 damage to up to one target creature that player or that "
@ -101,7 +100,7 @@ class ChandraPyromasterEffect1 extends OneShotEffect {
class ChandraPyromasterTarget extends TargetPermanent {
public ChandraPyromasterTarget() {
ChandraPyromasterTarget() {
super(0, 1, new FilterCreaturePermanent("creature that the targeted player "
+ "or planeswalker's controller controls"), false);
}
@ -138,7 +137,7 @@ class ChandraPyromasterTarget extends TargetPermanent {
class ChandraPyromasterEffect2 extends OneShotEffect {
public ChandraPyromasterEffect2() {
ChandraPyromasterEffect2() {
super(Outcome.Detriment);
this.staticText = "Exile the top card of your library. You may play it this turn";
}

View file

@ -1,14 +1,14 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndAllControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.common.TargetPlayerOrPlaneswalker;
import java.util.UUID;
/**
*
* @author North
@ -19,10 +19,8 @@ public final class ChandrasFury extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
// Chandra's Fury deals 4 damage to target player and 1 damage to each creature that player controls.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addEffect(new DamageAllControlledTargetEffect(1)
.setText("and 1 damage to each creature that player or that planeswalker's controller controls")
);
this.getSpellAbility().addEffect(new DamageTargetAndAllControlledEffect(4, 1,
StaticFilters.FILTER_PERMANENT_CREATURE));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
}

View file

@ -1,16 +1,13 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
@ -21,10 +18,7 @@ public final class ChandrasOutrage extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}{R}");
// Chandra's Outrage deals 4 damage to target creature and 2 damage to that creature's controller.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
Effect effect = new DamageTargetControllerEffect(2);
effect.setText("and 2 damage to that creature's controller");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(new DamageTargetAndTargetControllerEffect(4, 2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}

View file

@ -1,7 +1,6 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectData;
@ -18,6 +17,8 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author emerald000
@ -70,7 +71,7 @@ class ChannelHarmEffect extends PreventionEffectImpl {
}
}
}
return true;
return false;
}
@Override

View file

@ -1,15 +1,13 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndYouEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author LevelX2
@ -19,13 +17,9 @@ public final class Char extends CardImpl {
public Char(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}");
// Char deals 4 damage to any target and 2 damage to you.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addEffect(new DamageTargetAndYouEffect(4, 2));
this.getSpellAbility().addTarget(new TargetAnyTarget());
Effect effect = new DamageControllerEffect(2);
effect.setText("and 2 damage to you");
this.getSpellAbility().addEffect(effect);
}
private Char(final Char card) {

View file

@ -0,0 +1,48 @@
package mage.cards.c;
import mage.abilities.condition.common.LessonsInGraveCondition;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.IntPlusDynamicValue;
import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.ExileTargetIfDiesEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CombustionTechnique extends CardImpl {
private static final DynamicValue xValue = new IntPlusDynamicValue(
2, new CardsInControllerGraveyardCount(new FilterCard(SubType.LESSON))
);
public CombustionTechnique(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
this.subtype.add(SubType.LESSON);
// Combustion Technique deals damage equal to 2 plus the number of Lesson cards in your graveyard to target creature. If that creature would die this turn, exile it instead.
this.getSpellAbility().addEffect(new DamageTargetEffect(xValue)
.setText("{this} deals damage equal to 2 plus the number of Lesson cards in your graveyard to target creature"));
this.getSpellAbility().addEffect(new ExileTargetIfDiesEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addHint(LessonsInGraveCondition.getHint());
}
private CombustionTechnique(final CombustionTechnique card) {
super(card);
}
@Override
public CombustionTechnique copy() {
return new CombustionTechnique(this);
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BecomesTappedSourceTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CompassionateHealer extends CardImpl {
public CompassionateHealer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
this.subtype.add(SubType.ALLY);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever this creature becomes tapped, you gain 1 life and scry 1.
Ability ability = new BecomesTappedSourceTriggeredAbility(new GainLifeEffect(1));
ability.addEffect(new ScryEffect(1).concatBy("and"));
this.addAbility(ability);
}
private CompassionateHealer(final CompassionateHealer card) {
super(card);
}
@Override
public CompassionateHealer copy() {
return new CompassionateHealer(this);
}
}

View file

@ -1,13 +1,12 @@
package mage.cards.c;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
@ -20,16 +19,11 @@ public final class ConductElectricity extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
// Conduct Electricity deals 6 damage to target creature and 2 damage to up to one target creature token.
this.getSpellAbility().addEffect(new DamageTargetEffect(
6, true, "", true
));
this.getSpellAbility().addEffect(new DamageTargetEffect(
2, true, "", true
).setTargetPointer(new SecondTargetPointer()).setText("and 2 damage to up to one target creature token"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(6, 2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPermanent(
0, 1, StaticFilters.FILTER_CREATURE_TOKEN
));
).setTargetTag(2));
}
private ConductElectricity(final ConductElectricity card) {

View file

@ -0,0 +1,42 @@
package mage.cards.c;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetControlledLandPermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CrackedEarthTechnique extends CardImpl {
public CrackedEarthTechnique(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}");
this.subtype.add(SubType.LESSON);
// Earthbend 3, then earthbend 3. You gain 3 life.
this.getSpellAbility().addEffect(new EarthbendTargetEffect(3));
this.getSpellAbility().addEffect(new EarthbendTargetEffect(3)
.setTargetPointer(new SecondTargetPointer())
.concatBy(", then"));
this.getSpellAbility().addTarget(new TargetControlledLandPermanent().withChooseHint("first target"));
this.getSpellAbility().addTarget(new TargetControlledLandPermanent().withChooseHint("second target"));
this.getSpellAbility().addEffect(new GainLifeEffect(3));
}
private CrackedEarthTechnique(final CrackedEarthTechnique card) {
super(card);
}
@Override
public CrackedEarthTechnique copy() {
return new CrackedEarthTechnique(this);
}
}

View file

@ -1,7 +1,8 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.keyword.CantBlockAloneAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CantBlockAloneSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -23,7 +24,7 @@ public final class CravenHulk extends CardImpl {
this.toughness = new MageInt(4);
// Craven Hulk can't block alone.
this.addAbility(CantBlockAloneAbility.getInstance());
this.addAbility(new SimpleStaticAbility(new CantBlockAloneSourceEffect()));
}
private CravenHulk(final CravenHulk card) {

View file

@ -0,0 +1,59 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.permanent.token.FoodToken;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CreepingCrystalCoating extends CardImpl {
public CreepingCrystalCoating(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
this.subtype.add(SubType.AURA);
// Flash
this.addAbility(FlashAbility.getInstance());
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.addAbility(new EnchantAbility(auraTarget));
// Enchanted creature gets +0/+3 and has "Whenever this creature attacks, create a Food token."
Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(0, 3));
ability.addEffect(new GainAbilityAttachedEffect(
new AttacksTriggeredAbility(new CreateTokenEffect(new FoodToken())), AttachmentType.AURA
).setText("and has \"Whenever this creature attacks, create a Food token.\""));
this.addAbility(ability);
}
private CreepingCrystalCoating(final CreepingCrystalCoating card) {
super(card);
}
@Override
public CreepingCrystalCoating copy() {
return new CreepingCrystalCoating(this);
}
}

View file

@ -0,0 +1,58 @@
package mage.cards.c;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.permanent.token.MonkRedToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CrescentIslandTemple extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SHRINE);
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
private static final Hint hint = new ValueHint("Shrines you control", xValue);
private static final FilterPermanent filter2 = new FilterControlledPermanent(SubType.SHRINE, "another Shrine you control");
static {
filter.add(AnotherPredicate.instance);
}
public CrescentIslandTemple(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.SHRINE);
// When Crescent Island Temple enters, for each Shrine you control, create a 1/1 red Monk creature token with prowess.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MonkRedToken(), xValue)
.setText("for each Shrine you control, create a 1/1 red Monk creature token with prowess")).addHint(hint));
// Whenever another Shrine you control enters, create a 1/1 red Monk creature token with prowess.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(new CreateTokenEffect(new MonkRedToken()), filter2));
}
private CrescentIslandTemple(final CrescentIslandTemple card) {
super(card);
}
@Override
public CrescentIslandTemple copy() {
return new CrescentIslandTemple(this);
}
}

View file

@ -0,0 +1,54 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.RaidCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.hint.common.RaidHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AbilityWord;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.game.permanent.token.SoldierFirebendingToken;
import mage.watchers.common.PlayerAttackedWatcher;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CruelAdministrator extends CardImpl {
public CruelAdministrator(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
// Raid -- This creature enters with a +1/+1 counter on it if you attacked this turn.
this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), RaidCondition.instance, ""
), "with a +1/+1 counter on it if you attacked this turn")
.setAbilityWord(AbilityWord.RAID)
.addHint(RaidHint.instance), new PlayerAttackedWatcher());
// Whenever this creature attacks, create a 2/2 red Soldier creature token with firebending 1.
this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect(new SoldierFirebendingToken())));
}
private CruelAdministrator(final CruelAdministrator card) {
super(card);
}
@Override
public CruelAdministrator copy() {
return new CruelAdministrator(this);
}
}

View file

@ -1,19 +1,21 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author LoneFox
@ -38,10 +40,10 @@ public final class CrumblingSanctuary extends CardImpl {
}
}
class CrumblingSanctuaryEffect extends PreventionEffectImpl {
class CrumblingSanctuaryEffect extends ReplacementEffectImpl {
CrumblingSanctuaryEffect() {
super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false, false);
super(Duration.WhileOnBattlefield, Outcome.PreventDamage);
staticText = "If damage would be dealt to a player, that player exiles that many cards from the top of their library instead.";
}
@ -59,16 +61,18 @@ class CrumblingSanctuaryEffect extends PreventionEffectImpl {
int amount = event.getAmount();
Player player = game.getPlayer(event.getTargetId());
if(player != null) {
preventDamageAction(event, source, game);
player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.EXILED, source, game);
}
return true;
}
return false;
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return super.applies(event, source, game) && (game.getPlayer(event.getTargetId()) != null);
return true;
}
}

View file

@ -0,0 +1,56 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.LandsYouControlCount;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CrystallineArmor extends CardImpl {
public CrystallineArmor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.addAbility(new EnchantAbility(auraTarget));
// Enchanted creature gets +1/+1 for each land you control and has trample.
Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(
LandsYouControlCount.instance, LandsYouControlCount.instance
).setText("enchanted creature gets +1/+1 for each land you control"));
ability.addEffect(new GainAbilityAttachedEffect(
TrampleAbility.getInstance(), AttachmentType.AURA
).setText("and has trample"));
this.addAbility(ability);
}
private CrystallineArmor(final CrystallineArmor card) {
super(card);
}
@Override
public CrystallineArmor copy() {
return new CrystallineArmor(this);
}
}

View file

@ -8,9 +8,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.target.TargetPermanent;
import mage.util.functions.CopyApplier;
@ -22,12 +20,6 @@ import java.util.UUID;
*/
public final class CrystallineResonance extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another permanent");
static {
filter.add(AnotherPredicate.instance);
}
public CrystallineResonance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
@ -54,7 +46,7 @@ public final class CrystallineResonance extends CardImpl {
"except it has this ability"
), true
);
ability.addTarget(new TargetPermanent(filter));
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_PERMANENT));
return ability;
}
}

View file

@ -1,17 +1,14 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DamageTargetAndTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
/**
*
@ -22,14 +19,11 @@ public final class CunningStrike extends CardImpl {
public CunningStrike(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{R}");
// Cunning Strike deals 2 damage to target creature and 2 damage to target player.
this.getSpellAbility().addEffect(new DamageTargetEffect(StaticValue.get(2), true, "", true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
Effect effect = new DamageTargetEffect(StaticValue.get(2), true, "", true);
effect.setTargetPointer(new SecondTargetPointer());
effect.setText("and 2 damage to target player or planeswalker");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
// Cunning Strike deals 2 damage to target creature and 2 damage to target player or planeswalker.
this.getSpellAbility().addEffect(new DamageTargetAndTargetEffect(2, 2));
this.getSpellAbility().addTarget(new TargetCreaturePermanent().setTargetTag(1));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker().setTargetTag(2));
// Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("<br>"));
}

View file

@ -1,4 +1,3 @@
package mage.cards.c;
import mage.MageInt;
@ -12,13 +11,13 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetOpponent;
import mage.target.targetadjustment.TargetAdjuster;
import mage.target.targetpointer.EachTargetPointer;
import java.util.UUID;
@ -35,7 +34,7 @@ public final class CuombajjWitches extends CardImpl {
this.toughness = new MageInt(3);
// {T}: Cuombajj Witches deals 1 damage to any target and 1 damage to any target of an opponent's choice.
Effect effect = new DamageTargetEffect(1);
Effect effect = new DamageTargetEffect(1).setTargetPointer(new EachTargetPointer());
effect.setText("{this} deals 1 damage to any target and 1 damage to any target of an opponent's choice");
Ability ability = new SimpleActivatedAbility(effect, new TapSourceCost());
ability.addTarget(new TargetAnyTarget());

View file

@ -0,0 +1,53 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DestroyTargetEffect;
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.StaticFilters;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CuriousFarmAnimals extends CardImpl {
public CuriousFarmAnimals(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
this.subtype.add(SubType.BOAR);
this.subtype.add(SubType.ELK);
this.subtype.add(SubType.BIRD);
this.subtype.add(SubType.OX);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// When this creature dies, you gain 3 life.
this.addAbility(new DiesSourceTriggeredAbility(new GainLifeEffect(3)));
// {2}, Sacrifice this creature: Destroy up to one target artifact or enchantment.
Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(2));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
this.addAbility(ability);
}
private CuriousFarmAnimals(final CuriousFarmAnimals card) {
super(card);
}
@Override
public CuriousFarmAnimals copy() {
return new CuriousFarmAnimals(this);
}
}

View file

@ -22,11 +22,7 @@ public final class CutIn extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Cut In deals 4 damage to target creature.
this.getSpellAbility().addEffect(
new DamageTargetEffect(4)
.setUseOnlyTargetPointer(true)
.setTargetPointer(new FirstTargetPointer())
);
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Create a Young Hero Role token attached to up to one target creature you control.

View file

@ -0,0 +1,39 @@
package mage.cards.c;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class CycleOfRenewal extends CardImpl {
public CycleOfRenewal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
this.subtype.add(SubType.LESSON);
// Sacrifice a land. Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle.
this.getSpellAbility().addEffect(new SacrificeControllerEffect(StaticFilters.FILTER_LAND, 1, ""));
this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(
0, 2, StaticFilters.FILTER_CARD_BASIC_LAND
), true));
}
private CycleOfRenewal(final CycleOfRenewal card) {
super(card);
}
@Override
public CycleOfRenewal copy() {
return new CycleOfRenewal(this);
}
}

View file

@ -3,14 +3,17 @@ package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
import mage.game.Game;
import java.util.UUID;
@ -28,14 +31,7 @@ public final class DaggerCaster extends CardImpl {
this.toughness = new MageInt(3);
// When Dagger Caster enters the battlefield, it deals 1 damage to each opponent and 1 damage to each creature your opponents control.
Ability ability = new EntersBattlefieldTriggeredAbility(new DamagePlayersEffect(
1, TargetController.OPPONENT, "it"
));
ability.addEffect(
new DamageAllEffect(1, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)
.setText("and 1 damage to each creature your opponents control")
);
this.addAbility(ability);
this.addAbility(new EntersBattlefieldTriggeredAbility(new DaggerCasterEffect()));
}
private DaggerCaster(final DaggerCaster card) {
@ -47,3 +43,29 @@ public final class DaggerCaster extends CardImpl {
return new DaggerCaster(this);
}
}
// needed for simultaneous damage
class DaggerCasterEffect extends OneShotEffect {
DaggerCasterEffect() {
super(Outcome.Damage);
staticText = "it deals 1 damage to each opponent and 1 damage to each creature your opponents control";
}
private DaggerCasterEffect(final DaggerCasterEffect effect) {
super(effect);
}
@Override
public DaggerCasterEffect copy() {
return new DaggerCasterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
new DamagePlayersEffect(1, TargetController.OPPONENT, "it").apply(game, source);
new DamageAllEffect(1, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE).apply(game, source);
return true;
}
}

View file

@ -0,0 +1,71 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.effects.keyword.EarthbendTargetEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.target.common.TargetControlledLandPermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DaiLiAgents extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("creatures you control with +1/+1 counters on them");
static {
filter.add(CounterType.P1P1.getPredicate());
}
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
private static final Hint hint = new ValueHint("Creatures you control with +1/+1 counters on them", xValue);
public DaiLiAgents(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// When this creature enters, earthbend 1, then earthbend 1.
Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(1).setText("earhbend 1"));
ability.addEffect(new EarthbendTargetEffect(1)
.setTargetPointer(new SecondTargetPointer())
.concatBy(", then"));
ability.addTarget(new TargetControlledLandPermanent().withChooseHint("first target"));
ability.addTarget(new TargetControlledLandPermanent().withChooseHint("second target"));
this.addAbility(ability.addHint(hint));
// Whenever this creature attacks, each opponent loses X life and you gain X life, where X is the number of creatures you control with +1/+1 counters on them.
ability = new AttacksTriggeredAbility(new LoseLifeOpponentsEffect(xValue).setText("each opponent loses X life"));
ability.addEffect(new GainLifeEffect(xValue).concatBy("and"));
this.addAbility(ability);
}
private DaiLiAgents(final DaiLiAgents card) {
super(card);
}
@Override
public DaiLiAgents copy() {
return new DaiLiAgents(this);
}
}

Some files were not shown because too many files have changed in this diff Show more